Diff for /embedaddon/pcre/sljit/sljitNativeARM_v5.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 27 Line 27
 SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()  SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()
 {  {
 #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)  #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
        return "arm-v7";        return "ARMv7" SLJIT_CPUINFO;
 #elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)  #elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
        return "arm-v5";        return "ARMv5" SLJIT_CPUINFO;
 #else  #else
 #error "Internal error: Unknown ARM architecture"  #error "Internal error: Unknown ARM architecture"
 #endif  #endif
Line 54  SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_p Line 54  SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_p
 #define MAX_DIFFERENCE(max_diff) \  #define MAX_DIFFERENCE(max_diff) \
         (((max_diff) / (int)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1))          (((max_diff) / (int)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1))
   
/* 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, 10, 11, 4, 5, 6, 7, 8, 13, 3, 12, 14, 15    0, 0, 1, 2, 10, 11, 4, 5, 6, 7, 8, 13, 3, 12, 14, 15
 };  };
Line 84  static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS Line 84  static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS
 #define BX              0xe12fff10  #define BX              0xe12fff10
 #define CLZ             0xe16f0f10  #define CLZ             0xe16f0f10
 #define CMP_DP          0xa  #define CMP_DP          0xa
#define DEBUGGER        0xe1200070#define BKPT            0xe1200070
 #define EOR_DP          0x1  #define EOR_DP          0x1
 #define MOV_DP          0xd  #define MOV_DP          0xd
 #define MUL             0xe0000090  #define MUL             0xe0000090
Line 98  static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS Line 98  static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS
 #define SBC_DP          0x6  #define SBC_DP          0x6
 #define SMULL           0xe0c00090  #define SMULL           0xe0c00090
 #define SUB_DP          0x2  #define SUB_DP          0x2
   #define UMULL           0xe0800090
 #define VABS_F64        0xeeb00bc0  #define VABS_F64        0xeeb00bc0
 #define VADD_F64        0xee300b00  #define VADD_F64        0xee300b00
 #define VCMP_F64        0xeeb40b40  #define VCMP_F64        0xeeb40b40
Line 819  static int emit_op(struct sljit_compiler *compiler, in Line 820  static int emit_op(struct sljit_compiler *compiler, in
         int src1, sljit_w src1w,          int src1, sljit_w src1w,
         int src2, sljit_w src2w);          int src2, sljit_w src2w);
   
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_uw push;          sljit_uw 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 general registers, temporary registers        /* Push saved registers, temporary registers
            stmdb sp!, {..., lr} */             stmdb sp!, {..., lr} */
         push = PUSH | (1 << 14);          push = PUSH | (1 << 14);
         if (temporaries >= 5)          if (temporaries >= 5)
                 push |= 1 << 11;                  push |= 1 << 11;
         if (temporaries >= 4)          if (temporaries >= 4)
                 push |= 1 << 10;                  push |= 1 << 10;
        if (generals >= 5)        if (saveds >= 5)
                 push |= 1 << 8;                  push |= 1 << 8;
        if (generals >= 4)        if (saveds >= 4)
                 push |= 1 << 7;                  push |= 1 << 7;
        if (generals >= 3)        if (saveds >= 3)
                 push |= 1 << 6;                  push |= 1 << 6;
        if (generals >= 2)        if (saveds >= 2)
                 push |= 1 << 5;                  push |= 1 << 5;
        if (generals >= 1)        if (saveds >= 1)
                 push |= 1 << 4;                  push |= 1 << 4;
         EMIT_INSTRUCTION(push);          EMIT_INSTRUCTION(push);
   
         /* Stack must be aligned to 8 bytes: */          /* Stack must be aligned to 8 bytes: */
        size = (1 + generals) * sizeof(sljit_uw);        size = (1 + saveds) * sizeof(sljit_uw);
         if (temporaries >= 4)          if (temporaries >= 4)
                 size += (temporaries - 3) * sizeof(sljit_uw);                  size += (temporaries - 3) * sizeof(sljit_uw);
         local_size += size;          local_size += size;
Line 861  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s Line 862  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s
                 FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size));                  FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size));
   
         if (args >= 1)          if (args >= 1)
                EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_GENERAL_REG1, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG1)));                EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG1, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG1)));
         if (args >= 2)          if (args >= 2)
                EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_GENERAL_REG2, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG2)));                EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG2, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG2)));
         if (args >= 3)          if (args >= 3)
                EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_GENERAL_REG3, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG3)));                EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG3, SLJIT_UNUSED, RM(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 = (1 + generals) * sizeof(sljit_uw);        size = (1 + saveds) * sizeof(sljit_uw);
         if (temporaries >= 4)          if (temporaries >= 4)
                 size += (temporaries - 3) * sizeof(sljit_uw);                  size += (temporaries - 3) * sizeof(sljit_uw);
         local_size += size;          local_size += size;
Line 889  SLJIT_API_FUNC_ATTRIBUTE void sljit_fake_enter(struct  Line 890  SLJIT_API_FUNC_ATTRIBUTE void sljit_fake_enter(struct 
         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_uw pop;          sljit_uw 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));
                FAIL_IF(emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, SLJIT_RETURN_REG, 0, TMP_REG1, 0, src, srcw)); 
   
         if (compiler->local_size > 0)          if (compiler->local_size > 0)
                 FAIL_IF(emit_op(compiler, SLJIT_ADD, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size));                  FAIL_IF(emit_op(compiler, SLJIT_ADD, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size));
   
         pop = POP | (1 << 15);          pop = POP | (1 << 15);
        /* Push general registers, temporary registers        /* Push saved registers, temporary registers
            ldmia sp!, {..., pc} */             ldmia sp!, {..., pc} */
         if (compiler->temporaries >= 5)          if (compiler->temporaries >= 5)
                 pop |= 1 << 11;                  pop |= 1 << 11;
         if (compiler->temporaries >= 4)          if (compiler->temporaries >= 4)
                 pop |= 1 << 10;                  pop |= 1 << 10;
        if (compiler->generals >= 5)        if (compiler->saveds >= 5)
                 pop |= 1 << 8;                  pop |= 1 << 8;
        if (compiler->generals >= 4)        if (compiler->saveds >= 4)
                 pop |= 1 << 7;                  pop |= 1 << 7;
        if (compiler->generals >= 3)        if (compiler->saveds >= 3)
                 pop |= 1 << 6;                  pop |= 1 << 6;
        if (compiler->generals >= 2)        if (compiler->saveds >= 2)
                 pop |= 1 << 5;                  pop |= 1 << 5;
        if (compiler->generals >= 1)        if (compiler->saveds >= 1)
                 pop |= 1 << 4;                  pop |= 1 << 4;
   
         return push_inst(compiler, pop);          return push_inst(compiler, pop);
Line 992  static sljit_w data_transfer_insts[16] = { Line 992  static sljit_w data_transfer_insts[16] = {
         if (compiler->shift_imm != 0x20) { \          if (compiler->shift_imm != 0x20) { \
                 SLJIT_ASSERT(src1 == TMP_REG1); \                  SLJIT_ASSERT(src1 == TMP_REG1); \
                 SLJIT_ASSERT(!(flags & ARGS_SWAPPED)); \                  SLJIT_ASSERT(!(flags & ARGS_SWAPPED)); \
                return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (compiler->shift_imm << 7) | (opcode << 5) | reg_map[src2])); \                if (compiler->shift_imm != 0) \
                         return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (compiler->shift_imm << 7) | (opcode << 5) | reg_map[src2])); \
                 return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, reg_map[src2])); \
         } \          } \
         return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (reg_map[(flags & ARGS_SWAPPED) ? src1 : src2] << 8) | (opcode << 5) | 0x10 | ((flags & ARGS_SWAPPED) ? reg_map[src2] : reg_map[src1])));          return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (reg_map[(flags & ARGS_SWAPPED) ? src1 : src2] << 8) | (opcode << 5) | 0x10 | ((flags & ARGS_SWAPPED) ? reg_map[src2] : reg_map[src1])));
   
Line 1755  static int emit_op(struct sljit_compiler *compiler, in Line 1757  static int emit_op(struct sljit_compiler *compiler, in
         return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
 }  }
   
   #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 1763  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct slj Line 1780  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct slj
         op = GET_OPCODE(op);          op = GET_OPCODE(op);
         switch (op) {          switch (op) {
         case SLJIT_BREAKPOINT:          case SLJIT_BREAKPOINT:
                EMIT_INSTRUCTION(DEBUGGER);                EMIT_INSTRUCTION(BKPT);
                 break;                  break;
         case SLJIT_NOP:          case SLJIT_NOP:
                 EMIT_INSTRUCTION(NOP);                  EMIT_INSTRUCTION(NOP);
                 break;                  break;
           case SLJIT_UMUL:
           case SLJIT_SMUL:
   #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
                   return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL)
                           | (reg_map[SLJIT_TEMPORARY_REG2] << 16)
                           | (reg_map[SLJIT_TEMPORARY_REG1] << 12)
                           | (reg_map[SLJIT_TEMPORARY_REG1] << 8)
                           | reg_map[SLJIT_TEMPORARY_REG2]);
   #else
                   EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG2)));
                   return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL)
                           | (reg_map[SLJIT_TEMPORARY_REG2] << 16)
                           | (reg_map[SLJIT_TEMPORARY_REG1] << 12)
                           | (reg_map[SLJIT_TEMPORARY_REG1] << 8)
                           | reg_map[TMP_REG1]);
   #endif
           case SLJIT_UDIV:
           case SLJIT_SDIV:
                   if (compiler->temporaries >= 3)
                           EMIT_INSTRUCTION(0xe52d2008 /* 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 >= 3)
                           return push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */);
                   return SLJIT_SUCCESS;
         }          }
   
         return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
Line 1870  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct slj Line 1916  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 == 4);
   
           return push_inst(compiler, *(sljit_uw*)instruction);
   }
   
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
 /*  Floating point operators                                             */  /*  Floating point operators                                             */
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
Line 2079  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sl Line 2141  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 = (1 + generals) * sizeof(sljit_uw);        size = (1 + saveds) * sizeof(sljit_uw);
         if (temporaries >= 4)          if (temporaries >= 4)
                 size += (temporaries - 3) * sizeof(sljit_uw);                  size += (temporaries - 3) * sizeof(sljit_uw);
         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>