Diff for /embedaddon/pcre/sljit/sljitNativeMIPS_32.c between versions 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2012/02/21 23:50:25 version 1.1.1.3, 2013/07/22 08:25:57
Line 26 Line 26
   
 /* mips 32-bit arch dependent functions. */  /* mips 32-bit arch dependent functions. */
   
static int load_immediate(struct sljit_compiler *compiler, int dst_ar, sljit_w imm)static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm)
 {  {
         if (!(imm & ~0xffff))          if (!(imm & ~0xffff))
                 return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);                  return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
Line 66  static int load_immediate(struct sljit_compiler *compi Line 66  static int load_immediate(struct sljit_compiler *compi
                         FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | D(dst), DR(dst))); \                          FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | D(dst), DR(dst))); \
         }          }
   
static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags,static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags,
        int dst, int src1, sljit_w src2)        sljit_si dst, sljit_si src1, sljit_sw src2)
 {  {
        int overflow_ra = 0;        sljit_si overflow_ra = 0;
   
         switch (GET_OPCODE(op)) {          switch (GET_OPCODE(op)) {
           case SLJIT_MOV:
           case SLJIT_MOV_UI:
           case SLJIT_MOV_SI:
           case SLJIT_MOV_P:
                   SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
                   if (dst != src2)
                           return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst));
                   return SLJIT_SUCCESS;
   
           case SLJIT_MOV_UB:
           case SLJIT_MOV_SB:
                   SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
                   if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
                           if (op == SLJIT_MOV_SB) {
   #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
                                   return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
   #else
                                   FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
                                   return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));
   #endif
                           }
                           return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
                   }
                   else if (dst != src2)
                           SLJIT_ASSERT_STOP();
                   return SLJIT_SUCCESS;
   
           case SLJIT_MOV_UH:
           case SLJIT_MOV_SH:
                   SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
                   if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
                           if (op == SLJIT_MOV_SH) {
   #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
                                   return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
   #else
                                   FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
                                   return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));
   #endif
                           }
                           return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
                   }
                   else if (dst != src2)
                           SLJIT_ASSERT_STOP();
                   return SLJIT_SUCCESS;
   
           case SLJIT_NOT:
                   SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
                   if (op & SLJIT_SET_E)
                           FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
                   if (CHECK_FLAGS(SLJIT_SET_E))
                           FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst)));
                   return SLJIT_SUCCESS;
   
           case SLJIT_CLZ:
                   SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
   #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
                   if (op & SLJIT_SET_E)
                           FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
                   if (CHECK_FLAGS(SLJIT_SET_E))
                           FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst)));
   #else
                   if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) {
                           FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG));
                           return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG);
                   }
                   /* Nearly all instructions are unmovable in the following sequence. */
                   FAIL_IF(push_inst(compiler, ADDU_W | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
                   /* Check zero. */
                   FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS));
                   FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS));
                   FAIL_IF(push_inst(compiler, ADDIU_W | SA(0) | T(dst) | IMM(-1), DR(dst)));
                   /* Loop for searching the highest bit. */
                   FAIL_IF(push_inst(compiler, ADDIU_W | S(dst) | T(dst) | IMM(1), DR(dst)));
                   FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS));
                   FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS));
                   if (op & SLJIT_SET_E)
                           return push_inst(compiler, ADDU_W | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG);
   #endif
                   return SLJIT_SUCCESS;
   
         case SLJIT_ADD:          case SLJIT_ADD:
                 if (flags & SRC2_IMM) {                  if (flags & SRC2_IMM) {
                         if (op & SLJIT_SET_O) {                          if (op & SLJIT_SET_O) {
Line 293  static SLJIT_INLINE int emit_single_op(struct sljit_co Line 373  static SLJIT_INLINE int emit_single_op(struct sljit_co
         case SLJIT_ASHR:          case SLJIT_ASHR:
                 EMIT_SHIFT(SRA, SRAV);                  EMIT_SHIFT(SRA, SRAV);
                 return SLJIT_SUCCESS;                  return SLJIT_SUCCESS;
   
         case SLJIT_MOV:  
         case SLJIT_MOV_UI:  
         case SLJIT_MOV_SI:  
                 SLJIT_ASSERT(src1 == TMP_REG1);  
                 if (dst != src2)  
                         return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst));  
                 return SLJIT_SUCCESS;  
   
         case SLJIT_MOV_UB:  
         case SLJIT_MOV_SB:  
                 SLJIT_ASSERT(src1 == TMP_REG1);  
                 if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {  
                         if (op == SLJIT_MOV_SB) {  
 #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)  
                                 return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));  
 #else  
                                 FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));  
                                 return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));  
 #endif  
                         }  
                         return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));  
                 }  
                 else if (dst != src2)  
                         SLJIT_ASSERT_STOP();  
                 return SLJIT_SUCCESS;  
   
         case SLJIT_MOV_UH:  
         case SLJIT_MOV_SH:  
                 SLJIT_ASSERT(src1 == TMP_REG1);  
                 if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {  
                         if (op == SLJIT_MOV_SH) {  
 #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)  
                                 return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));  
 #else  
                                 FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));  
                                 return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));  
 #endif  
                         }  
                         return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));  
                 }  
                 else if (dst != src2)  
                         SLJIT_ASSERT_STOP();  
                 return SLJIT_SUCCESS;  
   
         case SLJIT_NOT:  
                 SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));  
                 if (op & SLJIT_SET_E)  
                         FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));  
                 if (CHECK_FLAGS(SLJIT_SET_E))  
                         FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst)));  
                 return SLJIT_SUCCESS;  
   
         case SLJIT_CLZ:  
                 SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));  
 #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)  
                 if (op & SLJIT_SET_E)  
                         FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));  
                 if (CHECK_FLAGS(SLJIT_SET_E))  
                         FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst)));  
 #else  
                 if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) {  
                         FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG));  
                         return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG);  
                 }  
                 /* Nearly all instructions are unmovable in the following sequence. */  
                 FAIL_IF(push_inst(compiler, ADDU_W | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));  
                 /* Check zero. */  
                 FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(6), UNMOVABLE_INS));  
                 FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS));  
                 /* Check sign bit. */  
                 FAIL_IF(push_inst(compiler, BLTZ | S(TMP_REG1) | IMM(4), UNMOVABLE_INS));  
                 FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(0), UNMOVABLE_INS));  
                 /* Loop for searching the highest bit. */  
                 FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1)));  
                 FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS));  
                 FAIL_IF(push_inst(compiler, ADDIU_W | S(dst) | T(dst) | IMM(1), UNMOVABLE_INS));  
                 if (op & SLJIT_SET_E)  
                         return push_inst(compiler, ADDU_W | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG);  
 #endif  
                 return SLJIT_SUCCESS;  
         }          }
   
         SLJIT_ASSERT_STOP();          SLJIT_ASSERT_STOP();
         return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
 }  }
   
static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value)static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value)
 {  {
        FAIL_IF(push_inst(compiler, LUI | T(reg) | IMM(init_value >> 16), DR(reg)));        FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 16), DR(dst)));
        return push_inst(compiler, ORI | S(reg) | T(reg) | IMM(init_value), DR(reg));        return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
 }  }
   
 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
Line 395  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(slji Line 394  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(slji
         SLJIT_CACHE_FLUSH(inst, inst + 2);          SLJIT_CACHE_FLUSH(inst, inst + 2);
 }  }
   
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
 {  {
         sljit_ins *inst = (sljit_ins*)addr;          sljit_ins *inst = (sljit_ins*)addr;
   

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


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