Diff for /embedaddon/pcre/sljit/sljitNativeARM_Thumb2.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/21 23:05:52 version 1.1.1.2, 2012/02/21 23:50:25
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
   
 SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()  SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()
 {  {
        return "arm-thumb2";        return "ARM-Thumb2" SLJIT_CPUINFO;
 }  }
   
 /* Last register + 1. */  /* Last register + 1. */
Line 38  SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_p Line 38  SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_p
 #define TMP_FREG1       (SLJIT_FLOAT_REG4 + 1)  #define TMP_FREG1       (SLJIT_FLOAT_REG4 + 1)
 #define TMP_FREG2       (SLJIT_FLOAT_REG4 + 2)  #define TMP_FREG2       (SLJIT_FLOAT_REG4 + 2)
   
/* See sljit_emit_enter if you want to change them. *//* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */
 static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = {  static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = {
   0, 0, 1, 2, 12, 5, 6, 7, 8, 10, 11, 13, 3, 4, 14, 15    0, 0, 1, 2, 12, 5, 6, 7, 8, 10, 11, 13, 3, 4, 14, 15
 };  };
Line 122  typedef sljit_ui sljit_ins; Line 122  typedef sljit_ui sljit_ins;
 #define LSR_W           0xfa20f000  #define LSR_W           0xfa20f000
 #define LSR_WI          0xea4f0010  #define LSR_WI          0xea4f0010
 #define MOV             0x4600  #define MOV             0x4600
   #define MOVS            0x0000
 #define MOVSI           0x2000  #define MOVSI           0x2000
 #define MOVT            0xf2c00000  #define MOVT            0xf2c00000
 #define MOVW            0xf2400000  #define MOVW            0xf2400000
   #define MOV_W           0xea4f0000
 #define MOV_WI          0xf04f0000  #define MOV_WI          0xf04f0000
 #define MUL             0xfb00f000  #define MUL             0xfb00f000
 #define MVNS            0x43c0  #define MVNS            0x43c0
Line 158  typedef sljit_ui sljit_ins; Line 160  typedef sljit_ui sljit_ins;
 #define SXTH            0xb200  #define SXTH            0xb200
 #define SXTH_W          0xfa0ff080  #define SXTH_W          0xfa0ff080
 #define TST             0x4200  #define TST             0x4200
   #define UMULL           0xfba00000
 #define UXTB            0xb2c0  #define UXTB            0xb2c0
 #define UXTB_W          0xfa5ff080  #define UXTB_W          0xfa5ff080
 #define UXTH            0xb280  #define UXTH            0xb280
Line 616  static int emit_op_imm(struct sljit_compiler *compiler Line 619  static int emit_op_imm(struct sljit_compiler *compiler
                 case SLJIT_SHL:                  case SLJIT_SHL:
                         if (flags & ARG2_IMM) {                          if (flags & ARG2_IMM) {
                                 imm &= 0x1f;                                  imm &= 0x1f;
                                   if (imm == 0) {
                                           if (!(flags & SET_FLAGS))
                                                   return push_inst16(compiler, MOV | SET_REGS44(dst, reg));
                                           if (IS_2_LO_REGS(dst, reg))
                                                   return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg));
                                           return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg));
                                   }
                                 if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))                                  if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))
                                         return push_inst16(compiler, LSLSI | RD3(dst) | RN3(reg) | (imm << 6));                                          return push_inst16(compiler, LSLSI | RD3(dst) | RN3(reg) | (imm << 6));
                                 return push_inst32(compiler, LSL_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));                                  return push_inst32(compiler, LSL_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
Line 624  static int emit_op_imm(struct sljit_compiler *compiler Line 634  static int emit_op_imm(struct sljit_compiler *compiler
                 case SLJIT_LSHR:                  case SLJIT_LSHR:
                         if (flags & ARG2_IMM) {                          if (flags & ARG2_IMM) {
                                 imm &= 0x1f;                                  imm &= 0x1f;
                                   if (imm == 0) {
                                           if (!(flags & SET_FLAGS))
                                                   return push_inst16(compiler, MOV | SET_REGS44(dst, reg));
                                           if (IS_2_LO_REGS(dst, reg))
                                                   return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg));
                                           return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg));
                                   }
                                 if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))                                  if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))
                                         return push_inst16(compiler, LSRSI | RD3(dst) | RN3(reg) | (imm << 6));                                          return push_inst16(compiler, LSRSI | RD3(dst) | RN3(reg) | (imm << 6));
                                 return push_inst32(compiler, LSR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));                                  return push_inst32(compiler, LSR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
Line 632  static int emit_op_imm(struct sljit_compiler *compiler Line 649  static int emit_op_imm(struct sljit_compiler *compiler
                 case SLJIT_ASHR:                  case SLJIT_ASHR:
                         if (flags & ARG2_IMM) {                          if (flags & ARG2_IMM) {
                                 imm &= 0x1f;                                  imm &= 0x1f;
                                   if (imm == 0) {
                                           if (!(flags & SET_FLAGS))
                                                   return push_inst16(compiler, MOV | SET_REGS44(dst, reg));
                                           if (IS_2_LO_REGS(dst, reg))
                                                   return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg));
                                           return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg));
                                   }
                                 if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))                                  if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))
                                         return push_inst16(compiler, ASRSI | RD3(dst) | RN3(reg) | (imm << 6));                                          return push_inst16(compiler, ASRSI | RD3(dst) | RN3(reg) | (imm << 6));
                                 return push_inst32(compiler, ASR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));                                  return push_inst32(compiler, ASR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
Line 1077  static SLJIT_INLINE int emit_op_mem(struct sljit_compi Line 1101  static SLJIT_INLINE int emit_op_mem(struct sljit_compi
         return getput_arg(compiler, flags, reg, arg, argw, 0, 0);          return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
 }  }
   
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 int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
 {  {
         int size;          int size;
         sljit_ins push;          sljit_ins push;
   
         CHECK_ERROR();          CHECK_ERROR();
        check_sljit_emit_enter(compiler, args, temporaries, generals, local_size);        check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);
   
         compiler->temporaries = temporaries;          compiler->temporaries = temporaries;
        compiler->generals = generals;        compiler->saveds = saveds;
   
         push = (1 << 4);          push = (1 << 4);
        if (generals >= 5)        if (saveds >= 5)
                 push |= 1 << 11;                  push |= 1 << 11;
        if (generals >= 4)        if (saveds >= 4)
                 push |= 1 << 10;                  push |= 1 << 10;
        if (generals >= 3)        if (saveds >= 3)
                 push |= 1 << 8;                  push |= 1 << 8;
        if (generals >= 2)        if (saveds >= 2)
                 push |= 1 << 7;                  push |= 1 << 7;
        if (generals >= 1)        if (saveds >= 1)
                 push |= 1 << 6;                  push |= 1 << 6;
         if (temporaries >= 5)          if (temporaries >= 5)
                 push |= 1 << 5;                  push |= 1 << 5;
        FAIL_IF(generals >= 3        FAIL_IF(saveds >= 3
                 ? push_inst32(compiler, PUSH_W | (1 << 14) | push)                  ? push_inst32(compiler, PUSH_W | (1 << 14) | push)
                 : push_inst16(compiler, PUSH | push));                  : push_inst16(compiler, PUSH | push));
   
         /* Stack must be aligned to 8 bytes: */          /* Stack must be aligned to 8 bytes: */
        size = (3 + generals) * sizeof(sljit_uw);        size = (3 + saveds) * sizeof(sljit_uw);
         local_size += size;          local_size += size;
         local_size = (local_size + 7) & ~7;          local_size = (local_size + 7) & ~7;
         local_size -= size;          local_size -= size;
Line 1119  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s Line 1143  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s
         }          }
   
         if (args >= 1)          if (args >= 1)
                FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_GENERAL_REG1, SLJIT_TEMPORARY_REG1)));                FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG1, SLJIT_TEMPORARY_REG1)));
         if (args >= 2)          if (args >= 2)
                FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_GENERAL_REG2, SLJIT_TEMPORARY_REG2)));                FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG2, SLJIT_TEMPORARY_REG2)));
         if (args >= 3)          if (args >= 3)
                FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_GENERAL_REG3, SLJIT_TEMPORARY_REG3)));                FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG3, SLJIT_TEMPORARY_REG3)));
   
         return SLJIT_SUCCESS;          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, int args, int temporaries, int saveds, int local_size)
 {  {
         int size;          int size;
   
         CHECK_ERROR_VOID();          CHECK_ERROR_VOID();
        check_sljit_fake_enter(compiler, args, temporaries, generals, local_size);        check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
   
         compiler->temporaries = temporaries;          compiler->temporaries = temporaries;
        compiler->generals = generals;        compiler->saveds = saveds;
   
        size = (3 + generals) * sizeof(sljit_uw);        size = (3 + saveds) * sizeof(sljit_uw);
         local_size += size;          local_size += size;
         local_size = (local_size + 7) & ~7;          local_size = (local_size + 7) & ~7;
         local_size -= size;          local_size -= size;
         compiler->local_size = local_size;          compiler->local_size = local_size;
 }  }
   
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int src, sljit_w srcw)SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
 {  {
         sljit_ins pop;          sljit_ins pop;
   
         CHECK_ERROR();          CHECK_ERROR();
        check_sljit_emit_return(compiler, src, srcw);        check_sljit_emit_return(compiler, op, src, srcw);
   
        if (src != SLJIT_UNUSED && src != SLJIT_RETURN_REG) {        FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
                if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REG3) 
                        FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_RETURN_REG, src))); 
                else 
                        FAIL_IF(emit_op_mem(compiler, WORD_SIZE, SLJIT_RETURN_REG, src, srcw)); 
        } 
   
         if (compiler->local_size > 0) {          if (compiler->local_size > 0) {
                 if (compiler->local_size <= (127 << 2))                  if (compiler->local_size <= (127 << 2))
Line 1167  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct  Line 1186  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct 
         }          }
   
         pop = (1 << 4);          pop = (1 << 4);
        if (compiler->generals >= 5)        if (compiler->saveds >= 5)
                 pop |= 1 << 11;                  pop |= 1 << 11;
        if (compiler->generals >= 4)        if (compiler->saveds >= 4)
                 pop |= 1 << 10;                  pop |= 1 << 10;
        if (compiler->generals >= 3)        if (compiler->saveds >= 3)
                 pop |= 1 << 8;                  pop |= 1 << 8;
        if (compiler->generals >= 2)        if (compiler->saveds >= 2)
                 pop |= 1 << 7;                  pop |= 1 << 7;
        if (compiler->generals >= 1)        if (compiler->saveds >= 1)
                 pop |= 1 << 6;                  pop |= 1 << 6;
         if (compiler->temporaries >= 5)          if (compiler->temporaries >= 5)
                 pop |= 1 << 5;                  pop |= 1 << 5;
        return compiler->generals >= 3        return compiler->saveds >= 3
                 ? push_inst32(compiler, POP_W | (1 << 15) | pop)                  ? push_inst32(compiler, POP_W | (1 << 15) | pop)
                 : push_inst16(compiler, POP | pop);                  : push_inst16(compiler, POP | pop);
 }  }
Line 1188  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct  Line 1207  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct 
 /*  Operators                                                            */  /*  Operators                                                            */
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
   
   #ifdef __cplusplus
   extern "C" {
   #endif
   
   #if defined(__GNUC__)
   extern unsigned int __aeabi_uidivmod(unsigned numerator, unsigned denominator);
   extern unsigned int __aeabi_idivmod(unsigned numerator, unsigned denominator);
   #else
   #error "Software divmod functions are needed"
   #endif
   
   #ifdef __cplusplus
   }
   #endif
   
 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
 {  {
         CHECK_ERROR();          CHECK_ERROR();
Line 1201  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct slj Line 1235  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct slj
         case SLJIT_NOP:          case SLJIT_NOP:
                 push_inst16(compiler, NOP);                  push_inst16(compiler, NOP);
                 break;                  break;
           case SLJIT_UMUL:
           case SLJIT_SMUL:
                   return push_inst32(compiler, (op == SLJIT_UMUL ? UMULL : SMULL)
                           | (reg_map[SLJIT_TEMPORARY_REG2] << 8)
                           | (reg_map[SLJIT_TEMPORARY_REG1] << 12)
                           | (reg_map[SLJIT_TEMPORARY_REG1] << 16)
                           | reg_map[SLJIT_TEMPORARY_REG2]);
           case SLJIT_UDIV:
           case SLJIT_SDIV:
                   if (compiler->temporaries >= 4) {
                           FAIL_IF(push_inst32(compiler, 0xf84d2d04 /* str r2, [sp, #-4]! */));
                           FAIL_IF(push_inst32(compiler, 0xf84dcd04 /* str ip, [sp, #-4]! */));
                   } else if (compiler->temporaries >= 3)
                           FAIL_IF(push_inst32(compiler, 0xf84d2d08 /* str r2, [sp, #-8]! */));
   #if defined(__GNUC__)
                   FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
                           (op == SLJIT_UDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
   #else
   #error "Software divmod functions are needed"
   #endif
                   if (compiler->temporaries >= 4) {
                           FAIL_IF(push_inst32(compiler, 0xf85dcb04 /* ldr ip, [sp], #4 */));
                           return push_inst32(compiler, 0xf85d2b04 /* ldr r2, [sp], #4 */);
                   } else if (compiler->temporaries >= 3)
                           return push_inst32(compiler, 0xf85d2b08 /* ldr r2, [sp], #8 */);
                   return SLJIT_SUCCESS;
         }          }
   
         return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
Line 1412  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct slj Line 1472  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct slj
         return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
 }  }
   
   SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)
   {
           check_sljit_get_register_index(reg);
           return reg_map[reg];
   }
   
   SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
           void *instruction, int size)
   {
           CHECK_ERROR();
           check_sljit_emit_op_custom(compiler, instruction, size);
           SLJIT_ASSERT(size == 2 || size == 4);
   
           if (size == 2)
                   return push_inst16(compiler, *(sljit_uh*)instruction);
           return push_inst32(compiler, *(sljit_ins*)instruction);
   }
   
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
 /*  Floating point operators                                             */  /*  Floating point operators                                             */
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
Line 1567  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sl Line 1645  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sl
 /*  Other instructions                                                   */  /*  Other instructions                                                   */
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
   
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 int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size)
 {  {
         int size;          int size;
   
         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, args, temporaries, saveds, local_size);
   
         compiler->temporaries = temporaries;          compiler->temporaries = temporaries;
        compiler->generals = generals;        compiler->saveds = saveds;
   
        size = (3 + generals) * sizeof(sljit_uw);        size = (3 + saveds) * sizeof(sljit_uw);
         local_size += size;          local_size += size;
         local_size = (local_size + 7) & ~7;          local_size = (local_size + 7) & ~7;
         local_size -= size;          local_size -= size;

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


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