Diff for /embedaddon/pcre/sljit/sljitNativeMIPS_common.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()
 {  {
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)        return "MIPS" SLJIT_CPUINFO;
        return "mips-32"; 
#else 
#error "mips-64 is not yet supported" 
#endif 
 }  }
   
 /* Latest MIPS architecture. */  /* Latest MIPS architecture. */
Line 109  typedef sljit_ui sljit_ins; Line 105  typedef sljit_ui sljit_ins;
 #define BREAK           (HI(0) | LO(13))  #define BREAK           (HI(0) | LO(13))
 #define C_UN_D          (HI(17) | FMT_D | LO(49))  #define C_UN_D          (HI(17) | FMT_D | LO(49))
 #define C_UEQ_D         (HI(17) | FMT_D | LO(51))  #define C_UEQ_D         (HI(17) | FMT_D | LO(51))
   #define C_ULE_D         (HI(17) | FMT_D | LO(55))
 #define C_ULT_D         (HI(17) | FMT_D | LO(53))  #define C_ULT_D         (HI(17) | FMT_D | LO(53))
   #define DIV             (HI(0) | LO(26))
   #define DIVU            (HI(0) | LO(27))
 #define DIV_D           (HI(17) | FMT_D | LO(3))  #define DIV_D           (HI(17) | FMT_D | LO(3))
 #define J               (HI(2))  #define J               (HI(2))
 #define JAL             (HI(3))  #define JAL             (HI(3))
Line 128  typedef sljit_ui sljit_ins; Line 127  typedef sljit_ui sljit_ins;
 #define MOVZ            (HI(0) | LO(10))  #define MOVZ            (HI(0) | LO(10))
 #define MUL_D           (HI(17) | FMT_D | LO(2))  #define MUL_D           (HI(17) | FMT_D | LO(2))
 #define MULT            (HI(0) | LO(24))  #define MULT            (HI(0) | LO(24))
   #define MULTU           (HI(0) | LO(25))
 #define NOP             (HI(0) | LO(0))  #define NOP             (HI(0) | LO(0))
 #define NOR             (HI(0) | LO(39))  #define NOR             (HI(0) | LO(39))
 #define OR              (HI(0) | LO(37))  #define OR              (HI(0) | LO(37))
Line 455  static int emit_op(struct sljit_compiler *compiler, in Line 455  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)
 {  {
         sljit_ins base;          sljit_ins base;
   
         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;
   
         compiler->has_locals = local_size > 0;          compiler->has_locals = local_size > 0;
        local_size += (generals + 2 + 4) * sizeof(sljit_w);        local_size += (saveds + 2 + 4) * sizeof(sljit_w);
         local_size = (local_size + 15) & ~0xf;          local_size = (local_size + 15) & ~0xf;
         compiler->local_size = local_size;          compiler->local_size = local_size;
   
Line 486  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s Line 486  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s
         FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (int)sizeof(sljit_w)), MOVABLE_INS));          FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (int)sizeof(sljit_w)), MOVABLE_INS));
         if (compiler->has_locals)          if (compiler->has_locals)
                 FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_LOCALS_REG) | IMM(local_size - 2 * (int)sizeof(sljit_w)), MOVABLE_INS));                  FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_LOCALS_REG) | IMM(local_size - 2 * (int)sizeof(sljit_w)), MOVABLE_INS));
        if (generals >= 1)        if (saveds >= 1)
                FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_GENERAL_REG1) | IMM(local_size - 3 * (int)sizeof(sljit_w)), MOVABLE_INS));                FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG1) | IMM(local_size - 3 * (int)sizeof(sljit_w)), MOVABLE_INS));
        if (generals >= 2)        if (saveds >= 2)
                FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_GENERAL_REG2) | IMM(local_size - 4 * (int)sizeof(sljit_w)), MOVABLE_INS));                FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG2) | IMM(local_size - 4 * (int)sizeof(sljit_w)), MOVABLE_INS));
        if (generals >= 3)        if (saveds >= 3)
                FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_GENERAL_REG3) | IMM(local_size - 5 * (int)sizeof(sljit_w)), MOVABLE_INS));                FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG3) | IMM(local_size - 5 * (int)sizeof(sljit_w)), MOVABLE_INS));
        if (generals >= 4)        if (saveds >= 4)
                FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_GENERAL_EREG1) | IMM(local_size - 6 * (int)sizeof(sljit_w)), MOVABLE_INS));                FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_EREG1) | IMM(local_size - 6 * (int)sizeof(sljit_w)), MOVABLE_INS));
        if (generals >= 5)        if (saveds >= 5)
                FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_GENERAL_EREG2) | IMM(local_size - 7 * (int)sizeof(sljit_w)), MOVABLE_INS));                FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_EREG2) | IMM(local_size - 7 * (int)sizeof(sljit_w)), MOVABLE_INS));
   
         if (compiler->has_locals)          if (compiler->has_locals)
                 FAIL_IF(push_inst(compiler, ADDIU_W | S(REAL_STACK_PTR) | T(SLJIT_LOCALS_REG) | IMM(4 * sizeof(sljit_w)), DR(SLJIT_LOCALS_REG)));                  FAIL_IF(push_inst(compiler, ADDIU_W | S(REAL_STACK_PTR) | T(SLJIT_LOCALS_REG) | IMM(4 * sizeof(sljit_w)), DR(SLJIT_LOCALS_REG)));
   
         if (args >= 1)          if (args >= 1)
                FAIL_IF(push_inst(compiler, ADDU_W | SA(4) | TA(0) | D(SLJIT_GENERAL_REG1), DR(SLJIT_GENERAL_REG1)));                FAIL_IF(push_inst(compiler, ADDU_W | SA(4) | TA(0) | D(SLJIT_SAVED_REG1), DR(SLJIT_SAVED_REG1)));
         if (args >= 2)          if (args >= 2)
                FAIL_IF(push_inst(compiler, ADDU_W | SA(5) | TA(0) | D(SLJIT_GENERAL_REG2), DR(SLJIT_GENERAL_REG2)));                FAIL_IF(push_inst(compiler, ADDU_W | SA(5) | TA(0) | D(SLJIT_SAVED_REG2), DR(SLJIT_SAVED_REG2)));
         if (args >= 3)          if (args >= 3)
                FAIL_IF(push_inst(compiler, ADDU_W | SA(6) | TA(0) | D(SLJIT_GENERAL_REG3), DR(SLJIT_GENERAL_REG3)));                FAIL_IF(push_inst(compiler, ADDU_W | SA(6) | TA(0) | D(SLJIT_SAVED_REG3), DR(SLJIT_SAVED_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)
 {  {
         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;
   
         compiler->has_locals = local_size > 0;          compiler->has_locals = local_size > 0;
        local_size += (generals + 2 + 4) * sizeof(sljit_w);        local_size += (saveds + 2 + 4) * sizeof(sljit_w);
         compiler->local_size = (local_size + 15) & ~0xf;          compiler->local_size = (local_size + 15) & ~0xf;
 }  }
   
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)
 {  {
         int local_size;          int local_size;
         sljit_ins base;          sljit_ins base;
   
         CHECK_ERROR();          CHECK_ERROR();
        check_sljit_emit_return(compiler, src, srcw);        check_sljit_emit_return(compiler, op, src, srcw);
   
        local_size = compiler->local_size;        FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
   
        if (src != SLJIT_UNUSED && src != SLJIT_RETURN_REG)        local_size = compiler->local_size;
                FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, SLJIT_RETURN_REG, 0, TMP_REG1, 0, src, srcw)); 
 
         if (local_size <= SIMM_MAX)          if (local_size <= SIMM_MAX)
                 base = S(REAL_STACK_PTR);                  base = S(REAL_STACK_PTR);
         else {          else {
Line 546  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct  Line 544  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct 
         }          }
   
         FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (int)sizeof(sljit_w)), RETURN_ADDR_REG));          FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (int)sizeof(sljit_w)), RETURN_ADDR_REG));
        if (compiler->generals >= 5)        if (compiler->saveds >= 5)
                FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_GENERAL_EREG2) | IMM(local_size - 7 * (int)sizeof(sljit_w)), DR(SLJIT_GENERAL_EREG2)));                FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_EREG2) | IMM(local_size - 7 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_EREG2)));
        if (compiler->generals >= 4)        if (compiler->saveds >= 4)
                FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_GENERAL_EREG1) | IMM(local_size - 6 * (int)sizeof(sljit_w)), DR(SLJIT_GENERAL_EREG1)));                FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_EREG1) | IMM(local_size - 6 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_EREG1)));
        if (compiler->generals >= 3)        if (compiler->saveds >= 3)
                FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_GENERAL_REG3) | IMM(local_size - 5 * (int)sizeof(sljit_w)), DR(SLJIT_GENERAL_REG3)));                FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG3) | IMM(local_size - 5 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG3)));
        if (compiler->generals >= 2)        if (compiler->saveds >= 2)
                FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_GENERAL_REG2) | IMM(local_size - 4 * (int)sizeof(sljit_w)), DR(SLJIT_GENERAL_REG2)));                FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG2) | IMM(local_size - 4 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG2)));
        if (compiler->generals >= 1)        if (compiler->saveds >= 1)
                FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_GENERAL_REG1) | IMM(local_size - 3 * (int)sizeof(sljit_w)), DR(SLJIT_GENERAL_REG1)));                FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG1) | IMM(local_size - 3 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG1)));
         if (compiler->has_locals)          if (compiler->has_locals)
                 FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_LOCALS_REG) | IMM(local_size - 2 * (int)sizeof(sljit_w)), DR(SLJIT_LOCALS_REG)));                  FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_LOCALS_REG) | IMM(local_size - 2 * (int)sizeof(sljit_w)), DR(SLJIT_LOCALS_REG)));
   
Line 929  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct slj Line 927  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct slj
                 return push_inst(compiler, BREAK, UNMOVABLE_INS);                  return push_inst(compiler, BREAK, UNMOVABLE_INS);
         case SLJIT_NOP:          case SLJIT_NOP:
                 return push_inst(compiler, NOP, UNMOVABLE_INS);                  return push_inst(compiler, NOP, UNMOVABLE_INS);
           case SLJIT_UMUL:
           case SLJIT_SMUL:
                   FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? MULTU : MULT) | S(SLJIT_TEMPORARY_REG1) | T(SLJIT_TEMPORARY_REG2), MOVABLE_INS));
                   FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_TEMPORARY_REG1), DR(SLJIT_TEMPORARY_REG1)));
                   return push_inst(compiler, MFHI | D(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2));
           case SLJIT_UDIV:
           case SLJIT_SDIV:
   #if !(defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
                   FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
                   FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
   #endif
                   FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVU : DIV) | S(SLJIT_TEMPORARY_REG1) | T(SLJIT_TEMPORARY_REG2), MOVABLE_INS));
                   FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_TEMPORARY_REG1), DR(SLJIT_TEMPORARY_REG1)));
                   return push_inst(compiler, MFHI | D(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2));
         }          }
   
         return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
Line 1054  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct slj Line 1066  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct slj
 #endif  #endif
 }  }
   
   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_ins*)instruction, UNMOVABLE_INS);
   }
   
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
 /*  Floating point operators                                             */  /*  Floating point operators                                             */
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
Line 1232  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sl Line 1260  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)
 {  {
         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;
   
         compiler->has_locals = local_size > 0;          compiler->has_locals = local_size > 0;
        local_size += (generals + 2 + 4) * sizeof(sljit_w);        local_size += (saveds + 2 + 4) * sizeof(sljit_w);
         compiler->local_size = (local_size + 15) & ~0xf;          compiler->local_size = (local_size + 15) & ~0xf;
   
         if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)          if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)
Line 1554  SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit Line 1582  SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit
   
 #undef RESOLVE_IMM1  #undef RESOLVE_IMM1
 #undef RESOLVE_IMM2  #undef RESOLVE_IMM2
   
   SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type,
           int src1, sljit_w src1w,
           int src2, sljit_w src2w)
   {
           struct sljit_jump *jump;
           sljit_ins inst;
           int if_true;
   
           CHECK_ERROR_PTR();
           check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w);
   
           compiler->cache_arg = 0;
           compiler->cache_argw = 0;
   
           if (src1 > SLJIT_FLOAT_REG4) {
                   PTR_FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w));
                   src1 = TMP_FREG1;
           }
           if (src2 > SLJIT_FLOAT_REG4) {
                   PTR_FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w));
                   src2 = TMP_FREG2;
           }
   
           jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
           PTR_FAIL_IF(!jump);
           set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
           jump->flags |= IS_BIT16_COND;
           type &= 0xff;
   
           switch (type) {
           case SLJIT_C_FLOAT_EQUAL:
                   inst = C_UEQ_D;
                   if_true = 1;
                   break;
           case SLJIT_C_FLOAT_NOT_EQUAL:
                   inst = C_UEQ_D;
                   if_true = 0;
                   break;
           case SLJIT_C_FLOAT_LESS:
                   inst = C_ULT_D;
                   if_true = 1;
                   break;
           case SLJIT_C_FLOAT_GREATER_EQUAL:
                   inst = C_ULT_D;
                   if_true = 0;
                   break;
           case SLJIT_C_FLOAT_GREATER:
                   inst = C_ULE_D;
                   if_true = 0;
                   break;
           case SLJIT_C_FLOAT_LESS_EQUAL:
                   inst = C_ULE_D;
                   if_true = 1;
                   break;
           case SLJIT_C_FLOAT_NAN:
                   inst = C_UN_D;
                   if_true = 1;
                   break;
           case SLJIT_C_FLOAT_NOT_NAN:
           default: /* Make compilers happy. */
                   inst = C_UN_D;
                   if_true = 0;
                   break;
           }
   
           PTR_FAIL_IF(push_inst(compiler, inst | FT(src2) | FS(src1), UNMOVABLE_INS));
           /* Intentionally the other opcode. */
           PTR_FAIL_IF(push_inst(compiler, (if_true ? BC1F : BC1T) | JUMP_LENGTH, UNMOVABLE_INS));
           PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
           PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
           jump->addr = compiler->size;
           PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
           return jump;
   }
   
 #undef JUMP_LENGTH  #undef JUMP_LENGTH
 #undef BR_Z  #undef BR_Z

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


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