Diff for /embedaddon/pcre/sljit/sljitNativeX86_64.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2012/10/09 09:19:18 version 1.1.1.4, 2013/07/22 08:25:57
Line 26 Line 26
   
 /* x86 64-bit arch dependent functions. */  /* x86 64-bit arch dependent functions. */
   
static int emit_load_imm64(struct sljit_compiler *compiler, int reg, sljit_w imm)static sljit_si emit_load_imm64(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm)
 {  {
        sljit_ub *buf;        sljit_ub *inst;
   
        buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_w));        inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw));
        FAIL_IF(!buf);        FAIL_IF(!inst);
        INC_SIZE(2 + sizeof(sljit_w));        INC_SIZE(2 + sizeof(sljit_sw));
        *buf++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B);        *inst++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B);
        *buf++ = 0xb8 + (reg_map[reg] & 0x7);        *inst++ = MOV_r_i32 + (reg_map[reg] & 0x7);
        *(sljit_w*)buf = imm;        *(sljit_sw*)inst = imm;
         return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
 }  }
   
static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type)static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type)
 {  {
         if (type < SLJIT_JUMP) {          if (type < SLJIT_JUMP) {
                   /* Invert type. */
                 *code_ptr++ = get_jump_code(type ^ 0x1) - 0x10;                  *code_ptr++ = get_jump_code(type ^ 0x1) - 0x10;
                 *code_ptr++ = 10 + 3;                  *code_ptr++ = 10 + 3;
         }          }
   
         SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_first);          SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_first);
         *code_ptr++ = REX_W | REX_B;          *code_ptr++ = REX_W | REX_B;
        *code_ptr++ = 0xb8 + 1;        *code_ptr++ = MOV_r_i32 + 1;
         jump->addr = (sljit_uw)code_ptr;          jump->addr = (sljit_uw)code_ptr;
   
         if (jump->flags & JUMP_LABEL)          if (jump->flags & JUMP_LABEL)
                 jump->flags |= PATCH_MD;                  jump->flags |= PATCH_MD;
         else          else
                *(sljit_w*)code_ptr = jump->u.target;                *(sljit_sw*)code_ptr = jump->u.target;
   
        code_ptr += sizeof(sljit_w);        code_ptr += sizeof(sljit_sw);
         *code_ptr++ = REX_B;          *code_ptr++ = REX_B;
        *code_ptr++ = 0xff;        *code_ptr++ = GROUP_FF;
        *code_ptr++ = (type >= SLJIT_FAST_CALL) ? 0xd1 /* call */ : 0xe1 /* jmp */;        *code_ptr++ = (type >= SLJIT_FAST_CALL) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1);
   
         return code_ptr;          return code_ptr;
 }  }
   
static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_w addr, int type)static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si type)
 {  {
        sljit_w delta = addr - ((sljit_w)code_ptr + 1 + sizeof(sljit_hw));        sljit_sw delta = addr - ((sljit_sw)code_ptr + 1 + sizeof(sljit_si));
   
         if (delta <= SLJIT_W(0x7fffffff) && delta >= SLJIT_W(-0x80000000)) {          if (delta <= SLJIT_W(0x7fffffff) && delta >= SLJIT_W(-0x80000000)) {
                *code_ptr++ = (type == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */;                *code_ptr++ = (type == 2) ? CALL_i32 : JMP_i32;
                *(sljit_w*)code_ptr = delta;                *(sljit_sw*)code_ptr = delta;
         }          }
         else {          else {
                 SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second);                  SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second);
                 *code_ptr++ = REX_W | REX_B;                  *code_ptr++ = REX_W | REX_B;
                *code_ptr++ = 0xb8 + 1;                *code_ptr++ = MOV_r_i32 + 1;
                *(sljit_w*)code_ptr = addr;                *(sljit_sw*)code_ptr = addr;
                code_ptr += sizeof(sljit_w);                code_ptr += sizeof(sljit_sw);
                 *code_ptr++ = REX_B;                  *code_ptr++ = REX_B;
                *code_ptr++ = 0xff;                *code_ptr++ = GROUP_FF;
                *code_ptr++ = (type == 2) ? 0xd1 /* call */ : 0xe1 /* jmp */;                *code_ptr++ = (type == 2) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1);
         }          }
   
         return code_ptr;          return code_ptr;
 }  }
   
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
 {  {
        int size, pushed_size;        sljit_si size, pushed_size;
        sljit_ub *buf;        sljit_ub *inst;
   
         CHECK_ERROR();          CHECK_ERROR();
        check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);        check_sljit_emit_enter(compiler, args, scratches, saveds, local_size);
   
        compiler->temporaries = temporaries;        compiler->scratches = scratches;
         compiler->saveds = saveds;          compiler->saveds = saveds;
         compiler->flags_saved = 0;          compiler->flags_saved = 0;
 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)  #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
Line 103  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s Line 104  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s
   
         size = saveds;          size = saveds;
         /* Including the return address saved by the call instruction. */          /* Including the return address saved by the call instruction. */
        pushed_size = (saveds + 1) * sizeof(sljit_w);        pushed_size = (saveds + 1) * sizeof(sljit_sw);
 #ifndef _WIN64  #ifndef _WIN64
         if (saveds >= 2)          if (saveds >= 2)
                 size += saveds - 1;                  size += saveds - 1;
 #else  #else
         if (saveds >= 4)          if (saveds >= 4)
                 size += saveds - 3;                  size += saveds - 3;
        if (temporaries >= 5) {        if (scratches >= 5) {
                 size += (5 - 4) * 2;                  size += (5 - 4) * 2;
                pushed_size += sizeof(sljit_w);                pushed_size += sizeof(sljit_sw);
         }          }
 #endif  #endif
         size += args * 3;          size += args * 3;
         if (size > 0) {          if (size > 0) {
                buf = (sljit_ub*)ensure_buf(compiler, 1 + size);                inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
                FAIL_IF(!buf);                FAIL_IF(!inst);
   
                 INC_SIZE(size);                  INC_SIZE(size);
                 if (saveds >= 5) {                  if (saveds >= 5) {
                         SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG2] >= 8, saved_ereg2_is_hireg);                          SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG2] >= 8, saved_ereg2_is_hireg);
                        *buf++ = REX_B;                        *inst++ = REX_B;
                         PUSH_REG(reg_lmap[SLJIT_SAVED_EREG2]);                          PUSH_REG(reg_lmap[SLJIT_SAVED_EREG2]);
                 }                  }
                 if (saveds >= 4) {                  if (saveds >= 4) {
                         SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG1] >= 8, saved_ereg1_is_hireg);                          SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG1] >= 8, saved_ereg1_is_hireg);
                        *buf++ = REX_B;                        *inst++ = REX_B;
                         PUSH_REG(reg_lmap[SLJIT_SAVED_EREG1]);                          PUSH_REG(reg_lmap[SLJIT_SAVED_EREG1]);
                 }                  }
                 if (saveds >= 3) {                  if (saveds >= 3) {
 #ifndef _WIN64  #ifndef _WIN64
                         SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] >= 8, saved_reg3_is_hireg);                          SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] >= 8, saved_reg3_is_hireg);
                        *buf++ = REX_B;                        *inst++ = REX_B;
 #else  #else
                         SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] < 8, saved_reg3_is_loreg);                          SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] < 8, saved_reg3_is_loreg);
 #endif  #endif
Line 143  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s Line 144  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s
                 if (saveds >= 2) {                  if (saveds >= 2) {
 #ifndef _WIN64  #ifndef _WIN64
                         SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] >= 8, saved_reg2_is_hireg);                          SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] >= 8, saved_reg2_is_hireg);
                        *buf++ = REX_B;                        *inst++ = REX_B;
 #else  #else
                         SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] < 8, saved_reg2_is_loreg);                          SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] < 8, saved_reg2_is_loreg);
 #endif  #endif
Line 154  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s Line 155  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s
                         PUSH_REG(reg_lmap[SLJIT_SAVED_REG1]);                          PUSH_REG(reg_lmap[SLJIT_SAVED_REG1]);
                 }                  }
 #ifdef _WIN64  #ifdef _WIN64
                if (temporaries >= 5) {                if (scratches >= 5) {
                         SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_EREG2] >= 8, temporary_ereg2_is_hireg);                          SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_EREG2] >= 8, temporary_ereg2_is_hireg);
                        *buf++ = REX_B;                        *inst++ = REX_B;
                         PUSH_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);                          PUSH_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
                 }                  }
 #endif  #endif
   
 #ifndef _WIN64  #ifndef _WIN64
                 if (args > 0) {                  if (args > 0) {
                        *buf++ = REX_W;                        *inst++ = REX_W;
                        *buf++ = 0x8b;                        *inst++ = MOV_r_rm;
                        *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x7;                        *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x7 /* rdi */;
                 }                  }
                 if (args > 1) {                  if (args > 1) {
                        *buf++ = REX_W | REX_R;                        *inst++ = REX_W | REX_R;
                        *buf++ = 0x8b;                        *inst++ = MOV_r_rm;
                        *buf++ = 0xc0 | (reg_lmap[SLJIT_SAVED_REG2] << 3) | 0x6;                        *inst++ = MOD_REG | (reg_lmap[SLJIT_SAVED_REG2] << 3) | 0x6 /* rsi */;
                 }                  }
                 if (args > 2) {                  if (args > 2) {
                        *buf++ = REX_W | REX_R;                        *inst++ = REX_W | REX_R;
                        *buf++ = 0x8b;                        *inst++ = MOV_r_rm;
                        *buf++ = 0xc0 | (reg_lmap[SLJIT_SAVED_REG3] << 3) | 0x2;                        *inst++ = MOD_REG | (reg_lmap[SLJIT_SAVED_REG3] << 3) | 0x2 /* rdx */;
                 }                  }
 #else  #else
                 if (args > 0) {                  if (args > 0) {
                        *buf++ = REX_W;                        *inst++ = REX_W;
                        *buf++ = 0x8b;                        *inst++ = MOV_r_rm;
                        *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x1;                        *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x1 /* rcx */;
                 }                  }
                 if (args > 1) {                  if (args > 1) {
                        *buf++ = REX_W;                        *inst++ = REX_W;
                        *buf++ = 0x8b;                        *inst++ = MOV_r_rm;
                        *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG2] << 3) | 0x2;                        *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG2] << 3) | 0x2 /* rdx */;
                 }                  }
                 if (args > 2) {                  if (args > 2) {
                        *buf++ = REX_W | REX_B;                        *inst++ = REX_W | REX_B;
                        *buf++ = 0x8b;                        *inst++ = MOV_r_rm;
                        *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x0;                        *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x0 /* r8 */;
                 }                  }
 #endif  #endif
         }          }
Line 201  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s Line 202  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s
 #ifdef _WIN64  #ifdef _WIN64
         if (local_size > 1024) {          if (local_size > 1024) {
                 /* Allocate stack for the callback, which grows the stack. */                  /* Allocate stack for the callback, which grows the stack. */
                buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);                inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + (3 + sizeof(sljit_si)));
                FAIL_IF(!buf);                FAIL_IF(!inst);
                INC_SIZE(4);                INC_SIZE(4 + (3 + sizeof(sljit_si)));
                *buf++ = REX_W;                *inst++ = REX_W;
                *buf++ = 0x83;                *inst++ = GROUP_BINARY_83;
                *buf++ = 0xc0 | (5 << 3) | 4;                *inst++ = MOD_REG | SUB | 4;
                 /* Pushed size must be divisible by 8. */                  /* Pushed size must be divisible by 8. */
                 SLJIT_ASSERT(!(pushed_size & 0x7));                  SLJIT_ASSERT(!(pushed_size & 0x7));
                 if (pushed_size & 0x8) {                  if (pushed_size & 0x8) {
                        *buf++ = 5 * sizeof(sljit_w);                        *inst++ = 5 * sizeof(sljit_sw);
                        local_size -= 5 * sizeof(sljit_w);                        local_size -= 5 * sizeof(sljit_sw);
                 } else {                  } else {
                        *buf++ = 4 * sizeof(sljit_w);                        *inst++ = 4 * sizeof(sljit_sw);
                        local_size -= 4 * sizeof(sljit_w);                        local_size -= 4 * sizeof(sljit_sw);
                 }                  }
                FAIL_IF(emit_load_imm64(compiler, SLJIT_TEMPORARY_REG1, local_size));                /* Second instruction */
                 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG1] < 8, temporary_reg1_is_loreg);
                 *inst++ = REX_W;
                 *inst++ = MOV_rm_i32;
                 *inst++ = MOD_REG | reg_lmap[SLJIT_SCRATCH_REG1];
                 *(sljit_si*)inst = local_size;
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
                 compiler->skip_checks = 1;
 #endif
                 FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));                  FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
         }          }
 #endif  #endif
         SLJIT_ASSERT(local_size > 0);          SLJIT_ASSERT(local_size > 0);
         if (local_size <= 127) {          if (local_size <= 127) {
                buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);                inst = (sljit_ub*)ensure_buf(compiler, 1 + 4);
                FAIL_IF(!buf);                FAIL_IF(!inst);
                 INC_SIZE(4);                  INC_SIZE(4);
                *buf++ = REX_W;                *inst++ = REX_W;
                *buf++ = 0x83;                *inst++ = GROUP_BINARY_83;
                *buf++ = 0xc0 | (5 << 3) | 4;                *inst++ = MOD_REG | SUB | 4;
                *buf++ = local_size;                *inst++ = local_size;
         }          }
         else {          else {
                buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);                inst = (sljit_ub*)ensure_buf(compiler, 1 + 7);
                FAIL_IF(!buf);                FAIL_IF(!inst);
                 INC_SIZE(7);                  INC_SIZE(7);
                *buf++ = REX_W;                *inst++ = REX_W;
                *buf++ = 0x81;                *inst++ = GROUP_BINARY_81;
                *buf++ = 0xc0 | (5 << 3) | 4;                *inst++ = MOD_REG | SUB | 4;
                *(sljit_hw*)buf = local_size;                *(sljit_si*)inst = local_size;
                buf += sizeof(sljit_hw);                inst += sizeof(sljit_si);
         }          }
   #ifdef _WIN64
           /* Save xmm6 with MOVAPS instruction. */
           inst = (sljit_ub*)ensure_buf(compiler, 1 + 5);
           FAIL_IF(!inst);
           INC_SIZE(5);
           *inst++ = GROUP_0F;
           *(sljit_si*)inst = 0x20247429;
   #endif
   
         return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
 }  }
   
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
 {  {
        int pushed_size;        sljit_si pushed_size;
   
         CHECK_ERROR_VOID();          CHECK_ERROR_VOID();
        check_sljit_set_context(compiler, args, temporaries, saveds, local_size);        check_sljit_set_context(compiler, args, scratches, saveds, local_size);
   
        compiler->temporaries = temporaries;        compiler->scratches = scratches;
         compiler->saveds = saveds;          compiler->saveds = saveds;
 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)  #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
         compiler->logical_local_size = local_size;          compiler->logical_local_size = local_size;
 #endif  #endif
   
         /* Including the return address saved by the call instruction. */          /* Including the return address saved by the call instruction. */
        pushed_size = (saveds + 1) * sizeof(sljit_w);        pushed_size = (saveds + 1) * sizeof(sljit_sw);
 #ifdef _WIN64  #ifdef _WIN64
        if (temporaries >= 5)        if (scratches >= 5)
                pushed_size += sizeof(sljit_w);                pushed_size += sizeof(sljit_sw);
 #endif  #endif
         compiler->local_size = ((local_size + FIXED_LOCALS_OFFSET + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;          compiler->local_size = ((local_size + FIXED_LOCALS_OFFSET + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;
 }  }
   
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
 {  {
        int size;        sljit_si size;
        sljit_ub *buf;        sljit_ub *inst;
   
         CHECK_ERROR();          CHECK_ERROR();
         check_sljit_emit_return(compiler, op, src, srcw);          check_sljit_emit_return(compiler, op, src, srcw);
         ADJUST_LOCAL_OFFSET(src, srcw);  
   
         compiler->flags_saved = 0;          compiler->flags_saved = 0;
         FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));          FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
   
   #ifdef _WIN64
           /* Restore xmm6 with MOVAPS instruction. */
           inst = (sljit_ub*)ensure_buf(compiler, 1 + 5);
           FAIL_IF(!inst);
           INC_SIZE(5);
           *inst++ = GROUP_0F;
           *(sljit_si*)inst = 0x20247428;
   #endif
         SLJIT_ASSERT(compiler->local_size > 0);          SLJIT_ASSERT(compiler->local_size > 0);
         if (compiler->local_size <= 127) {          if (compiler->local_size <= 127) {
                buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);                inst = (sljit_ub*)ensure_buf(compiler, 1 + 4);
                FAIL_IF(!buf);                FAIL_IF(!inst);
                 INC_SIZE(4);                  INC_SIZE(4);
                *buf++ = REX_W;                *inst++ = REX_W;
                *buf++ = 0x83;                *inst++ = GROUP_BINARY_83;
                *buf++ = 0xc0 | (0 << 3) | 4;                *inst++ = MOD_REG | ADD | 4;
                *buf = compiler->local_size;                *inst = compiler->local_size;
         }          }
         else {          else {
                buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);                inst = (sljit_ub*)ensure_buf(compiler, 1 + 7);
                FAIL_IF(!buf);                FAIL_IF(!inst);
                 INC_SIZE(7);                  INC_SIZE(7);
                *buf++ = REX_W;                *inst++ = REX_W;
                *buf++ = 0x81;                *inst++ = GROUP_BINARY_81;
                *buf++ = 0xc0 | (0 << 3) | 4;                *inst++ = MOD_REG | ADD | 4;
                *(sljit_hw*)buf = compiler->local_size;                *(sljit_si*)inst = compiler->local_size;
         }          }
   
         size = 1 + compiler->saveds;          size = 1 + compiler->saveds;
Line 305  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct  Line 329  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct 
 #else  #else
         if (compiler->saveds >= 4)          if (compiler->saveds >= 4)
                 size += compiler->saveds - 3;                  size += compiler->saveds - 3;
        if (compiler->temporaries >= 5)        if (compiler->scratches >= 5)
                 size += (5 - 4) * 2;                  size += (5 - 4) * 2;
 #endif  #endif
        buf = (sljit_ub*)ensure_buf(compiler, 1 + size);        inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
        FAIL_IF(!buf);        FAIL_IF(!inst);
   
         INC_SIZE(size);          INC_SIZE(size);
   
 #ifdef _WIN64  #ifdef _WIN64
        if (compiler->temporaries >= 5) {        if (compiler->scratches >= 5) {
                *buf++ = REX_B;                *inst++ = REX_B;
                 POP_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);                  POP_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
         }          }
 #endif  #endif
Line 323  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct  Line 347  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct 
                 POP_REG(reg_map[SLJIT_SAVED_REG1]);                  POP_REG(reg_map[SLJIT_SAVED_REG1]);
         if (compiler->saveds >= 2) {          if (compiler->saveds >= 2) {
 #ifndef _WIN64  #ifndef _WIN64
                *buf++ = REX_B;                *inst++ = REX_B;
 #endif  #endif
                 POP_REG(reg_lmap[SLJIT_SAVED_REG2]);                  POP_REG(reg_lmap[SLJIT_SAVED_REG2]);
         }          }
         if (compiler->saveds >= 3) {          if (compiler->saveds >= 3) {
 #ifndef _WIN64  #ifndef _WIN64
                *buf++ = REX_B;                *inst++ = REX_B;
 #endif  #endif
                 POP_REG(reg_lmap[SLJIT_SAVED_REG3]);                  POP_REG(reg_lmap[SLJIT_SAVED_REG3]);
         }          }
         if (compiler->saveds >= 4) {          if (compiler->saveds >= 4) {
                *buf++ = REX_B;                *inst++ = REX_B;
                 POP_REG(reg_lmap[SLJIT_SAVED_EREG1]);                  POP_REG(reg_lmap[SLJIT_SAVED_EREG1]);
         }          }
         if (compiler->saveds >= 5) {          if (compiler->saveds >= 5) {
                *buf++ = REX_B;                *inst++ = REX_B;
                 POP_REG(reg_lmap[SLJIT_SAVED_EREG2]);                  POP_REG(reg_lmap[SLJIT_SAVED_EREG2]);
         }          }
   
Line 350  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct  Line 374  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct 
 /*  Operators                                                            */  /*  Operators                                                            */
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
   
static int emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_w imm)static sljit_si emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_sw imm)
 {  {
        sljit_ub *buf;        sljit_ub *inst;
         sljit_si length = 1 + (rex ? 1 : 0) + sizeof(sljit_si);
   
        if (rex != 0) {        inst = (sljit_ub*)ensure_buf(compiler, 1 + length);
                buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_hw));        FAIL_IF(!inst);
                FAIL_IF(!buf);        INC_SIZE(length);
                INC_SIZE(2 + sizeof(sljit_hw));        if (rex)
                *buf++ = rex;                *inst++ = rex;
                *buf++ = opcode;        *inst++ = opcode;
                *(sljit_hw*)buf = imm;        *(sljit_si*)inst = imm;
        } 
        else { 
                buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_hw)); 
                FAIL_IF(!buf); 
                INC_SIZE(1 + sizeof(sljit_hw)); 
                *buf++ = opcode; 
                *(sljit_hw*)buf = imm; 
        } 
         return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
 }  }
   
static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size,
         /* The register or immediate operand. */          /* The register or immediate operand. */
        int a, sljit_w imma,        sljit_si a, sljit_sw imma,
         /* The general operand (not immediate). */          /* The general operand (not immediate). */
        int b, sljit_w immb)        sljit_si b, sljit_sw immb)
 {  {
        sljit_ub *buf;        sljit_ub *inst;
         sljit_ub *buf_ptr;          sljit_ub *buf_ptr;
         sljit_ub rex = 0;          sljit_ub rex = 0;
        int flags = size & ~0xf;        sljit_si flags = size & ~0xf;
        int inst_size;        sljit_si inst_size;
   
         /* The immediate operand must be 32 bit. */          /* The immediate operand must be 32 bit. */
         SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma));          SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma));
Line 395  static sljit_ub* emit_x86_instruction(struct sljit_com Line 412  static sljit_ub* emit_x86_instruction(struct sljit_com
 #if (defined SLJIT_SSE2 && SLJIT_SSE2)  #if (defined SLJIT_SSE2 && SLJIT_SSE2)
         /* SSE2 and immediate is not possible. */          /* SSE2 and immediate is not possible. */
         SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));          SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
           SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3)
                   && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66)
                   && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66));
 #endif  #endif
   
         size &= 0xf;          size &= 0xf;
Line 416  static sljit_ub* emit_x86_instruction(struct sljit_com Line 436  static sljit_ub* emit_x86_instruction(struct sljit_com
                 rex |= REX;                  rex |= REX;
   
 #if (defined SLJIT_SSE2 && SLJIT_SSE2)  #if (defined SLJIT_SSE2 && SLJIT_SSE2)
        if (flags & EX86_PREF_F2)        if (flags & (EX86_PREF_F2 | EX86_PREF_F3))
                 inst_size++;                  inst_size++;
 #endif  #endif
         if (flags & EX86_PREF_66)          if (flags & EX86_PREF_66)
Line 426  static sljit_ub* emit_x86_instruction(struct sljit_com Line 446  static sljit_ub* emit_x86_instruction(struct sljit_com
         inst_size += 1; /* mod r/m byte. */          inst_size += 1; /* mod r/m byte. */
         if (b & SLJIT_MEM) {          if (b & SLJIT_MEM) {
                 if ((b & 0x0f) == SLJIT_UNUSED)                  if ((b & 0x0f) == SLJIT_UNUSED)
                        inst_size += 1 + sizeof(sljit_hw); /* SIB byte required to avoid RIP based addressing. */                        inst_size += 1 + sizeof(sljit_si); /* SIB byte required to avoid RIP based addressing. */
                 else {                  else {
                         if (reg_map[b & 0x0f] >= 8)                          if (reg_map[b & 0x0f] >= 8)
                                 rex |= REX_B;                                  rex |= REX_B;
                         if (immb != 0 && !(b & 0xf0)) {                          if (immb != 0 && !(b & 0xf0)) {
                                 /* Immediate operand. */                                  /* Immediate operand. */
                                 if (immb <= 127 && immb >= -128)                                  if (immb <= 127 && immb >= -128)
                                        inst_size += sizeof(sljit_b);                                        inst_size += sizeof(sljit_sb);
                                 else                                  else
                                        inst_size += sizeof(sljit_hw);                                        inst_size += sizeof(sljit_si);
                         }                          }
                 }                  }
   
Line 475  static sljit_ub* emit_x86_instruction(struct sljit_com Line 495  static sljit_ub* emit_x86_instruction(struct sljit_com
                 else if (flags & EX86_HALF_ARG)                  else if (flags & EX86_HALF_ARG)
                         inst_size += sizeof(short);                          inst_size += sizeof(short);
                 else                  else
                        inst_size += sizeof(sljit_hw);                        inst_size += sizeof(sljit_si);
         }          }
         else {          else {
                 SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);                  SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
Line 492  static sljit_ub* emit_x86_instruction(struct sljit_com Line 512  static sljit_ub* emit_x86_instruction(struct sljit_com
         if (rex)          if (rex)
                 inst_size++;                  inst_size++;
   
        buf = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);        inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
        PTR_FAIL_IF(!buf);        PTR_FAIL_IF(!inst);
   
         /* Encoding the byte. */          /* Encoding the byte. */
         INC_SIZE(inst_size);          INC_SIZE(inst_size);
 #if (defined SLJIT_SSE2 && SLJIT_SSE2)  #if (defined SLJIT_SSE2 && SLJIT_SSE2)
         if (flags & EX86_PREF_F2)          if (flags & EX86_PREF_F2)
                *buf++ = 0xf2;                *inst++ = 0xf2;
         if (flags & EX86_PREF_F3)
                 *inst++ = 0xf3;
 #endif  #endif
         if (flags & EX86_PREF_66)          if (flags & EX86_PREF_66)
                *buf++ = 0x66;                *inst++ = 0x66;
         if (rex)          if (rex)
                *buf++ = rex;                *inst++ = rex;
        buf_ptr = buf + size;        buf_ptr = inst + size;
   
         /* Encode mod/rm byte. */          /* Encode mod/rm byte. */
         if (!(flags & EX86_SHIFT_INS)) {          if (!(flags & EX86_SHIFT_INS)) {
                 if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))                  if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
                        *buf = (flags & EX86_BYTE_ARG) ? 0x83 : 0x81;                        *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;
   
                 if ((a & SLJIT_IMM) || (a == 0))                  if ((a & SLJIT_IMM) || (a == 0))
                         *buf_ptr = 0;                          *buf_ptr = 0;
Line 527  static sljit_ub* emit_x86_instruction(struct sljit_com Line 549  static sljit_ub* emit_x86_instruction(struct sljit_com
         else {          else {
                 if (a & SLJIT_IMM) {                  if (a & SLJIT_IMM) {
                         if (imma == 1)                          if (imma == 1)
                                *buf = 0xd1;                                *inst = GROUP_SHIFT_1;
                         else                          else
                                *buf = 0xc1;                                *inst = GROUP_SHIFT_N;
                 } else                  } else
                        *buf = 0xd3;                        *inst = GROUP_SHIFT_CL;
                 *buf_ptr = 0;                  *buf_ptr = 0;
         }          }
   
         if (!(b & SLJIT_MEM))          if (!(b & SLJIT_MEM))
 #if (defined SLJIT_SSE2 && SLJIT_SSE2)  #if (defined SLJIT_SSE2 && SLJIT_SSE2)
                *buf_ptr++ |= 0xc0 + ((!(flags & EX86_SSE2)) ? reg_lmap[b] : b);                *buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2)) ? reg_lmap[b] : b);
 #else  #else
                *buf_ptr++ |= 0xc0 + reg_lmap[b];                *buf_ptr++ |= MOD_REG + reg_lmap[b];
 #endif  #endif
         else if ((b & 0x0f) != SLJIT_UNUSED) {          else if ((b & 0x0f) != SLJIT_UNUSED) {
                 if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) {                  if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) {
Line 561  static sljit_ub* emit_x86_instruction(struct sljit_com Line 583  static sljit_ub* emit_x86_instruction(struct sljit_com
                                 if (immb <= 127 && immb >= -128)                                  if (immb <= 127 && immb >= -128)
                                         *buf_ptr++ = immb; /* 8 bit displacement. */                                          *buf_ptr++ = immb; /* 8 bit displacement. */
                                 else {                                  else {
                                        *(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */                                        *(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */
                                        buf_ptr += sizeof(sljit_hw);                                        buf_ptr += sizeof(sljit_si);
                                 }                                  }
                         }                          }
                 }                  }
Line 574  static sljit_ub* emit_x86_instruction(struct sljit_com Line 596  static sljit_ub* emit_x86_instruction(struct sljit_com
         else {          else {
                 *buf_ptr++ |= 0x04;                  *buf_ptr++ |= 0x04;
                 *buf_ptr++ = 0x25;                  *buf_ptr++ = 0x25;
                *(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */                *(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */
                buf_ptr += sizeof(sljit_hw);                buf_ptr += sizeof(sljit_si);
         }          }
   
         if (a & SLJIT_IMM) {          if (a & SLJIT_IMM) {
Line 584  static sljit_ub* emit_x86_instruction(struct sljit_com Line 606  static sljit_ub* emit_x86_instruction(struct sljit_com
                 else if (flags & EX86_HALF_ARG)                  else if (flags & EX86_HALF_ARG)
                         *(short*)buf_ptr = imma;                          *(short*)buf_ptr = imma;
                 else if (!(flags & EX86_SHIFT_INS))                  else if (!(flags & EX86_SHIFT_INS))
                        *(sljit_hw*)buf_ptr = imma;                        *(sljit_si*)buf_ptr = imma;
         }          }
   
        return !(flags & EX86_SHIFT_INS) ? buf : (buf + 1);        return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1);
 }  }
   
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
 /*  Call / return instructions                                           */  /*  Call / return instructions                                           */
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
   
static SLJIT_INLINE int call_with_args(struct sljit_compiler *compiler, int type)static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type)
 {  {
        sljit_ub *buf;        sljit_ub *inst;
   
 #ifndef _WIN64  #ifndef _WIN64
        SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 6 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers);        SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG2] == 6 && reg_map[SLJIT_SCRATCH_REG1] < 8 && reg_map[SLJIT_SCRATCH_REG3] < 8, args_registers);
   
        buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));        inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
        FAIL_IF(!buf);        FAIL_IF(!inst);
         INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);          INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
         if (type >= SLJIT_CALL3) {          if (type >= SLJIT_CALL3) {
                *buf++ = REX_W;                *inst++ = REX_W;
                *buf++ = 0x8b;                *inst++ = MOV_r_rm;
                *buf++ = 0xc0 | (0x2 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3];                *inst++ = MOD_REG | (0x2 /* rdx */ << 3) | reg_lmap[SLJIT_SCRATCH_REG3];
         }          }
        *buf++ = REX_W;        *inst++ = REX_W;
        *buf++ = 0x8b;        *inst++ = MOV_r_rm;
        *buf++ = 0xc0 | (0x7 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1];        *inst++ = MOD_REG | (0x7 /* rdi */ << 3) | reg_lmap[SLJIT_SCRATCH_REG1];
 #else  #else
        SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 2 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers);        SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG2] == 2 && reg_map[SLJIT_SCRATCH_REG1] < 8 && reg_map[SLJIT_SCRATCH_REG3] < 8, args_registers);
   
        buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));        inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
        FAIL_IF(!buf);        FAIL_IF(!inst);
         INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);          INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
         if (type >= SLJIT_CALL3) {          if (type >= SLJIT_CALL3) {
                *buf++ = REX_W | REX_R;                *inst++ = REX_W | REX_R;
                *buf++ = 0x8b;                *inst++ = MOV_r_rm;
                *buf++ = 0xc0 | (0x0 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3];                *inst++ = MOD_REG | (0x0 /* r8 */ << 3) | reg_lmap[SLJIT_SCRATCH_REG3];
         }          }
        *buf++ = REX_W;        *inst++ = REX_W;
        *buf++ = 0x8b;        *inst++ = MOV_r_rm;
        *buf++ = 0xc0 | (0x1 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1];        *inst++ = MOD_REG | (0x1 /* rcx */ << 3) | reg_lmap[SLJIT_SCRATCH_REG1];
 #endif  #endif
         return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
 }  }
   
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw)SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
 {  {
        sljit_ub *buf;        sljit_ub *inst;
   
         CHECK_ERROR();          CHECK_ERROR();
         check_sljit_emit_fast_enter(compiler, dst, dstw);          check_sljit_emit_fast_enter(compiler, dst, dstw);
Line 642  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(str Line 664  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(str
         if (dst == SLJIT_UNUSED)          if (dst == SLJIT_UNUSED)
                 dst = TMP_REGISTER;                  dst = TMP_REGISTER;
   
        if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {        if (dst <= TMP_REGISTER) {
                 if (reg_map[dst] < 8) {                  if (reg_map[dst] < 8) {
                        buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);                        inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
                        FAIL_IF(!buf);                        FAIL_IF(!inst);
 
                         INC_SIZE(1);                          INC_SIZE(1);
                         POP_REG(reg_lmap[dst]);                          POP_REG(reg_lmap[dst]);
                           return SLJIT_SUCCESS;
                 }                  }
                 else {  
                         buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);  
                         FAIL_IF(!buf);  
   
                        INC_SIZE(2);                inst = (sljit_ub*)ensure_buf(compiler, 1 + 2);
                        *buf++ = REX_B;                FAIL_IF(!inst);
                        POP_REG(reg_lmap[dst]);                INC_SIZE(2);
                }                *inst++ = REX_B;
                 POP_REG(reg_lmap[dst]);
                 return SLJIT_SUCCESS;
         }          }
        else if (dst & SLJIT_MEM) {
                /* REX_W is not necessary (src is not immediate). */        /* REX_W is not necessary (src is not immediate). */
                compiler->mode32 = 1;        compiler->mode32 = 1;
                buf = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);        inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
                FAIL_IF(!buf);        FAIL_IF(!inst);
                *buf++ = 0x8f;        *inst++ = POP_rm;
        } 
         return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
 }  }
   
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
 {  {
        sljit_ub *buf;        sljit_ub *inst;
   
         CHECK_ERROR();          CHECK_ERROR();
         check_sljit_emit_fast_return(compiler, src, srcw);          check_sljit_emit_fast_return(compiler, src, srcw);
Line 682  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st Line 702  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st
                 src = TMP_REGISTER;                  src = TMP_REGISTER;
         }          }
   
        if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) {        if (src <= TMP_REGISTER) {
                 if (reg_map[src] < 8) {                  if (reg_map[src] < 8) {
                        buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);                        inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
                        FAIL_IF(!buf);                        FAIL_IF(!inst);
   
                         INC_SIZE(1 + 1);                          INC_SIZE(1 + 1);
                         PUSH_REG(reg_lmap[src]);                          PUSH_REG(reg_lmap[src]);
                 }                  }
                 else {                  else {
                        buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1);                        inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1);
                        FAIL_IF(!buf);                        FAIL_IF(!inst);
   
                         INC_SIZE(2 + 1);                          INC_SIZE(2 + 1);
                        *buf++ = REX_B;                        *inst++ = REX_B;
                         PUSH_REG(reg_lmap[src]);                          PUSH_REG(reg_lmap[src]);
                 }                  }
         }          }
         else if (src & SLJIT_MEM) {          else if (src & SLJIT_MEM) {
                 /* REX_W is not necessary (src is not immediate). */                  /* REX_W is not necessary (src is not immediate). */
                 compiler->mode32 = 1;                  compiler->mode32 = 1;
                buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);                inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
                FAIL_IF(!buf);                FAIL_IF(!inst);
                *buf++ = 0xff;                *inst++ = GROUP_FF;
                *buf |= 6 << 3;                *inst |= PUSH_rm;
   
                buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);                inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
                FAIL_IF(!buf);                FAIL_IF(!inst);
                 INC_SIZE(1);                  INC_SIZE(1);
         }          }
         else {          else {
                 SLJIT_ASSERT(IS_HALFWORD(srcw));                  SLJIT_ASSERT(IS_HALFWORD(srcw));
                 /* SLJIT_IMM. */                  /* SLJIT_IMM. */
                buf = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);                inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
                FAIL_IF(!buf);                FAIL_IF(!inst);
   
                 INC_SIZE(5 + 1);                  INC_SIZE(5 + 1);
                *buf++ = 0x68;                *inst++ = PUSH_i32;
                *(sljit_hw*)buf = srcw;                *(sljit_si*)inst = srcw;
                buf += sizeof(sljit_hw);                inst += sizeof(sljit_si);
         }          }
   
         RET();          RET();
Line 732  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st Line 752  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st
 /*  Extend input                                                         */  /*  Extend input                                                         */
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
   
static int emit_mov_int(struct sljit_compiler *compiler, int sign,static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign,
        int dst, sljit_w dstw,        sljit_si dst, sljit_sw dstw,
        int src, sljit_w srcw)        sljit_si src, sljit_sw srcw)
 {  {
        sljit_ub* code;        sljit_ub* inst;
        int dst_r;        sljit_si dst_r;
   
         compiler->mode32 = 0;          compiler->mode32 = 0;
   
Line 745  static int emit_mov_int(struct sljit_compiler *compile Line 765  static int emit_mov_int(struct sljit_compiler *compile
                 return SLJIT_SUCCESS; /* Empty instruction. */                  return SLJIT_SUCCESS; /* Empty instruction. */
   
         if (src & SLJIT_IMM) {          if (src & SLJIT_IMM) {
                if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {                if (dst <= TMP_REGISTER) {
                         if (sign || ((sljit_uw)srcw <= 0x7fffffff)) {                          if (sign || ((sljit_uw)srcw <= 0x7fffffff)) {
                                code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_w)(sljit_i)srcw, dst, dstw);                                inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw);
                                FAIL_IF(!code);                                FAIL_IF(!inst);
                                *code = 0xc7;                                *inst = MOV_rm_i32;
                                 return SLJIT_SUCCESS;                                  return SLJIT_SUCCESS;
                         }                          }
                         return emit_load_imm64(compiler, dst, srcw);                          return emit_load_imm64(compiler, dst, srcw);
                 }                  }
                 compiler->mode32 = 1;                  compiler->mode32 = 1;
                code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_w)(sljit_i)srcw, dst, dstw);                inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw);
                FAIL_IF(!code);                FAIL_IF(!inst);
                *code = 0xc7;                *inst = MOV_rm_i32;
                 compiler->mode32 = 0;                  compiler->mode32 = 0;
                 return SLJIT_SUCCESS;                  return SLJIT_SUCCESS;
         }          }
   
        dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_SAVED_REG3) ? dst : TMP_REGISTER;        dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER;
   
        if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_SAVED_REG3))        if ((dst & SLJIT_MEM) && (src <= TMP_REGISTER))
                 dst_r = src;                  dst_r = src;
         else {          else {
                 if (sign) {                  if (sign) {
                        code = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);                        inst = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);
                        FAIL_IF(!code);                        FAIL_IF(!inst);
                        *code++ = 0x63;                        *inst++ = MOVSXD_r_rm;
                 } else {                  } else {
                         compiler->mode32 = 1;                          compiler->mode32 = 1;
                         FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw));                          FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw));
Line 780  static int emit_mov_int(struct sljit_compiler *compile Line 800  static int emit_mov_int(struct sljit_compiler *compile
   
         if (dst & SLJIT_MEM) {          if (dst & SLJIT_MEM) {
                 compiler->mode32 = 1;                  compiler->mode32 = 1;
                code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);                inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
                FAIL_IF(!code);                FAIL_IF(!inst);
                *code = 0x89;                *inst = MOV_rm_r;
                 compiler->mode32 = 0;                  compiler->mode32 = 0;
         }          }
   

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


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