Annotation of embedaddon/pcre/sljit/sljitNativeMIPS_32.c, revision 1.1.1.3

1.1       misho       1: /*
                      2:  *    Stack-less Just-In-Time compiler
                      3:  *
1.1.1.2   misho       4:  *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
1.1       misho       5:  *
                      6:  * Redistribution and use in source and binary forms, with or without modification, are
                      7:  * permitted provided that the following conditions are met:
                      8:  *
                      9:  *   1. Redistributions of source code must retain the above copyright notice, this list of
                     10:  *      conditions and the following disclaimer.
                     11:  *
                     12:  *   2. Redistributions in binary form must reproduce the above copyright notice, this list
                     13:  *      of conditions and the following disclaimer in the documentation and/or other materials
                     14:  *      provided with the distribution.
                     15:  *
                     16:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
                     17:  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     18:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
                     19:  * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
                     20:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
                     21:  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
                     22:  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     23:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     24:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     25:  */
                     26: 
                     27: /* mips 32-bit arch dependent functions. */
                     28: 
1.1.1.3 ! misho      29: static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm)
1.1       misho      30: {
                     31:        if (!(imm & ~0xffff))
                     32:                return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
                     33: 
                     34:        if (imm < 0 && imm >= SIMM_MIN)
                     35:                return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
                     36: 
                     37:        FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar));
                     38:        return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS;
                     39: }
                     40: 
                     41: #define EMIT_LOGICAL(op_imm, op_norm) \
                     42:        if (flags & SRC2_IMM) { \
                     43:                if (op & SLJIT_SET_E) \
                     44:                        FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \
                     45:                if (CHECK_FLAGS(SLJIT_SET_E)) \
                     46:                        FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \
                     47:        } \
                     48:        else { \
                     49:                if (op & SLJIT_SET_E) \
                     50:                        FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
                     51:                if (CHECK_FLAGS(SLJIT_SET_E)) \
                     52:                        FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \
                     53:        }
                     54: 
                     55: #define EMIT_SHIFT(op_imm, op_norm) \
                     56:        if (flags & SRC2_IMM) { \
                     57:                if (op & SLJIT_SET_E) \
                     58:                        FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \
                     59:                if (CHECK_FLAGS(SLJIT_SET_E)) \
                     60:                        FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \
                     61:        } \
                     62:        else { \
                     63:                if (op & SLJIT_SET_E) \
                     64:                        FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
                     65:                if (CHECK_FLAGS(SLJIT_SET_E)) \
                     66:                        FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | D(dst), DR(dst))); \
                     67:        }
                     68: 
1.1.1.3 ! misho      69: static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags,
        !            70:        sljit_si dst, sljit_si src1, sljit_sw src2)
1.1       misho      71: {
1.1.1.3 ! misho      72:        sljit_si overflow_ra = 0;
1.1       misho      73: 
                     74:        switch (GET_OPCODE(op)) {
1.1.1.3 ! misho      75:        case SLJIT_MOV:
        !            76:        case SLJIT_MOV_UI:
        !            77:        case SLJIT_MOV_SI:
        !            78:        case SLJIT_MOV_P:
        !            79:                SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
        !            80:                if (dst != src2)
        !            81:                        return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst));
        !            82:                return SLJIT_SUCCESS;
        !            83: 
        !            84:        case SLJIT_MOV_UB:
        !            85:        case SLJIT_MOV_SB:
        !            86:                SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
        !            87:                if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
        !            88:                        if (op == SLJIT_MOV_SB) {
        !            89: #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
        !            90:                                return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
        !            91: #else
        !            92:                                FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
        !            93:                                return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));
        !            94: #endif
        !            95:                        }
        !            96:                        return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
        !            97:                }
        !            98:                else if (dst != src2)
        !            99:                        SLJIT_ASSERT_STOP();
        !           100:                return SLJIT_SUCCESS;
        !           101: 
        !           102:        case SLJIT_MOV_UH:
        !           103:        case SLJIT_MOV_SH:
        !           104:                SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
        !           105:                if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
        !           106:                        if (op == SLJIT_MOV_SH) {
        !           107: #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
        !           108:                                return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
        !           109: #else
        !           110:                                FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
        !           111:                                return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));
        !           112: #endif
        !           113:                        }
        !           114:                        return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
        !           115:                }
        !           116:                else if (dst != src2)
        !           117:                        SLJIT_ASSERT_STOP();
        !           118:                return SLJIT_SUCCESS;
        !           119: 
        !           120:        case SLJIT_NOT:
        !           121:                SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
        !           122:                if (op & SLJIT_SET_E)
        !           123:                        FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
        !           124:                if (CHECK_FLAGS(SLJIT_SET_E))
        !           125:                        FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst)));
        !           126:                return SLJIT_SUCCESS;
        !           127: 
        !           128:        case SLJIT_CLZ:
        !           129:                SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
        !           130: #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
        !           131:                if (op & SLJIT_SET_E)
        !           132:                        FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
        !           133:                if (CHECK_FLAGS(SLJIT_SET_E))
        !           134:                        FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst)));
        !           135: #else
        !           136:                if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) {
        !           137:                        FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG));
        !           138:                        return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG);
        !           139:                }
        !           140:                /* Nearly all instructions are unmovable in the following sequence. */
        !           141:                FAIL_IF(push_inst(compiler, ADDU_W | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
        !           142:                /* Check zero. */
        !           143:                FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS));
        !           144:                FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS));
        !           145:                FAIL_IF(push_inst(compiler, ADDIU_W | SA(0) | T(dst) | IMM(-1), DR(dst)));
        !           146:                /* Loop for searching the highest bit. */
        !           147:                FAIL_IF(push_inst(compiler, ADDIU_W | S(dst) | T(dst) | IMM(1), DR(dst)));
        !           148:                FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS));
        !           149:                FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS));
        !           150:                if (op & SLJIT_SET_E)
        !           151:                        return push_inst(compiler, ADDU_W | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG);
        !           152: #endif
        !           153:                return SLJIT_SUCCESS;
        !           154: 
1.1       misho     155:        case SLJIT_ADD:
                    156:                if (flags & SRC2_IMM) {
                    157:                        if (op & SLJIT_SET_O) {
                    158:                                FAIL_IF(push_inst(compiler, SRL | T(src1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
                    159:                                if (src2 < 0)
                    160:                                        FAIL_IF(push_inst(compiler, XORI | SA(TMP_EREG1) | TA(TMP_EREG1) | IMM(1), TMP_EREG1));
                    161:                        }
                    162:                        if (op & SLJIT_SET_E)
                    163:                                FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
                    164:                        if (op & SLJIT_SET_C) {
                    165:                                if (src2 >= 0)
                    166:                                        FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
                    167:                                else {
                    168:                                        FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
                    169:                                        FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
                    170:                                }
                    171:                        }
                    172:                        /* dst may be the same as src1 or src2. */
                    173:                        if (CHECK_FLAGS(SLJIT_SET_E))
                    174:                                FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst)));
                    175:                        if (op & SLJIT_SET_O) {
                    176:                                FAIL_IF(push_inst(compiler, SRL | T(dst) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
                    177:                                if (src2 < 0)
                    178:                                        FAIL_IF(push_inst(compiler, XORI | SA(OVERFLOW_FLAG) | TA(OVERFLOW_FLAG) | IMM(1), OVERFLOW_FLAG));
                    179:                        }
                    180:                }
                    181:                else {
                    182:                        if (op & SLJIT_SET_O) {
                    183:                                FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
                    184:                                FAIL_IF(push_inst(compiler, SRL | TA(TMP_EREG1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
                    185:                                if (src1 != dst)
                    186:                                        overflow_ra = DR(src1);
                    187:                                else if (src2 != dst)
                    188:                                        overflow_ra = DR(src2);
                    189:                                else {
                    190:                                        /* Rare ocasion. */
                    191:                                        FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2));
                    192:                                        overflow_ra = TMP_EREG2;
                    193:                                }
                    194:                        }
                    195:                        if (op & SLJIT_SET_E)
                    196:                                FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
                    197:                        if (op & SLJIT_SET_C)
                    198:                                FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
                    199:                        /* dst may be the same as src1 or src2. */
                    200:                        if (CHECK_FLAGS(SLJIT_SET_E))
                    201:                                FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst)));
                    202:                        if (op & SLJIT_SET_O) {
                    203:                                FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(overflow_ra) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
                    204:                                FAIL_IF(push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
                    205:                        }
                    206:                }
                    207: 
                    208:                /* a + b >= a | b (otherwise, the carry should be set to 1). */
                    209:                if (op & SLJIT_SET_C)
                    210:                        FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
                    211:                if (op & SLJIT_SET_O)
                    212:                        return push_inst(compiler, MOVN | SA(0) | TA(TMP_EREG1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
                    213:                return SLJIT_SUCCESS;
                    214: 
                    215:        case SLJIT_ADDC:
                    216:                if (flags & SRC2_IMM) {
                    217:                        if (op & SLJIT_SET_C) {
                    218:                                if (src2 >= 0)
                    219:                                        FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1));
                    220:                                else {
                    221:                                        FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1));
                    222:                                        FAIL_IF(push_inst(compiler, OR | S(src1) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1));
                    223:                                }
                    224:                        }
                    225:                        FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst)));
                    226:                } else {
                    227:                        if (op & SLJIT_SET_C)
                    228:                                FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
                    229:                        /* dst may be the same as src1 or src2. */
                    230:                        FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst)));
                    231:                }
                    232:                if (op & SLJIT_SET_C)
                    233:                        FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1));
                    234: 
                    235:                FAIL_IF(push_inst(compiler, ADDU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
                    236:                if (!(op & SLJIT_SET_C))
                    237:                        return SLJIT_SUCCESS;
                    238: 
                    239:                /* Set TMP_EREG2 (dst == 0) && (ULESS_FLAG == 1). */
                    240:                FAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(TMP_EREG2) | IMM(1), TMP_EREG2));
                    241:                FAIL_IF(push_inst(compiler, AND | SA(TMP_EREG2) | TA(ULESS_FLAG) | DA(TMP_EREG2), TMP_EREG2));
                    242:                /* Set carry flag. */
                    243:                return push_inst(compiler, OR | SA(TMP_EREG2) | TA(TMP_EREG1) | DA(ULESS_FLAG), ULESS_FLAG);
                    244: 
                    245:        case SLJIT_SUB:
                    246:                if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_S | SLJIT_SET_U)) || src2 == SIMM_MIN)) {
                    247:                        FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
                    248:                        src2 = TMP_REG2;
                    249:                        flags &= ~SRC2_IMM;
                    250:                }
                    251: 
                    252:                if (flags & SRC2_IMM) {
                    253:                        if (op & SLJIT_SET_O) {
                    254:                                FAIL_IF(push_inst(compiler, SRL | T(src1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
                    255:                                if (src2 < 0)
                    256:                                        FAIL_IF(push_inst(compiler, XORI | SA(TMP_EREG1) | TA(TMP_EREG1) | IMM(1), TMP_EREG1));
                    257:                                if (src1 != dst)
                    258:                                        overflow_ra = DR(src1);
                    259:                                else {
                    260:                                        /* Rare ocasion. */
                    261:                                        FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2));
                    262:                                        overflow_ra = TMP_EREG2;
                    263:                                }
                    264:                        }
                    265:                        if (op & SLJIT_SET_E)
                    266:                                FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
                    267:                        if (op & SLJIT_SET_C)
                    268:                                FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
                    269:                        /* dst may be the same as src1 or src2. */
                    270:                        if (CHECK_FLAGS(SLJIT_SET_E))
                    271:                                FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst)));
                    272:                }
                    273:                else {
                    274:                        if (op & SLJIT_SET_O) {
                    275:                                FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
                    276:                                FAIL_IF(push_inst(compiler, SRL | TA(TMP_EREG1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
                    277:                                if (src1 != dst)
                    278:                                        overflow_ra = DR(src1);
                    279:                                else {
                    280:                                        /* Rare ocasion. */
                    281:                                        FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2));
                    282:                                        overflow_ra = TMP_EREG2;
                    283:                                }
                    284:                        }
                    285:                        if (op & SLJIT_SET_E)
                    286:                                FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
                    287:                        if (op & (SLJIT_SET_U | SLJIT_SET_C))
                    288:                                FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
                    289:                        if (op & SLJIT_SET_U)
                    290:                                FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG));
                    291:                        if (op & SLJIT_SET_S) {
                    292:                                FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG));
                    293:                                FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG));
                    294:                        }
                    295:                        /* dst may be the same as src1 or src2. */
                    296:                        if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))
                    297:                                FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst)));
                    298:                }
                    299: 
                    300:                if (op & SLJIT_SET_O) {
                    301:                        FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(overflow_ra) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
                    302:                        FAIL_IF(push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
                    303:                        return push_inst(compiler, MOVZ | SA(0) | TA(TMP_EREG1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
                    304:                }
                    305:                return SLJIT_SUCCESS;
                    306: 
                    307:        case SLJIT_SUBC:
                    308:                if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
                    309:                        FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
                    310:                        src2 = TMP_REG2;
                    311:                        flags &= ~SRC2_IMM;
                    312:                }
                    313: 
                    314:                if (flags & SRC2_IMM) {
                    315:                        if (op & SLJIT_SET_C)
                    316:                                FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(TMP_EREG1) | IMM(-src2), TMP_EREG1));
                    317:                        /* dst may be the same as src1 or src2. */
                    318:                        FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst)));
                    319:                }
                    320:                else {
                    321:                        if (op & SLJIT_SET_C)
                    322:                                FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
                    323:                        /* dst may be the same as src1 or src2. */
                    324:                        FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst)));
                    325:                }
                    326: 
                    327:                if (op & SLJIT_SET_C)
                    328:                        FAIL_IF(push_inst(compiler, MOVZ | SA(ULESS_FLAG) | T(dst) | DA(TMP_EREG1), TMP_EREG1));
                    329: 
                    330:                FAIL_IF(push_inst(compiler, SUBU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
                    331: 
                    332:                if (op & SLJIT_SET_C)
                    333:                        FAIL_IF(push_inst(compiler, ADDU | SA(TMP_EREG1) | TA(0) | DA(ULESS_FLAG), ULESS_FLAG));
                    334: 
                    335:                return SLJIT_SUCCESS;
                    336: 
                    337:        case SLJIT_MUL:
                    338:                SLJIT_ASSERT(!(flags & SRC2_IMM));
                    339:                if (!(op & SLJIT_SET_O)) {
                    340: #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
                    341:                        return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
                    342: #else
                    343:                        FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
                    344:                        return push_inst(compiler, MFLO | D(dst), DR(dst));
                    345: #endif
                    346:                }
                    347:                FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
                    348:                FAIL_IF(push_inst(compiler, MFHI | DA(TMP_EREG1), TMP_EREG1));
                    349:                FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
                    350:                FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(TMP_EREG2) | SH_IMM(31), TMP_EREG2));
                    351:                return push_inst(compiler, SUBU | SA(TMP_EREG1) | TA(TMP_EREG2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
                    352: 
                    353:        case SLJIT_AND:
                    354:                EMIT_LOGICAL(ANDI, AND);
                    355:                return SLJIT_SUCCESS;
                    356: 
                    357:        case SLJIT_OR:
                    358:                EMIT_LOGICAL(ORI, OR);
                    359:                return SLJIT_SUCCESS;
                    360: 
                    361:        case SLJIT_XOR:
                    362:                EMIT_LOGICAL(XORI, XOR);
                    363:                return SLJIT_SUCCESS;
                    364: 
                    365:        case SLJIT_SHL:
                    366:                EMIT_SHIFT(SLL, SLLV);
                    367:                return SLJIT_SUCCESS;
                    368: 
                    369:        case SLJIT_LSHR:
                    370:                EMIT_SHIFT(SRL, SRLV);
                    371:                return SLJIT_SUCCESS;
                    372: 
                    373:        case SLJIT_ASHR:
                    374:                EMIT_SHIFT(SRA, SRAV);
                    375:                return SLJIT_SUCCESS;
                    376:        }
                    377: 
                    378:        SLJIT_ASSERT_STOP();
                    379:        return SLJIT_SUCCESS;
                    380: }
                    381: 
1.1.1.3 ! misho     382: static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value)
1.1       misho     383: {
1.1.1.3 ! misho     384:        FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 16), DR(dst)));
        !           385:        return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
1.1       misho     386: }
                    387: 
                    388: SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
                    389: {
                    390:        sljit_ins *inst = (sljit_ins*)addr;
                    391: 
                    392:        inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
                    393:        inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff);
                    394:        SLJIT_CACHE_FLUSH(inst, inst + 2);
                    395: }
                    396: 
1.1.1.3 ! misho     397: SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
1.1       misho     398: {
                    399:        sljit_ins *inst = (sljit_ins*)addr;
                    400: 
                    401:        inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
                    402:        inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
                    403:        SLJIT_CACHE_FLUSH(inst, inst + 2);
                    404: }

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