/[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 704 by zherczeg, Wed Sep 21 12:35:36 2011 UTC revision 880 by zherczeg, Sun Jan 15 17:23:37 2012 UTC
# Line 1  Line 1 
1  /*  /*
2   *    Stack-less Just-In-Time compiler   *    Stack-less Just-In-Time compiler
3   *   *
4   *    Copyright 2009-2010 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.   *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
5   *   *
6   * Redistribution and use in source and binary forms, with or without modification, are   * Redistribution and use in source and binary forms, with or without modification, are
7   * permitted provided that the following conditions are met:   * permitted provided that the following conditions are met:
# Line 24  Line 24 
24   * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25   */   */
26    
27  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)  #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
30          return "x86-32";          return "x86-32";
# 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 245  static sljit_ub* generate_near_jump_code Line 245  static sljit_ub* generate_near_jump_code
245                          *code_ptr++ = 0xe9;                          *code_ptr++ = 0xe9;
246                  jump->addr++;                  jump->addr++;
247          }          }
248          else if (type >= SLJIT_CALL0) {          else if (type >= SLJIT_FAST_CALL) {
249                  short_jump = 0;                  short_jump = 0;
250                  *code_ptr++ = 0xe8;                  *code_ptr++ = 0xe8;
251                  jump->addr++;                  jump->addr++;
# Line 275  static sljit_ub* generate_near_jump_code Line 275  static sljit_ub* generate_near_jump_code
275          return code_ptr;          return code_ptr;
276  }  }
277    
278  void* sljit_generate_code(struct sljit_compiler *compiler)  SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
279  {  {
280          struct sljit_memory_fragment *buf;          struct sljit_memory_fragment *buf;
281          sljit_ub *code;          sljit_ub *code;
# Line 357  void* sljit_generate_code(struct sljit_c Line 357  void* sljit_generate_code(struct sljit_c
357          while (jump) {          while (jump) {
358                  if (jump->flags & PATCH_MB) {                  if (jump->flags & PATCH_MB) {
359                          SLJIT_ASSERT((sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))) >= -128 && (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))) <= 127);                          SLJIT_ASSERT((sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))) >= -128 && (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))) <= 127);
360                          *(sljit_ub*)jump->addr = jump->u.label->addr - (jump->addr + sizeof(sljit_b));                          *(sljit_ub*)jump->addr = (sljit_ub)(jump->u.label->addr - (jump->addr + sizeof(sljit_b)));
361                  } else if (jump->flags & PATCH_MW) {                  } else if (jump->flags & PATCH_MW) {
362                          if (jump->flags & JUMP_LABEL) {                          if (jump->flags & JUMP_LABEL) {
363  #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)  #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
364                                  *(sljit_w*)jump->addr = jump->u.label->addr - (jump->addr + sizeof(sljit_w));                                  *(sljit_w*)jump->addr = (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_w)));
365  #else  #else
366                                  SLJIT_ASSERT((sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll);                                  SLJIT_ASSERT((sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll);
367                                  *(sljit_hw*)jump->addr = jump->u.label->addr - (jump->addr + sizeof(sljit_hw));                                  *(sljit_hw*)jump->addr = (sljit_hw)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw)));
368  #endif  #endif
369                          }                          }
370                          else {                          else {
371  #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)  #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
372                                  *(sljit_w*)jump->addr = jump->u.target - (jump->addr + sizeof(sljit_w));                                  *(sljit_w*)jump->addr = (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_w)));
373  #else  #else
374                                  SLJIT_ASSERT((sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll);                                  SLJIT_ASSERT((sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll);
375                                  *(sljit_hw*)jump->addr = jump->u.target - (jump->addr + sizeof(sljit_hw));                                  *(sljit_hw*)jump->addr = (sljit_hw)(jump->u.target - (jump->addr + sizeof(sljit_hw)));
376  #endif  #endif
377                          }                          }
378                  }                  }
# Line 387  void* sljit_generate_code(struct sljit_c Line 387  void* sljit_generate_code(struct sljit_c
387          /* Maybe we waste some space because of short jumps. */          /* Maybe we waste some space because of short jumps. */
388          SLJIT_ASSERT(code_ptr <= code + compiler->size);          SLJIT_ASSERT(code_ptr <= code + compiler->size);
389          compiler->error = SLJIT_ERR_COMPILED;          compiler->error = SLJIT_ERR_COMPILED;
390            compiler->executable_size = compiler->size;
391          return (void*)code;          return (void*)code;
392  }  }
393    
# Line 473  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    
 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 567  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 927  static int emit_clz(struct sljit_compile Line 1038  static int emit_clz(struct sljit_compile
1038          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
1039  }  }
1040    
1041  int sljit_emit_op1(struct sljit_compiler *compiler, int op,  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
1042          int dst, sljit_w dstw,          int dst, sljit_w dstw,
1043          int src, sljit_w srcw)          int src, sljit_w srcw)
1044  {  {
# Line 955  int sljit_emit_op1(struct sljit_compiler Line 1066  int sljit_emit_op1(struct sljit_compiler
1066                  compiler->mode32 = 0;                  compiler->mode32 = 0;
1067  #endif  #endif
1068    
1069                  SLJIT_ASSERT(SLJIT_MOV + 7 == SLJIT_MOVU);                  SLJIT_COMPILE_ASSERT(SLJIT_MOV + 7 == SLJIT_MOVU, movu_offset);
1070                  if (op >= SLJIT_MOVU) {                  if (op >= SLJIT_MOVU) {
1071                          update = 1;                          update = 1;
1072                          op -= 7;                          op -= 7;
# Line 1360  static int emit_mul(struct sljit_compile Line 1471  static int emit_mul(struct sljit_compile
1471                          code = (sljit_ub*)ensure_buf(compiler, 1 + 4);                          code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
1472                          FAIL_IF(!code);                          FAIL_IF(!code);
1473                          INC_CSIZE(4);                          INC_CSIZE(4);
1474                          *(sljit_hw*)code = src1w;                          *(sljit_hw*)code = (sljit_hw)src1w;
1475                  }                  }
1476                  else {                  else {
1477                          EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);                          EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);
# Line 1403  static int emit_mul(struct sljit_compile Line 1514  static int emit_mul(struct sljit_compile
1514                          code = (sljit_ub*)ensure_buf(compiler, 1 + 4);                          code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
1515                          FAIL_IF(!code);                          FAIL_IF(!code);
1516                          INC_CSIZE(4);                          INC_CSIZE(4);
1517                          *(sljit_hw*)code = src2w;                          *(sljit_hw*)code = (sljit_hw)src2w;
1518                  }                  }
1519                  else {                  else {
1520                          EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);                          EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);
# Line 1418  static int emit_mul(struct sljit_compile Line 1529  static int emit_mul(struct sljit_compile
1529          }          }
1530          else {          else {
1531                  /* Neither argument is immediate. */                  /* Neither argument is immediate. */
1532                  if (depends_on(src2, dst_r))                  if (ADDRESSING_DEPENDS_ON(src2, dst_r))
1533                          dst_r = TMP_REGISTER;                          dst_r = TMP_REGISTER;
1534                  EMIT_MOV(compiler, dst_r, 0, src1, src1w);                  EMIT_MOV(compiler, dst_r, 0, src1, src1w);
1535                  code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);                  code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);
# Line 1706  static int emit_shift(struct sljit_compi Line 1817  static int emit_shift(struct sljit_compi
1817                  *code |= mode;                  *code |= mode;
1818                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
1819          }          }
1820          else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS && dst != src2 && !depends_on(src2, dst)) {          else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) {
1821                  if (src1 != dst)                  if (src1 != dst)
1822                          EMIT_MOV(compiler, dst, 0, src1, src1w);                          EMIT_MOV(compiler, dst, 0, src1, src1w);
1823                  EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_PREF_SHIFT_REG, 0);                  EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_PREF_SHIFT_REG, 0);
# Line 1717  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 1744  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  int sljit_emit_op2(struct sljit_compiler *compiler, int op,  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,
1892          int dst, sljit_w dstw,          int dst, sljit_w dstw,
1893          int src1, sljit_w src1w,          int src1, sljit_w src1w,
1894          int src2, sljit_w src2w)          int src2, sljit_w src2w)
# Line 1823  int sljit_emit_op2(struct sljit_compiler Line 1967  int sljit_emit_op2(struct sljit_compiler
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    
1980          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
1981  }  }
1982    
1983    SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)
1984    {
1985            check_sljit_get_register_index(reg);
1986    #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
1987            if (reg == SLJIT_TEMPORARY_EREG1 || reg == SLJIT_TEMPORARY_EREG2
1988                            || reg == SLJIT_SAVED_EREG1 || reg == SLJIT_SAVED_EREG2)
1989                    return -1;
1990    #endif
1991            return reg_map[reg];
1992    }
1993    
1994    SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
1995            void *instruction, int size)
1996    {
1997            sljit_ub *buf;
1998    
1999            CHECK_ERROR();
2000            check_sljit_emit_op_custom(compiler, instruction, size);
2001            SLJIT_ASSERT(size > 0 && size < 16);
2002    
2003            buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
2004            FAIL_IF(!buf);
2005            INC_SIZE(size);
2006            SLJIT_MEMMOVE(buf, instruction, size);
2007            return SLJIT_SUCCESS;
2008    }
2009    
2010  /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
2011  /*  Floating point operators                                             */  /*  Floating point operators                                             */
2012  /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
# Line 1893  static void init_compiler() Line 2064  static void init_compiler()
2064    
2065  #endif  #endif
2066    
2067  int sljit_is_fpu_available(void)  SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
2068  {  {
2069          /* Always available. */          /* Always available. */
2070          return 1;          return 1;
# Line 1938  static SLJIT_INLINE int emit_sse2_store( Line 2109  static SLJIT_INLINE int emit_sse2_store(
2109  }  }
2110    
2111  #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2112  int sljit_emit_fop1(struct sljit_compiler *compiler, int op,  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
2113  #else  #else
2114  static int sljit_emit_sse2_fop1(struct sljit_compiler *compiler, int op,  static int sljit_emit_sse2_fop1(struct sljit_compiler *compiler, int op,
2115  #endif  #endif
# Line 2000  static int sljit_emit_sse2_fop1(struct s Line 2171  static int sljit_emit_sse2_fop1(struct s
2171  }  }
2172    
2173  #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2174  int sljit_emit_fop2(struct sljit_compiler *compiler, int op,  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
2175  #else  #else
2176  static int sljit_emit_sse2_fop2(struct sljit_compiler *compiler, int op,  static int sljit_emit_sse2_fop2(struct sljit_compiler *compiler, int op,
2177  #endif  #endif
# Line 2123  static int emit_fop_regs(struct sljit_co Line 2294  static int emit_fop_regs(struct sljit_co
2294  }  }
2295    
2296  #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2297  int sljit_emit_fop1(struct sljit_compiler *compiler, int op,  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
2298  #else  #else
2299  static int sljit_emit_fpu_fop1(struct sljit_compiler *compiler, int op,  static int sljit_emit_fpu_fop1(struct sljit_compiler *compiler, int op,
2300  #endif  #endif
# Line 2188  static int sljit_emit_fpu_fop1(struct sl Line 2359  static int sljit_emit_fpu_fop1(struct sl
2359  }  }
2360    
2361  #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2362  int sljit_emit_fop2(struct sljit_compiler *compiler, int op,  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
2363  #else  #else
2364  static int sljit_emit_fpu_fop2(struct sljit_compiler *compiler, int op,  static int sljit_emit_fpu_fop2(struct sljit_compiler *compiler, int op,
2365  #endif  #endif
# Line 2266  static int sljit_emit_fpu_fop2(struct sl Line 2437  static int sljit_emit_fpu_fop2(struct sl
2437    
2438  #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
2439    
2440  int sljit_emit_fop1(struct sljit_compiler *compiler, int op,  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
2441          int dst, sljit_w dstw,          int dst, sljit_w dstw,
2442          int src, sljit_w srcw)          int src, sljit_w srcw)
2443  {  {
# Line 2276  int sljit_emit_fop1(struct sljit_compile Line 2447  int sljit_emit_fop1(struct sljit_compile
2447                  return sljit_emit_fpu_fop1(compiler, op, dst, dstw, src, srcw);                  return sljit_emit_fpu_fop1(compiler, op, dst, dstw, src, srcw);
2448  }  }
2449    
2450  int sljit_emit_fop2(struct sljit_compiler *compiler, int op,  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
2451          int dst, sljit_w dstw,          int dst, sljit_w dstw,
2452          int src1, sljit_w src1w,          int src1, sljit_w src1w,
2453          int src2, sljit_w src2w)          int src2, sljit_w src2w)
# Line 2293  int sljit_emit_fop2(struct sljit_compile Line 2464  int sljit_emit_fop2(struct sljit_compile
2464  /*  Conditional instructions                                             */  /*  Conditional instructions                                             */
2465  /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
2466    
2467  struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)  SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
2468  {  {
2469          sljit_ub *buf;          sljit_ub *buf;
2470          struct sljit_label *label;          struct sljit_label *label;
# Line 2322  struct sljit_label* sljit_emit_label(str Line 2493  struct sljit_label* sljit_emit_label(str
2493          return label;          return label;
2494  }  }
2495    
2496  struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)  SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
2497  {  {
2498          sljit_ub *buf;          sljit_ub *buf;
2499          struct sljit_jump *jump;          struct sljit_jump *jump;
# Line 2359  struct sljit_jump* sljit_emit_jump(struc Line 2530  struct sljit_jump* sljit_emit_jump(struc
2530          return jump;          return jump;
2531  }  }
2532    
2533  int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
2534  {  {
2535          sljit_ub *code;          sljit_ub *code;
2536          struct sljit_jump *jump;          struct sljit_jump *jump;
# Line 2436  int sljit_emit_ijump(struct sljit_compil Line 2607  int sljit_emit_ijump(struct sljit_compil
2607                  code = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);                  code = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
2608                  FAIL_IF(!code);                  FAIL_IF(!code);
2609                  *code++ = 0xff;                  *code++ = 0xff;
2610                  *code |= (type >= SLJIT_CALL0) ? (2 << 3) : (4 << 3);                  *code |= (type >= SLJIT_FAST_CALL) ? (2 << 3) : (4 << 3);
2611          }          }
2612          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
2613  }  }
2614    
2615  int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
2616  {  {
2617          sljit_ub *buf;          sljit_ub *buf;
2618          sljit_ub cond_set = 0;          sljit_ub cond_set = 0;
# Line 2581  int sljit_emit_cond_value(struct sljit_c Line 2752  int sljit_emit_cond_value(struct sljit_c
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;
# Line 2629  int sljit_emit_cond_value(struct sljit_c Line 2800  int sljit_emit_cond_value(struct sljit_c
2800          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
2801  }  }
2802    
2803  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)
2804  {  {
2805          sljit_ub *buf;          sljit_ub *buf;
2806          struct sljit_const *const_;          struct sljit_const *const_;
# Line 2675  struct sljit_const* sljit_emit_const(str Line 2846  struct sljit_const* sljit_emit_const(str
2846          return const_;          return const_;
2847  }  }
2848    
2849  void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
2850  {  {
2851  #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)  #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
2852          *(sljit_w*)addr = new_addr - (addr + 4);          *(sljit_w*)addr = new_addr - (addr + 4);
# Line 2684  void sljit_set_jump_addr(sljit_uw addr, Line 2855  void sljit_set_jump_addr(sljit_uw addr,
2855  #endif  #endif
2856  }  }
2857    
2858  void sljit_set_const(sljit_uw addr, sljit_w new_constant)  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
2859  {  {
2860          *(sljit_w*)addr = new_constant;          *(sljit_w*)addr = new_constant;
2861  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.5