Diff for /embedaddon/pcre/sljit/sljitNativeX86_32.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 32-bit arch dependent functions. */  /* x86 32-bit arch dependent functions. */
   
static int emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_w imm)static sljit_si emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_sw imm)
 {  {
        sljit_ub *buf;        sljit_ub *inst;
   
        buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_w));        inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_sw));
        FAIL_IF(!buf);        FAIL_IF(!inst);
        INC_SIZE(1 + sizeof(sljit_w));        INC_SIZE(1 + sizeof(sljit_sw));
        *buf++ = opcode;        *inst++ = opcode;
        *(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) {
                *code_ptr++ = 0xe9;                *code_ptr++ = JMP_i32;
                 jump->addr++;                  jump->addr++;
         }          }
         else if (type >= SLJIT_FAST_CALL) {          else if (type >= SLJIT_FAST_CALL) {
                *code_ptr++ = 0xe8;                *code_ptr++ = CALL_i32;
                 jump->addr++;                  jump->addr++;
         }          }
         else {          else {
                *code_ptr++ = 0x0f;                *code_ptr++ = GROUP_0F;
                 *code_ptr++ = get_jump_code(type);                  *code_ptr++ = get_jump_code(type);
                 jump->addr += 2;                  jump->addr += 2;
         }          }
Line 57  static sljit_ub* generate_far_jump_code(struct sljit_j Line 57  static sljit_ub* generate_far_jump_code(struct sljit_j
         if (jump->flags & JUMP_LABEL)          if (jump->flags & JUMP_LABEL)
                 jump->flags |= PATCH_MW;                  jump->flags |= PATCH_MW;
         else          else
                *(sljit_w*)code_ptr = jump->u.target - (jump->addr + 4);                *(sljit_sw*)code_ptr = jump->u.target - (jump->addr + 4);
         code_ptr += 4;          code_ptr += 4;
   
         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;        sljit_si size;
        int locals_offset;        sljit_si locals_offset;
        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->args = args;          compiler->args = args;
         compiler->flags_saved = 0;          compiler->flags_saved = 0;
Line 85  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s Line 85  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s
 #else  #else
         size = 1 + (saveds <= 3 ? saveds : 3) + (args > 0 ? (2 + args * 3) : 0);          size = 1 + (saveds <= 3 ? saveds : 3) + (args > 0 ? (2 + args * 3) : 0);
 #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);
         PUSH_REG(reg_map[TMP_REGISTER]);          PUSH_REG(reg_map[TMP_REGISTER]);
 #if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)  #if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
         if (args > 0) {          if (args > 0) {
                *buf++ = 0x8b;                *inst++ = MOV_r_rm;
                *buf++ = 0xc4 | (reg_map[TMP_REGISTER] << 3);                *inst++ = MOD_REG | (reg_map[TMP_REGISTER] << 3) | 0x4 /* esp */;
         }          }
 #endif  #endif
         if (saveds > 2)          if (saveds > 2)
Line 105  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s Line 105  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s
   
 #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)  #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
         if (args > 0) {          if (args > 0) {
                *buf++ = 0x8b;                *inst++ = MOV_r_rm;
                *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[SLJIT_TEMPORARY_REG3];                *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[SLJIT_SCRATCH_REG3];
         }          }
         if (args > 1) {          if (args > 1) {
                *buf++ = 0x8b;                *inst++ = MOV_r_rm;
                *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[SLJIT_TEMPORARY_REG2];                *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[SLJIT_SCRATCH_REG2];
         }          }
         if (args > 2) {          if (args > 2) {
                *buf++ = 0x8b;                *inst++ = MOV_r_rm;
                *buf++ = 0x44 | (reg_map[SLJIT_SAVED_REG3] << 3);                *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x4 /* esp */;
                *buf++ = 0x24;                *inst++ = 0x24;
                *buf++ = sizeof(sljit_w) * (3 + 2); /* saveds >= 3 as well. */                *inst++ = sizeof(sljit_sw) * (3 + 2); /* saveds >= 3 as well. */
         }          }
 #else  #else
         if (args > 0) {          if (args > 0) {
                *buf++ = 0x8b;                *inst++ = MOV_r_rm;
                *buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[TMP_REGISTER];                *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[TMP_REGISTER];
                *buf++ = sizeof(sljit_w) * 2;                *inst++ = sizeof(sljit_sw) * 2;
         }          }
         if (args > 1) {          if (args > 1) {
                *buf++ = 0x8b;                *inst++ = MOV_r_rm;
                *buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[TMP_REGISTER];                *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[TMP_REGISTER];
                *buf++ = sizeof(sljit_w) * 3;                *inst++ = sizeof(sljit_sw) * 3;
         }          }
         if (args > 2) {          if (args > 2) {
                *buf++ = 0x8b;                *inst++ = MOV_r_rm;
                *buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG3] << 3) | reg_map[TMP_REGISTER];                *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG3] << 3) | reg_map[TMP_REGISTER];
                *buf++ = sizeof(sljit_w) * 4;                *inst++ = sizeof(sljit_sw) * 4;
         }          }
 #endif  #endif
   
   #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
         locals_offset = 2 * sizeof(sljit_uw);          locals_offset = 2 * sizeof(sljit_uw);
        compiler->temporaries_start = locals_offset;#else
        if (temporaries > 3)        SLJIT_COMPILE_ASSERT(FIXED_LOCALS_OFFSET >= 2 * sizeof(sljit_uw), require_at_least_two_words);
                locals_offset += (temporaries - 3) * sizeof(sljit_uw);        locals_offset = FIXED_LOCALS_OFFSET;
 #endif
         compiler->scratches_start = locals_offset;
         if (scratches > 3)
                 locals_offset += (scratches - 3) * sizeof(sljit_uw);
         compiler->saveds_start = locals_offset;          compiler->saveds_start = locals_offset;
         if (saveds > 3)          if (saveds > 3)
                 locals_offset += (saveds - 3) * sizeof(sljit_uw);                  locals_offset += (saveds - 3) * sizeof(sljit_uw);
         compiler->locals_offset = locals_offset;          compiler->locals_offset = locals_offset;
   #if defined(__APPLE__)
           saveds = (2 + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
           local_size = ((locals_offset + saveds + local_size + 15) & ~15) - saveds;
   #else
         local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1));          local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1));
   #endif
   
           compiler->local_size = local_size;
 #ifdef _WIN32  #ifdef _WIN32
         if (local_size > 1024) {          if (local_size > 1024) {
                FAIL_IF(emit_do_imm(compiler, 0xb8 + reg_map[SLJIT_TEMPORARY_REG1], local_size));#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
                 FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_SCRATCH_REG1], local_size));
 #else
                 local_size -= FIXED_LOCALS_OFFSET;
                 FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_SCRATCH_REG1], local_size));
                 FAIL_IF(emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
                         SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, FIXED_LOCALS_OFFSET));
 #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
   
         compiler->local_size = local_size;  
         SLJIT_ASSERT(local_size > 0);          SLJIT_ASSERT(local_size > 0);
        return emit_non_cum_binary(compiler, 0x2b, 0x29, 0x5 << 3, 0x2d,        return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
                 SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size);                  SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size);
   
         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 locals_offset;        sljit_si locals_offset;
   
         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;
         compiler->args = args;          compiler->args = args;
 #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
   
   #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
         locals_offset = 2 * sizeof(sljit_uw);          locals_offset = 2 * sizeof(sljit_uw);
        compiler->temporaries_start = locals_offset;#else
        if (temporaries > 3)        locals_offset = FIXED_LOCALS_OFFSET;
                locals_offset += (temporaries - 3) * sizeof(sljit_uw);#endif
         compiler->scratches_start = locals_offset;
         if (scratches > 3)
                 locals_offset += (scratches - 3) * sizeof(sljit_uw);
         compiler->saveds_start = locals_offset;          compiler->saveds_start = locals_offset;
         if (saveds > 3)          if (saveds > 3)
                 locals_offset += (saveds - 3) * sizeof(sljit_uw);                  locals_offset += (saveds - 3) * sizeof(sljit_uw);
         compiler->locals_offset = locals_offset;          compiler->locals_offset = locals_offset;
   #if defined(__APPLE__)
           saveds = (2 + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
           compiler->local_size = ((locals_offset + saveds + local_size + 15) & ~15) - saveds;
   #else
         compiler->local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1));          compiler->local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1));
   #endif
 }  }
   
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);
         SLJIT_ASSERT(compiler->args >= 0);          SLJIT_ASSERT(compiler->args >= 0);
         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));
   
         SLJIT_ASSERT(compiler->local_size > 0);          SLJIT_ASSERT(compiler->local_size > 0);
        FAIL_IF(emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05,        FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
                 SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size));                  SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size));
   
         size = 2 + (compiler->saveds <= 3 ? compiler->saveds : 3);          size = 2 + (compiler->saveds <= 3 ? compiler->saveds : 3);
Line 211  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct  Line 234  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct 
         if (compiler->args > 0)          if (compiler->args > 0)
                 size += 2;                  size += 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);
   
Line 225  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct  Line 248  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct 
         POP_REG(reg_map[TMP_REGISTER]);          POP_REG(reg_map[TMP_REGISTER]);
 #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)  #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
         if (compiler->args > 2)          if (compiler->args > 2)
                RETN(sizeof(sljit_w));                RET_I16(sizeof(sljit_sw));
         else          else
                 RET();                  RET();
 #else  #else
        if (compiler->args > 0)        RET();
                RETN(compiler->args * sizeof(sljit_w)); 
        else 
                RET(); 
 #endif  #endif
   
         return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
Line 243  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct  Line 263  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct 
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
   
 /* Size contains the flags as well. */  /* Size contains the flags as well. */
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;
        int flags = size & ~0xf;        sljit_si flags = size & ~0xf;
        int inst_size;        sljit_si inst_size;
   
         /* Both cannot be switched on. */          /* Both cannot be switched on. */
         SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));          SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
Line 263  static sljit_ub* emit_x86_instruction(struct sljit_com Line 283  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;
         inst_size = size;          inst_size = size;
   
 #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 279  static sljit_ub* emit_x86_instruction(struct sljit_com Line 302  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 += sizeof(sljit_w);                        inst_size += sizeof(sljit_sw);
                 else if (immb != 0 && !(b & 0xf0)) {                  else 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_w);                                inst_size += sizeof(sljit_sw);
                 }                  }
   
                 if ((b & 0xf) == SLJIT_LOCALS_REG && !(b & 0xf0))                  if ((b & 0xf) == SLJIT_LOCALS_REG && !(b & 0xf0))
Line 315  static sljit_ub* emit_x86_instruction(struct sljit_com Line 338  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_w);                        inst_size += sizeof(sljit_sw);
         }          }
         else          else
                 SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);                  SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
   
        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;
   
        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 354  static sljit_ub* emit_x86_instruction(struct sljit_com Line 379  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_map[b] : b);                *buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2)) ? reg_map[b] : b);
 #else  #else
                *buf_ptr++ |= 0xc0 + reg_map[b];                *buf_ptr++ |= MOD_REG + reg_map[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 388  static sljit_ub* emit_x86_instruction(struct sljit_com Line 413  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_w*)buf_ptr = immb; /* 32 bit displacement. */                                        *(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */
                                        buf_ptr += sizeof(sljit_w);                                        buf_ptr += sizeof(sljit_sw);
                                 }                                  }
                         }                          }
                 }                  }
Line 400  static sljit_ub* emit_x86_instruction(struct sljit_com Line 425  static sljit_ub* emit_x86_instruction(struct sljit_com
         }          }
         else {          else {
                 *buf_ptr++ |= 0x05;                  *buf_ptr++ |= 0x05;
                *(sljit_w*)buf_ptr = immb; /* 32 bit displacement. */                *(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */
                buf_ptr += sizeof(sljit_w);                buf_ptr += sizeof(sljit_sw);
         }          }
   
         if (a & SLJIT_IMM) {          if (a & SLJIT_IMM) {
Line 410  static sljit_ub* emit_x86_instruction(struct sljit_com Line 435  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_w*)buf_ptr = imma;                        *(sljit_sw*)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;
   
 #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)  #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
        buf = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2);        inst = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2);
        FAIL_IF(!buf);        FAIL_IF(!inst);
         INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2);          INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2);
   
         if (type >= SLJIT_CALL3)          if (type >= SLJIT_CALL3)
                PUSH_REG(reg_map[SLJIT_TEMPORARY_REG3]);                PUSH_REG(reg_map[SLJIT_SCRATCH_REG3]);
        *buf++ = 0x8b;        *inst++ = MOV_r_rm;
        *buf++ = 0xc0 | (reg_map[SLJIT_TEMPORARY_REG3] << 3) | reg_map[SLJIT_TEMPORARY_REG1];        *inst++ = MOD_REG | (reg_map[SLJIT_SCRATCH_REG3] << 3) | reg_map[SLJIT_SCRATCH_REG1];
 #else  #else
        buf = (sljit_ub*)ensure_buf(compiler, type - SLJIT_CALL0 + 1);        inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0));
        FAIL_IF(!buf);        FAIL_IF(!inst);
        INC_SIZE(type - SLJIT_CALL0);        INC_SIZE(4 * (type - SLJIT_CALL0));
        if (type >= SLJIT_CALL3)
                PUSH_REG(reg_map[SLJIT_TEMPORARY_REG3]);        *inst++ = MOV_rm_r;
        if (type >= SLJIT_CALL2)        *inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG1] << 3) | 0x4 /* SIB */;
                PUSH_REG(reg_map[SLJIT_TEMPORARY_REG2]);        *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG];
        PUSH_REG(reg_map[SLJIT_TEMPORARY_REG1]);        *inst++ = 0;
         if (type >= SLJIT_CALL2) {
                 *inst++ = MOV_rm_r;
                 *inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG2] << 3) | 0x4 /* SIB */;
                 *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG];
                 *inst++ = sizeof(sljit_sw);
         }
         if (type >= SLJIT_CALL3) {
                 *inst++ = MOV_rm_r;
                 *inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG3] << 3) | 0x4 /* SIB */;
                 *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG];
                 *inst++ = 2 * sizeof(sljit_sw);
         }
 #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 456  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(str Line 493  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(str
   
         CHECK_EXTRA_REGS(dst, dstw, (void)0);          CHECK_EXTRA_REGS(dst, dstw, (void)0);
   
        if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {        /* For UNUSED dst. Uncommon, but possible. */
                buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);        if (dst == SLJIT_UNUSED)
                FAIL_IF(!buf);                dst = TMP_REGISTER;
   
           if (dst <= TMP_REGISTER) {
                   /* Unused dest is possible here. */
                   inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
                   FAIL_IF(!inst);
   
                 INC_SIZE(1);                  INC_SIZE(1);
                 POP_REG(reg_map[dst]);                  POP_REG(reg_map[dst]);
                 return SLJIT_SUCCESS;                  return SLJIT_SUCCESS;
         }          }
         else if (dst & SLJIT_MEM) {  
                 buf = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);  
                 FAIL_IF(!buf);  
                 *buf++ = 0x8f;  
                 return SLJIT_SUCCESS;  
         }  
   
        /* For UNUSED dst. Uncommon, but possible. */        /* Memory. */
        buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);        inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
        FAIL_IF(!buf);        FAIL_IF(!inst);
        *inst++ = POP_rm;
        INC_SIZE(1); 
        POP_REG(reg_map[TMP_REGISTER]); 
         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 490  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st Line 524  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st
   
         CHECK_EXTRA_REGS(src, srcw, (void)0);          CHECK_EXTRA_REGS(src, srcw, (void)0);
   
        if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) {        if (src <= TMP_REGISTER) {
                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_map[src]);                  PUSH_REG(reg_map[src]);
         }          }
         else if (src & SLJIT_MEM) {          else if (src & SLJIT_MEM) {
                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_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_w*)buf = srcw;                *(sljit_sw*)inst = srcw;
                buf += sizeof(sljit_w);                inst += sizeof(sljit_sw);
         }          }
   
         RET();          RET();

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


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