/[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 839 by zherczeg, Fri Dec 30 13:22:28 2011 UTC revision 966 by zherczeg, Mon May 14 06:27:21 2012 UTC
# Line 26  Line 26 
26    
27  SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()  SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()
28  {  {
29  #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)          return "x86" SLJIT_CPUINFO;
         return "x86-32";  
 #else  
         return "x86-64";  
 #endif  
30  }  }
31    
32  /*  /*
# Line 80  static SLJIT_CONST sljit_ub reg_map[SLJI Line 76  static SLJIT_CONST sljit_ub reg_map[SLJI
76                  p = SLJIT_MEM1(SLJIT_LOCALS_REG); \                  p = SLJIT_MEM1(SLJIT_LOCALS_REG); \
77                  do; \                  do; \
78          } \          } \
79          else if (p >= SLJIT_GENERAL_EREG1 && p <= SLJIT_GENERAL_EREG2) { \          else if (p >= SLJIT_SAVED_EREG1 && p <= SLJIT_SAVED_EREG2) { \
80                  w = compiler->generals_start + (p - SLJIT_GENERAL_EREG1) * sizeof(sljit_w); \                  w = compiler->saveds_start + (p - SLJIT_SAVED_EREG1) * sizeof(sljit_w); \
81                  p = SLJIT_MEM1(SLJIT_LOCALS_REG); \                  p = SLJIT_MEM1(SLJIT_LOCALS_REG); \
82                  do; \                  do; \
83          }          }
# Line 95  static SLJIT_CONST sljit_ub reg_map[SLJI Line 91  static SLJIT_CONST sljit_ub reg_map[SLJI
91    
92  /* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present  /* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present
93     Note: avoid to use r12 and r13 for memory addessing     Note: avoid to use r12 and r13 for memory addessing
94     therefore r12 is better for GENERAL_EREG than GENERAL_REG. */     therefore r12 is better for SAVED_EREG than SAVED_REG. */
95  #ifndef _WIN64  #ifndef _WIN64
96  /* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */  /* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */
97  static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {  static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {
# Line 108  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 419  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 443  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 461  static SLJIT_INLINE int emit_restore_fla Line 457  static SLJIT_INLINE int emit_restore_fla
457  #ifdef _WIN32  #ifdef _WIN32
458  #include <malloc.h>  #include <malloc.h>
459    
460  static void SLJIT_CALL sljit_touch_stack(sljit_w local_size)  static void SLJIT_CALL sljit_grow_stack(sljit_w local_size)
461  {  {
462          /* Workaround for calling _chkstk. */          /* Workaround for calling the internal _chkstk() function on Windows.
463            This function touches all 4k pages belongs to the requested stack space,
464            which size is passed in local_size. This is necessary on Windows where
465            the stack can only grow in 4k steps. However, this function just burn
466            CPU cycles if the stack is large enough, but you don't know it in advance.
467            I think this is a bad design even if it has some reasons. */
468          alloca(local_size);          alloca(local_size);
469  }  }
470    
471  #endif  #endif
472    
473  #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)  #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
# Line 474  static void SLJIT_CALL sljit_touch_stack Line 476  static void SLJIT_CALL sljit_touch_stack
476  #include "sljitNativeX86_64.c"  #include "sljitNativeX86_64.c"
477  #endif  #endif
478    
 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)  
 {  
         sljit_ub *buf;  
   
         CHECK_ERROR();  
         check_sljit_emit_op0(compiler, op);  
   
         op = GET_OPCODE(op);  
         switch (op) {  
         case SLJIT_BREAKPOINT:  
                 buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);  
                 FAIL_IF(!buf);  
                 INC_SIZE(1);  
                 *buf = 0xcc;  
                 break;  
         case SLJIT_NOP:  
                 buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);  
                 FAIL_IF(!buf);  
                 INC_SIZE(1);  
                 *buf = 0x90;  
                 break;  
         }  
   
         return SLJIT_SUCCESS;  
 }  
   
479  static int emit_mov(struct sljit_compiler *compiler,  static int emit_mov(struct sljit_compiler *compiler,
480          int dst, sljit_w dstw,          int dst, sljit_w dstw,
481          int src, sljit_w srcw)          int src, sljit_w srcw)
# Line 568  static int emit_mov(struct sljit_compile Line 544  static int emit_mov(struct sljit_compile
544  #define EMIT_MOV(compiler, dst, dstw, src, srcw) \  #define EMIT_MOV(compiler, dst, dstw, src, srcw) \
545          FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));          FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
546    
547    SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
548    {
549            sljit_ub *buf;
550    #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
551            int size;
552    #endif
553    
554            CHECK_ERROR();
555            check_sljit_emit_op0(compiler, op);
556    
557            switch (GET_OPCODE(op)) {
558            case SLJIT_BREAKPOINT:
559                    buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
560                    FAIL_IF(!buf);
561                    INC_SIZE(1);
562                    *buf = 0xcc;
563                    break;
564            case SLJIT_NOP:
565                    buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
566                    FAIL_IF(!buf);
567                    INC_SIZE(1);
568                    *buf = 0x90;
569                    break;
570            case SLJIT_UMUL:
571            case SLJIT_SMUL:
572            case SLJIT_UDIV:
573            case SLJIT_SDIV:
574                    compiler->flags_saved = 0;
575    #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
576    #ifdef _WIN64
577                    SLJIT_COMPILE_ASSERT(
578                            reg_map[SLJIT_TEMPORARY_REG1] == 0
579                            && reg_map[SLJIT_TEMPORARY_REG2] == 2
580                            && reg_map[TMP_REGISTER] > 7,
581                            invalid_register_assignment_for_div_mul);
582    #else
583                    SLJIT_COMPILE_ASSERT(
584                            reg_map[SLJIT_TEMPORARY_REG1] == 0
585                            && reg_map[SLJIT_TEMPORARY_REG2] < 7
586                            && reg_map[TMP_REGISTER] == 2,
587                            invalid_register_assignment_for_div_mul);
588    #endif
589                    compiler->mode32 = op & SLJIT_INT_OP;
590    #endif
591    
592                    op = GET_OPCODE(op);
593                    if (op == SLJIT_UDIV) {
594    #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
595                            EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0);
596                            buf = emit_x86_instruction(compiler, 1, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0);
597    #else
598                            buf = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
599    #endif
600                            FAIL_IF(!buf);
601                            *buf = 0x33;
602                    }
603    
604                    if (op == SLJIT_SDIV) {
605    #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
606                            EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0);
607    #endif
608    
609                            /* CDQ instruction */
610    #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
611                            buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
612                            FAIL_IF(!buf);
613                            INC_SIZE(1);
614                            *buf = 0x99;
615    #else
616                            if (compiler->mode32) {
617                                    buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
618                                    FAIL_IF(!buf);
619                                    INC_SIZE(1);
620                                    *buf = 0x99;
621                            } else {
622                                    buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
623                                    FAIL_IF(!buf);
624                                    INC_SIZE(2);
625                                    *buf++ = REX_W;
626                                    *buf = 0x99;
627                            }
628    #endif
629                    }
630    
631    #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
632                    buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
633                    FAIL_IF(!buf);
634                    INC_SIZE(2);
635                    *buf++ = 0xf7;
636                    *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_map[TMP_REGISTER] : reg_map[SLJIT_TEMPORARY_REG2]);
637    #else
638    #ifdef _WIN64
639                    size = (!compiler->mode32 || op >= SLJIT_UDIV) ? 3 : 2;
640    #else
641                    size = (!compiler->mode32) ? 3 : 2;
642    #endif
643                    buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
644                    FAIL_IF(!buf);
645                    INC_SIZE(size);
646    #ifdef _WIN64
647                    if (!compiler->mode32)
648                            *buf++ = REX_W | ((op >= SLJIT_UDIV) ? REX_B : 0);
649                    else if (op >= SLJIT_UDIV)
650                            *buf++ = REX_B;
651                    *buf++ = 0xf7;
652                    *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_lmap[TMP_REGISTER] : reg_lmap[SLJIT_TEMPORARY_REG2]);
653    #else
654                    if (!compiler->mode32)
655                            *buf++ = REX_W;
656                    *buf++ = 0xf7;
657                    *buf = 0xc0 | reg_map[SLJIT_TEMPORARY_REG2];
658    #endif
659    #endif
660                    switch (op) {
661                    case SLJIT_UMUL:
662                            *buf |= 4 << 3;
663                            break;
664                    case SLJIT_SMUL:
665                            *buf |= 5 << 3;
666                            break;
667                    case SLJIT_UDIV:
668                            *buf |= 6 << 3;
669                            break;
670                    case SLJIT_SDIV:
671                            *buf |= 7 << 3;
672                            break;
673                    }
674    #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64)
675                    EMIT_MOV(compiler, SLJIT_TEMPORARY_REG2, 0, TMP_REGISTER, 0);
676    #endif
677                    break;
678            }
679    
680            return SLJIT_SUCCESS;
681    }
682    
683  #define ENCODE_PREFIX(prefix) \  #define ENCODE_PREFIX(prefix) \
684          do { \          do { \
685                  code = (sljit_ub*)ensure_buf(compiler, 1 + 1); \                  code = (sljit_ub*)ensure_buf(compiler, 1 + 1); \
# Line 853  static int emit_clz(struct sljit_compile Line 965  static int emit_clz(struct sljit_compile
965          sljit_ub* code;          sljit_ub* code;
966          int dst_r;          int dst_r;
967    
968            SLJIT_UNUSED_ARG(op);
969          if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {          if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
970                  /* Just set the zero flag. */                  /* Just set the zero flag. */
971                  EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);                  EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
# Line 943  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 1056  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
1056    
1057          CHECK_ERROR();          CHECK_ERROR();
1058          check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);          check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
1059            ADJUST_LOCAL_OFFSET(dst, dstw);
1060            ADJUST_LOCAL_OFFSET(src, srcw);
1061    
1062            CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);
1063            CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1);
1064  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1065          compiler->mode32 = op & SLJIT_INT_OP;          compiler->mode32 = op & SLJIT_INT_OP;
1066  #endif  #endif
         CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);  
         CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1);  
1067    
1068          if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) {          if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) {
1069                  op = GET_OPCODE(op);                  op = GET_OPCODE(op);
# Line 1451  static int emit_lea_binary(struct sljit_ Line 1566  static int emit_lea_binary(struct sljit_
1566          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;
1567    
1568          if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {          if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
1569                  if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {                  if ((src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) || src2 == TMP_REGISTER) {
1570                          /* It is not possible to be both SLJIT_LOCALS_REG. */                          code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0);
1571                          if (src1 != SLJIT_LOCALS_REG || src2 != SLJIT_LOCALS_REG) {                          FAIL_IF(!code);
1572                                  code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0);                          *code = 0x8d;
1573                                  FAIL_IF(!code);                          done = 1;
                                 *code = 0x8d;  
                                 done = 1;  
                         }  
1574                  }                  }
1575  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1576                  if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) {                  if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) {
# Line 1718  static int emit_shift(struct sljit_compi Line 1830  static int emit_shift(struct sljit_compi
1830                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1831          }          }
1832          else {          else {
1833                  /* This case is really difficult, since ecx can be used for                  /* This case is really difficult, since ecx itself may used for
1834                     addressing as well, and we must ensure to work even in that case. */                     addressing, and we must ensure to work even in that case. */
1835                    EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1836  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1837                  EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);                  EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);
1838  #else  #else
1839                  /* [esp - 4] is reserved for eflags. */                  /* [esp+0] contains the flags. */
1840                  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);
1841  #endif  #endif
   
                 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);  
1842                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
1843                  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);
1844                  FAIL_IF(!code);                  FAIL_IF(!code);
1845                  *code |= mode;                  *code |= mode;
   
1846  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1847                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);
1848  #else  #else
1849                  /* [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)));  
1850  #endif  #endif
1851                  EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);                  EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1852          }          }
# Line 1745  static int emit_shift(struct sljit_compi Line 1854  static int emit_shift(struct sljit_compi
1854          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
1855  }  }
1856    
1857    static int emit_shift_with_flags(struct sljit_compiler *compiler,
1858            sljit_ub mode, int set_flags,
1859            int dst, sljit_w dstw,
1860            int src1, sljit_w src1w,
1861            int src2, sljit_w src2w)
1862    {
1863            /* The CPU does not set flags if the shift count is 0. */
1864            if (src2 & SLJIT_IMM) {
1865    #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1866                    if ((src2w & 0x3f) != 0 || (compiler->mode32 && (src2w & 0x1f) != 0))
1867                            return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
1868    #else
1869                    if ((src2w & 0x1f) != 0)
1870                            return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
1871    #endif
1872                    if (!set_flags)
1873                            return emit_mov(compiler, dst, dstw, src1, src1w);
1874                    /* OR dst, src, 0 */
1875                    return emit_cum_binary(compiler, 0x0b, 0x09, 0x1 << 3, 0x0d,
1876                            dst, dstw, src1, src1w, SLJIT_IMM, 0);
1877            }
1878    
1879            if (!set_flags)
1880                    return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
1881    
1882            if (!(dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS))
1883                    FAIL_IF(emit_cmp_binary(compiler, src1, src1w, SLJIT_IMM, 0));
1884    
1885            FAIL_IF(emit_shift(compiler,mode, dst, dstw, src1, src1w, src2, src2w));
1886    
1887            if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)
1888                    return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0);
1889            return SLJIT_SUCCESS;
1890    }
1891    
1892  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
1893          int dst, sljit_w dstw,          int dst, sljit_w dstw,
1894          int src1, sljit_w src1w,          int src1, sljit_w src1w,
# Line 1752  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 1896  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
1896  {  {
1897          CHECK_ERROR();          CHECK_ERROR();
1898          check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);          check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
1899            ADJUST_LOCAL_OFFSET(dst, dstw);
1900            ADJUST_LOCAL_OFFSET(src1, src1w);
1901            ADJUST_LOCAL_OFFSET(src2, src2w);
1902    
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  
         compiler->mode32 = op & SLJIT_INT_OP;  
 #endif  
1903          CHECK_EXTRA_REGS(dst, dstw, (void)0);          CHECK_EXTRA_REGS(dst, dstw, (void)0);
1904          CHECK_EXTRA_REGS(src1, src1w, (void)0);          CHECK_EXTRA_REGS(src1, src1w, (void)0);
1905          CHECK_EXTRA_REGS(src2, src2w, (void)0);          CHECK_EXTRA_REGS(src2, src2w, (void)0);
1906    #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1907            compiler->mode32 = op & SLJIT_INT_OP;
1908    #endif
1909    
1910          if (GET_OPCODE(op) >= SLJIT_MUL) {          if (GET_OPCODE(op) >= SLJIT_MUL) {
1911                  if (SLJIT_UNLIKELY(GET_FLAGS(op)))                  if (SLJIT_UNLIKELY(GET_FLAGS(op)))
# Line 1772  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 1919  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
1919                  if (!GET_FLAGS(op)) {                  if (!GET_FLAGS(op)) {
1920                          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)
1921                                  return compiler->error;                                  return compiler->error;
1922                  }                  }
1923                  else                  else
1924                          compiler->flags_saved = 0;                          compiler->flags_saved = 0;
1925                  if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)                  if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
# Line 1824  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 1971  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
1971                  return emit_cum_binary(compiler, 0x33, 0x31, 0x6 << 3, 0x35,                  return emit_cum_binary(compiler, 0x33, 0x31, 0x6 << 3, 0x35,
1972                          dst, dstw, src1, src1w, src2, src2w);                          dst, dstw, src1, src1w, src2, src2w);
1973          case SLJIT_SHL:          case SLJIT_SHL:
1974                  return emit_shift(compiler, 0x4 << 3,                  return emit_shift_with_flags(compiler, 0x4 << 3, GET_FLAGS(op),
1975                          dst, dstw, src1, src1w, src2, src2w);                          dst, dstw, src1, src1w, src2, src2w);
1976          case SLJIT_LSHR:          case SLJIT_LSHR:
1977                  return emit_shift(compiler, 0x5 << 3,                  return emit_shift_with_flags(compiler, 0x5 << 3, GET_FLAGS(op),
1978                          dst, dstw, src1, src1w, src2, src2w);                          dst, dstw, src1, src1w, src2, src2w);
1979          case SLJIT_ASHR:          case SLJIT_ASHR:
1980                  return emit_shift(compiler, 0x7 << 3,                  return emit_shift_with_flags(compiler, 0x7 << 3, GET_FLAGS(op),
1981                          dst, dstw, src1, src1w, src2, src2w);                          dst, dstw, src1, src1w, src2, src2w);
1982          }          }
1983    
# Line 1842  SLJIT_API_FUNC_ATTRIBUTE int sljit_get_r Line 1989  SLJIT_API_FUNC_ATTRIBUTE int sljit_get_r
1989          check_sljit_get_register_index(reg);          check_sljit_get_register_index(reg);
1990  #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)  #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1991          if (reg == SLJIT_TEMPORARY_EREG1 || reg == SLJIT_TEMPORARY_EREG2          if (reg == SLJIT_TEMPORARY_EREG1 || reg == SLJIT_TEMPORARY_EREG2
1992                          || reg == SLJIT_GENERAL_EREG1 || reg == SLJIT_GENERAL_EREG2)                          || reg == SLJIT_SAVED_EREG1 || reg == SLJIT_SAVED_EREG2)
1993                  return -1;                  return -1;
1994  #endif  #endif
1995          return reg_map[reg];          return reg_map[reg];
# Line 1868  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 2015  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2015  /*  Floating point operators                                             */  /*  Floating point operators                                             */
2016  /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
2017    
 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
 static int sse2_available = 0;  
 #endif  
   
2018  #if (defined SLJIT_SSE2 && SLJIT_SSE2)  #if (defined SLJIT_SSE2 && SLJIT_SSE2)
2019    
2020  /* Alignment + 2 * 16 bytes. */  /* Alignment + 2 * 16 bytes. */
# Line 1880  static sljit_i *sse2_buffer; Line 2023  static sljit_i *sse2_buffer;
2023    
2024  static void init_compiler()  static void init_compiler()
2025  {  {
 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
         int features = 0;  
 #endif  
   
2026          sse2_buffer = (sljit_i*)(((sljit_uw)sse2_data + 15) & ~0xf);          sse2_buffer = (sljit_i*)(((sljit_uw)sse2_data + 15) & ~0xf);
2027          sse2_buffer[0] = 0;          sse2_buffer[0] = 0;
2028          sse2_buffer[1] = 0x80000000;          sse2_buffer[1] = 0x80000000;
2029          sse2_buffer[4] = 0xffffffff;          sse2_buffer[4] = 0xffffffff;
2030          sse2_buffer[5] = 0x7fffffff;          sse2_buffer[5] = 0x7fffffff;
2031    }
2032    
2033    #endif
2034    
2035    SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
2036    {
2037    #if (defined SLJIT_SSE2 && SLJIT_SSE2)
2038    #if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
2039            static int sse2_available = -1;
2040            int features;
2041    
2042            if (sse2_available != -1)
2043                    return sse2_available;
2044    
 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
2045  #ifdef __GNUC__  #ifdef __GNUC__
2046          /* AT&T syntax. */          /* AT&T syntax. */
2047          asm (          asm (
# Line 1913  static void init_compiler() Line 2064  static void init_compiler()
2064                  mov features, edx                  mov features, edx
2065          }          }
2066  #else  #else
2067          #error "SLJIT_SSE2_AUTO is not implemented for this C compiler"          #error "SLJIT_DETECT_SSE2 is not implemented for this C compiler"
2068  #endif  #endif
2069          sse2_available = (features >> 26) & 0x1;          sse2_available = (features >> 26) & 0x1;
2070            return sse2_available;
2071    #else
2072            return 1;
2073  #endif  #endif
2074  }  #else
2075            return 0;
2076  #endif  #endif
   
 SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)  
 {  
         /* Always available. */  
         return 1;  
2077  }  }
2078    
2079  #if (defined SLJIT_SSE2 && SLJIT_SSE2)  #if (defined SLJIT_SSE2 && SLJIT_SSE2)
# Line 1965  static SLJIT_INLINE int emit_sse2_store( Line 2114  static SLJIT_INLINE int emit_sse2_store(
2114          return emit_sse2(compiler, 0x11, src, dst, dstw);          return emit_sse2(compiler, 0x11, src, dst, dstw);
2115  }  }
2116    
 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
2117  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  
2118          int dst, sljit_w dstw,          int dst, sljit_w dstw,
2119          int src, sljit_w srcw)          int src, sljit_w srcw)
2120  {  {
# Line 2027  static int sljit_emit_sse2_fop1(struct s Line 2172  static int sljit_emit_sse2_fop1(struct s
2172          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
2173  }  }
2174    
 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
2175  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  
2176          int dst, sljit_w dstw,          int dst, sljit_w dstw,
2177          int src1, sljit_w src1w,          int src1, sljit_w src1w,
2178          int src2, sljit_w src2w)          int src2, sljit_w src2w)
# Line 2089  static int sljit_emit_sse2_fop2(struct s Line 2230  static int sljit_emit_sse2_fop2(struct s
2230          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
2231  }  }
2232    
2233  #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;  
 }  
2234    
 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
2235  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  
2236          int dst, sljit_w dstw,          int dst, sljit_w dstw,
2237          int src, sljit_w srcw)          int src, sljit_w srcw)
2238  {  {
 #if !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  
         sljit_ub *buf;  
 #endif  
   
2239          CHECK_ERROR();          CHECK_ERROR();
2240            /* Should cause an assertion fail. */
2241          check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);          check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
2242            compiler->error = SLJIT_ERR_UNSUPPORTED;
2243  #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;  
2244  }  }
2245    
 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
2246  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  
2247          int dst, sljit_w dstw,          int dst, sljit_w dstw,
2248          int src1, sljit_w src1w,          int src1, sljit_w src1w,
2249          int src2, sljit_w src2w)          int src2, sljit_w src2w)
2250  {  {
2251          CHECK_ERROR();          CHECK_ERROR();
2252            /* Should cause an assertion fail. */
2253          check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);          check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2254            compiler->error = SLJIT_ERR_UNSUPPORTED;
2255  #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);  
2256  }  }
2257    
2258  #endif  #endif
# Line 2394  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 2334  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2334    
2335          CHECK_ERROR();          CHECK_ERROR();
2336          check_sljit_emit_ijump(compiler, type, src, srcw);          check_sljit_emit_ijump(compiler, type, src, srcw);
2337            ADJUST_LOCAL_OFFSET(src, srcw);
2338    
2339          CHECK_EXTRA_REGS(src, srcw, (void)0);          CHECK_EXTRA_REGS(src, srcw, (void)0);
2340    
2341          if (SLJIT_UNLIKELY(compiler->flags_saved)) {          if (SLJIT_UNLIKELY(compiler->flags_saved)) {
2342                  if (type <= SLJIT_JUMP)                  if (type <= SLJIT_JUMP)
2343                          FAIL_IF(emit_restore_flags(compiler, 0));                          FAIL_IF(emit_restore_flags(compiler, 0));
# Line 2409  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 2351  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2351                          EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);                          EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
2352                          src = TMP_REGISTER;                          src = TMP_REGISTER;
2353                  }                  }
2354                  if ((src & SLJIT_MEM) && (src & 0xf) == SLJIT_LOCALS_REG && type >= SLJIT_CALL3) {                  if (src == SLJIT_MEM1(SLJIT_LOCALS_REG) && type >= SLJIT_CALL3)
2355                          if (src & 0xf0) {                          srcw += sizeof(sljit_w);
                                 EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);  
                                 src = TMP_REGISTER;  
                         }  
                         else  
                                 srcw += sizeof(sljit_w);  
                 }  
2356  #else  #else
2357                  if ((src & SLJIT_MEM) && (src & 0xf) == SLJIT_LOCALS_REG) {                  if (src == SLJIT_MEM1(SLJIT_LOCALS_REG))
2358                          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);  
                 }  
2359  #endif  #endif
2360  #endif  #endif
2361  #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 2473  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 2403  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2403  {  {
2404          sljit_ub *buf;          sljit_ub *buf;
2405          sljit_ub cond_set = 0;          sljit_ub cond_set = 0;
2406            int dst_save = dst;
2407            sljit_w dstw_save = dstw;
2408  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2409          int reg;          int reg;
2410  #endif  #endif
# Line 2483  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 2415  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2415          if (dst == SLJIT_UNUSED)          if (dst == SLJIT_UNUSED)
2416                  return SLJIT_SUCCESS;                  return SLJIT_SUCCESS;
2417    
2418            ADJUST_LOCAL_OFFSET(dst, dstw);
2419          CHECK_EXTRA_REGS(dst, dstw, (void)0);          CHECK_EXTRA_REGS(dst, dstw, (void)0);
2420          if (SLJIT_UNLIKELY(compiler->flags_saved))          if (SLJIT_UNLIKELY(compiler->flags_saved))
2421                  FAIL_IF(emit_restore_flags(compiler, 0));                  FAIL_IF(emit_restore_flags(compiler, op & SLJIT_KEEP_FLAGS));
2422    
2423          switch (type) {          switch (type) {
2424          case SLJIT_C_EQUAL:          case SLJIT_C_EQUAL:
# Line 2578  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 2511  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2511  #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)  #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
2512                          compiler->skip_checks = 1;                          compiler->skip_checks = 1;
2513  #endif  #endif
2514                          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);
2515                  }                  }
2516          }          }
2517  #else  #else
# Line 2609  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 2542  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2542    
2543                          *buf++ = 0x0f;                          *buf++ = 0x0f;
2544                          *buf++ = 0xb6;                          *buf++ = 0xb6;
2545                          if (dst >= SLJIT_GENERAL_REG1 && dst <= SLJIT_NO_REGISTERS)                          if (dst >= SLJIT_SAVED_REG1 && dst <= SLJIT_NO_REGISTERS)
2546                                  *buf = 0xC0 | (reg_map[dst] << 3);                                  *buf = 0xC0 | (reg_map[dst] << 3);
2547                          else {                          else {
2548                                  *buf = 0xC0;                                  *buf = 0xC0;
# Line 2650  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 2583  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2583  #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)  #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
2584                  compiler->skip_checks = 1;                  compiler->skip_checks = 1;
2585  #endif  #endif
2586                  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);
2587          }          }
2588  #endif  #endif
2589    
2590          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
2591  }  }
2592    
2593    SLJIT_API_FUNC_ATTRIBUTE int sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w offset)
2594    {
2595            CHECK_ERROR();
2596            check_sljit_get_local_base(compiler, dst, dstw, offset);
2597            ADJUST_LOCAL_OFFSET(dst, dstw);
2598    
2599            CHECK_EXTRA_REGS(dst, dstw, (void)0);
2600    
2601    #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2602            compiler->mode32 = 0;
2603    #endif
2604    
2605            ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_LOCALS_REG), offset);
2606    
2607    #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2608            if (NOT_HALFWORD(offset)) {
2609                    FAIL_IF(emit_load_imm64(compiler, TMP_REGISTER, offset));
2610    #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
2611                    SLJIT_ASSERT(emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0) != SLJIT_ERR_UNSUPPORTED);
2612                    return compiler->error;
2613    #else
2614                    return emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0);
2615    #endif
2616            }
2617    #endif
2618    
2619            if (offset != 0)
2620                    return emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, SLJIT_IMM, offset);
2621            return emit_mov(compiler, dst, dstw, SLJIT_LOCALS_REG, 0);
2622    }
2623    
2624  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)
2625  {  {
2626          sljit_ub *buf;          sljit_ub *buf;
# Line 2667  SLJIT_API_FUNC_ATTRIBUTE struct sljit_co Line 2631  SLJIT_API_FUNC_ATTRIBUTE struct sljit_co
2631    
2632          CHECK_ERROR_PTR();          CHECK_ERROR_PTR();
2633          check_sljit_emit_const(compiler, dst, dstw, init_value);          check_sljit_emit_const(compiler, dst, dstw, init_value);
2634            ADJUST_LOCAL_OFFSET(dst, dstw);
2635    
2636          CHECK_EXTRA_REGS(dst, dstw, (void)0);          CHECK_EXTRA_REGS(dst, dstw, (void)0);
2637    

Legend:
Removed from v.839  
changed lines
  Added in v.966

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12