Diff for /embedaddon/pcre/sljit/sljitNativeX86_32.c between versions 1.1 and 1.1.1.4

version 1.1, 2012/02/21 23:05:52 version 1.1.1.4, 2013/07/22 08:25:57
Line 1 Line 1
 /*  /*
  *    Stack-less Just-In-Time compiler   *    Stack-less Just-In-Time compiler
  *   *
 *    Copyright 2009-2010 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *   *
  * 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
  * permitted provided that the following conditions are met:   * permitted provided that the following conditions are met:
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 generals, 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;
        sljit_ub *buf;        sljit_si locals_offset;
         sljit_ub *inst;
   
         CHECK_ERROR();          CHECK_ERROR();
        check_sljit_emit_enter(compiler, args, temporaries, generals, local_size);        check_sljit_emit_enter(compiler, args, scratches, saveds, local_size);
   
        compiler->temporaries = temporaries;        compiler->scratches = scratches;
        compiler->generals = generals;        compiler->saveds = saveds;
         compiler->args = args;          compiler->args = args;
         compiler->flags_saved = 0;          compiler->flags_saved = 0;
   #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
           compiler->logical_local_size = local_size;
   #endif
   
 #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)  #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
        size = 1 + (generals <= 3 ? generals : 3) + (args > 0 ? (args * 2) : 0) + (args > 2 ? 2 : 0);        size = 1 + (saveds <= 3 ? saveds : 3) + (args > 0 ? (args * 2) : 0) + (args > 2 ? 2 : 0);
 #else  #else
        size = 1 + (generals <= 3 ? generals : 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 (generals > 2)        if (saveds > 2)
                PUSH_REG(reg_map[SLJIT_GENERAL_REG3]);                PUSH_REG(reg_map[SLJIT_SAVED_REG3]);
        if (generals > 1)        if (saveds > 1)
                PUSH_REG(reg_map[SLJIT_GENERAL_REG2]);                PUSH_REG(reg_map[SLJIT_SAVED_REG2]);
        if (generals > 0)        if (saveds > 0)
                PUSH_REG(reg_map[SLJIT_GENERAL_REG1]);                PUSH_REG(reg_map[SLJIT_SAVED_REG1]);
   
 #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_GENERAL_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_GENERAL_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_GENERAL_REG3] << 3);                *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x4 /* esp */;
                *buf++ = 0x24;                *inst++ = 0x24;
                *buf++ = sizeof(sljit_w) * (3 + 2); /* generals >= 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_GENERAL_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_GENERAL_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_GENERAL_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
   
        local_size = (local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1);#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
        compiler->temporaries_start = local_size;        locals_offset = 2 * sizeof(sljit_uw);
        if (temporaries > 3)#else
                local_size += (temporaries - 3) * sizeof(sljit_uw);        SLJIT_COMPILE_ASSERT(FIXED_LOCALS_OFFSET >= 2 * sizeof(sljit_uw), require_at_least_two_words);
        compiler->generals_start = local_size;        locals_offset = FIXED_LOCALS_OFFSET;
        if (generals > 3)#endif
                local_size += (generals - 3) * sizeof(sljit_uw);        compiler->scratches_start = locals_offset;
         if (scratches > 3)
                 locals_offset += (scratches - 3) * sizeof(sljit_uw);
         compiler->saveds_start = locals_offset;
         if (saveds > 3)
                 locals_offset += (saveds - 3) * sizeof(sljit_uw);
         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));
 #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(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_touch_stack)));                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)));
         }          }
 #endif  #endif
   
        compiler->local_size = local_size;        SLJIT_ASSERT(local_size > 0);
        if (local_size > 0)        return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
                return emit_non_cum_binary(compiler, 0x2b, 0x29, 0x5 << 3, 0x2d,                SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size);
                        SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size); 
 
        /* Mov arguments to general registers. */ 
        return SLJIT_SUCCESS; 
 }  }
   
SLJIT_API_FUNC_ATTRIBUTE void sljit_fake_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, 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)
 {  {
           sljit_si locals_offset;
   
         CHECK_ERROR_VOID();          CHECK_ERROR_VOID();
        check_sljit_fake_enter(compiler, args, temporaries, generals, local_size);        check_sljit_set_context(compiler, args, scratches, saveds, local_size);
   
        compiler->temporaries = temporaries;        compiler->scratches = scratches;
        compiler->generals = generals;        compiler->saveds = saveds;
         compiler->args = args;          compiler->args = args;
        compiler->local_size = (local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1);#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
        compiler->temporaries_start = compiler->local_size;        compiler->logical_local_size = local_size;
        if (temporaries > 3)#endif
                compiler->local_size += (temporaries - 3) * sizeof(sljit_uw);
        compiler->generals_start = compiler->local_size;#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
        if (generals > 3)        locals_offset = 2 * sizeof(sljit_uw);
                compiler->local_size += (generals - 3) * sizeof(sljit_uw);#else
         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;
         if (saveds > 3)
                 locals_offset += (saveds - 3) * sizeof(sljit_uw);
         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));
 #endif
 }  }
   
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, 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, src, srcw);        check_sljit_emit_return(compiler, op, src, srcw);
         SLJIT_ASSERT(compiler->args >= 0);          SLJIT_ASSERT(compiler->args >= 0);
   
         compiler->flags_saved = 0;          compiler->flags_saved = 0;
        CHECK_EXTRA_REGS(src, srcw, (void)0);        FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
   
        if (src != SLJIT_UNUSED && src != SLJIT_RETURN_REG)        SLJIT_ASSERT(compiler->local_size > 0);
                FAIL_IF(emit_mov(compiler, SLJIT_RETURN_REG, 0, src, srcw));        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));
   
        if (compiler->local_size > 0)        size = 2 + (compiler->saveds <= 3 ? compiler->saveds : 3);
                FAIL_IF(emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05, 
                                SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size)); 
 
        size = 2 + (compiler->generals <= 3 ? compiler->generals : 3); 
 #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)
                 size += 2;                  size += 2;
Line 200  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);
   
        if (compiler->generals > 0)        if (compiler->saveds > 0)
                POP_REG(reg_map[SLJIT_GENERAL_REG1]);                POP_REG(reg_map[SLJIT_SAVED_REG1]);
        if (compiler->generals > 1)        if (compiler->saveds > 1)
                POP_REG(reg_map[SLJIT_GENERAL_REG2]);                POP_REG(reg_map[SLJIT_SAVED_REG2]);
        if (compiler->generals > 2)        if (compiler->saveds > 2)
                POP_REG(reg_map[SLJIT_GENERAL_REG3]);                POP_REG(reg_map[SLJIT_SAVED_REG3]);
         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 232  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 252  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 268  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 304  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 343  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 377  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 389  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 399  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, int args, int temporaries, int generals, int local_size)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, args, temporaries, generals, local_size);        check_sljit_emit_fast_enter(compiler, dst, dstw);
         ADJUST_LOCAL_OFFSET(dst, dstw);
   
         compiler->temporaries = temporaries;  
         compiler->generals = generals;  
         compiler->args = args;  
         compiler->local_size = (local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1);  
         compiler->temporaries_start = compiler->local_size;  
         if (temporaries > 3)  
                 compiler->local_size += (temporaries - 3) * sizeof(sljit_uw);  
         compiler->generals_start = compiler->local_size;  
         if (generals > 3)  
                 compiler->local_size += (generals - 3) * sizeof(sljit_uw);  
   
         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);
           ADJUST_LOCAL_OFFSET(src, srcw);
   
         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  
changed lines
  Added in v.1.1.1.4


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