/[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 880 by zherczeg, Sun Jan 15 17:23:37 2012 UTC
# Line 80  static SLJIT_CONST sljit_ub reg_map[SLJI Line 80  static SLJIT_CONST sljit_ub reg_map[SLJI
80                  p = SLJIT_MEM1(SLJIT_LOCALS_REG); \                  p = SLJIT_MEM1(SLJIT_LOCALS_REG); \
81                  do; \                  do; \
82          } \          } \
83          else if (p >= SLJIT_GENERAL_EREG1 && p <= SLJIT_GENERAL_EREG2) { \          else if (p >= SLJIT_SAVED_EREG1 && p <= SLJIT_SAVED_EREG2) { \
84                  w = compiler->generals_start + (p - SLJIT_GENERAL_EREG1) * sizeof(sljit_w); \                  w = compiler->saveds_start + (p - SLJIT_SAVED_EREG1) * sizeof(sljit_w); \
85                  p = SLJIT_MEM1(SLJIT_LOCALS_REG); \                  p = SLJIT_MEM1(SLJIT_LOCALS_REG); \
86                  do; \                  do; \
87          }          }
# Line 95  static SLJIT_CONST sljit_ub reg_map[SLJI Line 95  static SLJIT_CONST sljit_ub reg_map[SLJI
95    
96  /* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present  /* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present
97     Note: avoid to use r12 and r13 for memory addessing     Note: avoid to use r12 and r13 for memory addessing
98     therefore r12 is better for GENERAL_EREG than GENERAL_REG. */     therefore r12 is better for SAVED_EREG than SAVED_REG. */
99  #ifndef _WIN64  #ifndef _WIN64
100  /* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */  /* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */
101  static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {  static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {
# Line 474  static void SLJIT_CALL sljit_touch_stack Line 474  static void SLJIT_CALL sljit_touch_stack
474  #include "sljitNativeX86_64.c"  #include "sljitNativeX86_64.c"
475  #endif  #endif
476    
 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;  
 }  
   
477  static int emit_mov(struct sljit_compiler *compiler,  static int emit_mov(struct sljit_compiler *compiler,
478          int dst, sljit_w dstw,          int dst, sljit_w dstw,
479          int src, sljit_w srcw)          int src, sljit_w srcw)
# Line 568  static int emit_mov(struct sljit_compile Line 542  static int emit_mov(struct sljit_compile
542  #define EMIT_MOV(compiler, dst, dstw, src, srcw) \  #define EMIT_MOV(compiler, dst, dstw, src, srcw) \
543          FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));          FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
544    
545    SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
546    {
547            sljit_ub *buf;
548    #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
549            int size;
550    #endif
551    
552            CHECK_ERROR();
553            check_sljit_emit_op0(compiler, op);
554    
555            switch (GET_OPCODE(op)) {
556            case SLJIT_BREAKPOINT:
557                    buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
558                    FAIL_IF(!buf);
559                    INC_SIZE(1);
560                    *buf = 0xcc;
561                    break;
562            case SLJIT_NOP:
563                    buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
564                    FAIL_IF(!buf);
565                    INC_SIZE(1);
566                    *buf = 0x90;
567                    break;
568            case SLJIT_UMUL:
569            case SLJIT_SMUL:
570            case SLJIT_UDIV:
571            case SLJIT_SDIV:
572                    compiler->flags_saved = 0;
573    #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
574    #ifdef _WIN64
575                    SLJIT_COMPILE_ASSERT(
576                            reg_map[SLJIT_TEMPORARY_REG1] == 0
577                            && reg_map[SLJIT_TEMPORARY_REG2] == 2
578                            && reg_map[TMP_REGISTER] > 7,
579                            invalid_register_assignment_for_div_mul);
580    #else
581                    SLJIT_COMPILE_ASSERT(
582                            reg_map[SLJIT_TEMPORARY_REG1] == 0
583                            && reg_map[SLJIT_TEMPORARY_REG2] < 7
584                            && reg_map[TMP_REGISTER] == 2,
585                            invalid_register_assignment_for_div_mul);
586    #endif
587                    compiler->mode32 = op & SLJIT_INT_OP;
588    #endif
589    
590                    op = GET_OPCODE(op);
591                    if (op == SLJIT_UDIV) {
592    #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
593                            EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0);
594                            buf = emit_x86_instruction(compiler, 1, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0);
595    #else
596                            buf = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
597    #endif
598                            FAIL_IF(!buf);
599                            *buf = 0x33;
600                    }
601    
602                    if (op == SLJIT_SDIV) {
603    #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
604                            EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0);
605    #endif
606    
607                            /* CDQ instruction */
608    #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
609                            buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
610                            FAIL_IF(!buf);
611                            INC_SIZE(1);
612                            *buf = 0x99;
613    #else
614                            if (compiler->mode32) {
615                                    buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
616                                    FAIL_IF(!buf);
617                                    INC_SIZE(1);
618                                    *buf = 0x99;
619                            } else {
620                                    buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
621                                    FAIL_IF(!buf);
622                                    INC_SIZE(2);
623                                    *buf++ = REX_W;
624                                    *buf = 0x99;
625                            }
626    #endif
627                    }
628    
629    #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
630                    buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
631                    FAIL_IF(!buf);
632                    INC_SIZE(2);
633                    *buf++ = 0xf7;
634                    *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_map[TMP_REGISTER] : reg_map[SLJIT_TEMPORARY_REG2]);
635    #else
636    #ifdef _WIN64
637                    size = (!compiler->mode32 || op >= SLJIT_UDIV) ? 3 : 2;
638    #else
639                    size = (!compiler->mode32) ? 3 : 2;
640    #endif
641                    buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
642                    FAIL_IF(!buf);
643                    INC_SIZE(size);
644    #ifdef _WIN64
645                    if (!compiler->mode32)
646                            *buf++ = REX_W | ((op >= SLJIT_UDIV) ? REX_B : 0);
647                    else if (op >= SLJIT_UDIV)
648                            *buf++ = REX_B;
649                    *buf++ = 0xf7;
650                    *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_lmap[TMP_REGISTER] : reg_lmap[SLJIT_TEMPORARY_REG2]);
651    #else
652                    if (!compiler->mode32)
653                            *buf++ = REX_W;
654                    *buf++ = 0xf7;
655                    *buf = 0xc0 | reg_map[SLJIT_TEMPORARY_REG2];
656    #endif
657    #endif
658                    switch (op) {
659                    case SLJIT_UMUL:
660                            *buf |= 4 << 3;
661                            break;
662                    case SLJIT_SMUL:
663                            *buf |= 5 << 3;
664                            break;
665                    case SLJIT_UDIV:
666                            *buf |= 6 << 3;
667                            break;
668                    case SLJIT_SDIV:
669                            *buf |= 7 << 3;
670                            break;
671                    }
672    #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64)
673                    EMIT_MOV(compiler, SLJIT_TEMPORARY_REG2, 0, TMP_REGISTER, 0);
674    #endif
675                    break;
676            }
677    
678            return SLJIT_SUCCESS;
679    }
680    
681  #define ENCODE_PREFIX(prefix) \  #define ENCODE_PREFIX(prefix) \
682          do { \          do { \
683                  code = (sljit_ub*)ensure_buf(compiler, 1 + 1); \                  code = (sljit_ub*)ensure_buf(compiler, 1 + 1); \
# Line 1718  static int emit_shift(struct sljit_compi Line 1828  static int emit_shift(struct sljit_compi
1828                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1829          }          }
1830          else {          else {
1831                  /* This case is really difficult, since ecx can be used for                  /* This case is really difficult, since ecx itself may used for
1832                     addressing as well, and we must ensure to work even in that case. */                     addressing, and we must ensure to work even in that case. */
1833                    EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
1834  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1835                  EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);                  EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);
1836  #else  #else
1837                  /* [esp - 4] is reserved for eflags. */                  /* [esp - 4] is reserved for eflags. */
1838                  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), -(int)(2 * sizeof(sljit_w)), SLJIT_PREF_SHIFT_REG, 0);
1839  #endif  #endif
   
                 EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);  
1840                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
1841                  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);
1842                  FAIL_IF(!code);                  FAIL_IF(!code);
1843                  *code |= mode;                  *code |= mode;
   
1844  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1845                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);
1846  #else  #else
# Line 1745  static int emit_shift(struct sljit_compi Line 1853  static int emit_shift(struct sljit_compi
1853          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
1854  }  }
1855    
1856    static int emit_shift_with_flags(struct sljit_compiler *compiler,
1857            sljit_ub mode, int set_flags,
1858            int dst, sljit_w dstw,
1859            int src1, sljit_w src1w,
1860            int src2, sljit_w src2w)
1861    {
1862            /* The CPU does not set flags if the shift count is 0. */
1863            if (src2 & SLJIT_IMM) {
1864    #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1865                    if ((src2w & 0x3f) != 0 || (compiler->mode32 && (src2w & 0x1f) != 0))
1866                            return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
1867    #else
1868                    if ((src2w & 0x1f) != 0)
1869                            return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
1870    #endif
1871                    if (!set_flags)
1872                            return emit_mov(compiler, dst, dstw, src1, src1w);
1873                    /* OR dst, src, 0 */
1874                    return emit_cum_binary(compiler, 0x0b, 0x09, 0x1 << 3, 0x0d,
1875                            dst, dstw, src1, src1w, SLJIT_IMM, 0);
1876            }
1877    
1878            if (!set_flags)
1879                    return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
1880    
1881            if (!(dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS))
1882                    FAIL_IF(emit_cmp_binary(compiler, src1, src1w, SLJIT_IMM, 0));
1883    
1884            FAIL_IF(emit_shift(compiler,mode, dst, dstw, src1, src1w, src2, src2w));
1885    
1886            if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)
1887                    return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0);
1888            return SLJIT_SUCCESS;
1889    }
1890    
1891  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,
1892          int dst, sljit_w dstw,          int dst, sljit_w dstw,
1893          int src1, sljit_w src1w,          int src1, sljit_w src1w,
# Line 1824  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 1967  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
1967                  return emit_cum_binary(compiler, 0x33, 0x31, 0x6 << 3, 0x35,                  return emit_cum_binary(compiler, 0x33, 0x31, 0x6 << 3, 0x35,
1968                          dst, dstw, src1, src1w, src2, src2w);                          dst, dstw, src1, src1w, src2, src2w);
1969          case SLJIT_SHL:          case SLJIT_SHL:
1970                  return emit_shift(compiler, 0x4 << 3,                  return emit_shift_with_flags(compiler, 0x4 << 3, GET_FLAGS(op),
1971                          dst, dstw, src1, src1w, src2, src2w);                          dst, dstw, src1, src1w, src2, src2w);
1972          case SLJIT_LSHR:          case SLJIT_LSHR:
1973                  return emit_shift(compiler, 0x5 << 3,                  return emit_shift_with_flags(compiler, 0x5 << 3, GET_FLAGS(op),
1974                          dst, dstw, src1, src1w, src2, src2w);                          dst, dstw, src1, src1w, src2, src2w);
1975          case SLJIT_ASHR:          case SLJIT_ASHR:
1976                  return emit_shift(compiler, 0x7 << 3,                  return emit_shift_with_flags(compiler, 0x7 << 3, GET_FLAGS(op),
1977                          dst, dstw, src1, src1w, src2, src2w);                          dst, dstw, src1, src1w, src2, src2w);
1978          }          }
1979    
# Line 1842  SLJIT_API_FUNC_ATTRIBUTE int sljit_get_r Line 1985  SLJIT_API_FUNC_ATTRIBUTE int sljit_get_r
1985          check_sljit_get_register_index(reg);          check_sljit_get_register_index(reg);
1986  #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)  #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1987          if (reg == SLJIT_TEMPORARY_EREG1 || reg == SLJIT_TEMPORARY_EREG2          if (reg == SLJIT_TEMPORARY_EREG1 || reg == SLJIT_TEMPORARY_EREG2
1988                          || reg == SLJIT_GENERAL_EREG1 || reg == SLJIT_GENERAL_EREG2)                          || reg == SLJIT_SAVED_EREG1 || reg == SLJIT_SAVED_EREG2)
1989                  return -1;                  return -1;
1990  #endif  #endif
1991          return reg_map[reg];          return reg_map[reg];
# Line 2609  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 2752  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2752    
2753                          *buf++ = 0x0f;                          *buf++ = 0x0f;
2754                          *buf++ = 0xb6;                          *buf++ = 0xb6;
2755                          if (dst >= SLJIT_GENERAL_REG1 && dst <= SLJIT_NO_REGISTERS)                          if (dst >= SLJIT_SAVED_REG1 && dst <= SLJIT_NO_REGISTERS)
2756                                  *buf = 0xC0 | (reg_map[dst] << 3);                                  *buf = 0xC0 | (reg_map[dst] << 3);
2757                          else {                          else {
2758                                  *buf = 0xC0;                                  *buf = 0xC0;

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

  ViewVC Help
Powered by ViewVC 1.1.5