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

1.1       misho       1: /*
                      2:  *    Stack-less Just-In-Time compiler
                      3:  *
                      4:  *    Copyright 2009-2010 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
                      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: 
                     29: static int load_immediate(struct sljit_compiler *compiler, int dst_ar, sljit_w imm)
                     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: 
                     69: static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags,
                     70:        int dst, int src1, sljit_w src2)
                     71: {
                     72:        int overflow_ra = 0;
                     73: 
                     74:        switch (GET_OPCODE(op)) {
                     75:        case SLJIT_ADD:
                     76:                if (flags & SRC2_IMM) {
                     77:                        if (op & SLJIT_SET_O) {
                     78:                                FAIL_IF(push_inst(compiler, SRL | T(src1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
                     79:                                if (src2 < 0)
                     80:                                        FAIL_IF(push_inst(compiler, XORI | SA(TMP_EREG1) | TA(TMP_EREG1) | IMM(1), TMP_EREG1));
                     81:                        }
                     82:                        if (op & SLJIT_SET_E)
                     83:                                FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
                     84:                        if (op & SLJIT_SET_C) {
                     85:                                if (src2 >= 0)
                     86:                                        FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
                     87:                                else {
                     88:                                        FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
                     89:                                        FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
                     90:                                }
                     91:                        }
                     92:                        /* dst may be the same as src1 or src2. */
                     93:                        if (CHECK_FLAGS(SLJIT_SET_E))
                     94:                                FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst)));
                     95:                        if (op & SLJIT_SET_O) {
                     96:                                FAIL_IF(push_inst(compiler, SRL | T(dst) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
                     97:                                if (src2 < 0)
                     98:                                        FAIL_IF(push_inst(compiler, XORI | SA(OVERFLOW_FLAG) | TA(OVERFLOW_FLAG) | IMM(1), OVERFLOW_FLAG));
                     99:                        }
                    100:                }
                    101:                else {
                    102:                        if (op & SLJIT_SET_O) {
                    103:                                FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
                    104:                                FAIL_IF(push_inst(compiler, SRL | TA(TMP_EREG1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
                    105:                                if (src1 != dst)
                    106:                                        overflow_ra = DR(src1);
                    107:                                else if (src2 != dst)
                    108:                                        overflow_ra = DR(src2);
                    109:                                else {
                    110:                                        /* Rare ocasion. */
                    111:                                        FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2));
                    112:                                        overflow_ra = TMP_EREG2;
                    113:                                }
                    114:                        }
                    115:                        if (op & SLJIT_SET_E)
                    116:                                FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
                    117:                        if (op & SLJIT_SET_C)
                    118:                                FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
                    119:                        /* dst may be the same as src1 or src2. */
                    120:                        if (CHECK_FLAGS(SLJIT_SET_E))
                    121:                                FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst)));
                    122:                        if (op & SLJIT_SET_O) {
                    123:                                FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(overflow_ra) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
                    124:                                FAIL_IF(push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
                    125:                        }
                    126:                }
                    127: 
                    128:                /* a + b >= a | b (otherwise, the carry should be set to 1). */
                    129:                if (op & SLJIT_SET_C)
                    130:                        FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
                    131:                if (op & SLJIT_SET_O)
                    132:                        return push_inst(compiler, MOVN | SA(0) | TA(TMP_EREG1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
                    133:                return SLJIT_SUCCESS;
                    134: 
                    135:        case SLJIT_ADDC:
                    136:                if (flags & SRC2_IMM) {
                    137:                        if (op & SLJIT_SET_C) {
                    138:                                if (src2 >= 0)
                    139:                                        FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1));
                    140:                                else {
                    141:                                        FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1));
                    142:                                        FAIL_IF(push_inst(compiler, OR | S(src1) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1));
                    143:                                }
                    144:                        }
                    145:                        FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst)));
                    146:                } else {
                    147:                        if (op & SLJIT_SET_C)
                    148:                                FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
                    149:                        /* dst may be the same as src1 or src2. */
                    150:                        FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst)));
                    151:                }
                    152:                if (op & SLJIT_SET_C)
                    153:                        FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1));
                    154: 
                    155:                FAIL_IF(push_inst(compiler, ADDU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
                    156:                if (!(op & SLJIT_SET_C))
                    157:                        return SLJIT_SUCCESS;
                    158: 
                    159:                /* Set TMP_EREG2 (dst == 0) && (ULESS_FLAG == 1). */
                    160:                FAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(TMP_EREG2) | IMM(1), TMP_EREG2));
                    161:                FAIL_IF(push_inst(compiler, AND | SA(TMP_EREG2) | TA(ULESS_FLAG) | DA(TMP_EREG2), TMP_EREG2));
                    162:                /* Set carry flag. */
                    163:                return push_inst(compiler, OR | SA(TMP_EREG2) | TA(TMP_EREG1) | DA(ULESS_FLAG), ULESS_FLAG);
                    164: 
                    165:        case SLJIT_SUB:
                    166:                if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_S | SLJIT_SET_U)) || src2 == SIMM_MIN)) {
                    167:                        FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
                    168:                        src2 = TMP_REG2;
                    169:                        flags &= ~SRC2_IMM;
                    170:                }
                    171: 
                    172:                if (flags & SRC2_IMM) {
                    173:                        if (op & SLJIT_SET_O) {
                    174:                                FAIL_IF(push_inst(compiler, SRL | T(src1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
                    175:                                if (src2 < 0)
                    176:                                        FAIL_IF(push_inst(compiler, XORI | SA(TMP_EREG1) | TA(TMP_EREG1) | IMM(1), TMP_EREG1));
                    177:                                if (src1 != dst)
                    178:                                        overflow_ra = DR(src1);
                    179:                                else {
                    180:                                        /* Rare ocasion. */
                    181:                                        FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2));
                    182:                                        overflow_ra = TMP_EREG2;
                    183:                                }
                    184:                        }
                    185:                        if (op & SLJIT_SET_E)
                    186:                                FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
                    187:                        if (op & SLJIT_SET_C)
                    188:                                FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
                    189:                        /* dst may be the same as src1 or src2. */
                    190:                        if (CHECK_FLAGS(SLJIT_SET_E))
                    191:                                FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst)));
                    192:                }
                    193:                else {
                    194:                        if (op & SLJIT_SET_O) {
                    195:                                FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
                    196:                                FAIL_IF(push_inst(compiler, SRL | TA(TMP_EREG1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
                    197:                                if (src1 != dst)
                    198:                                        overflow_ra = DR(src1);
                    199:                                else {
                    200:                                        /* Rare ocasion. */
                    201:                                        FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2));
                    202:                                        overflow_ra = TMP_EREG2;
                    203:                                }
                    204:                        }
                    205:                        if (op & SLJIT_SET_E)
                    206:                                FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
                    207:                        if (op & (SLJIT_SET_U | SLJIT_SET_C))
                    208:                                FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
                    209:                        if (op & SLJIT_SET_U)
                    210:                                FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG));
                    211:                        if (op & SLJIT_SET_S) {
                    212:                                FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG));
                    213:                                FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG));
                    214:                        }
                    215:                        /* dst may be the same as src1 or src2. */
                    216:                        if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))
                    217:                                FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst)));
                    218:                }
                    219: 
                    220:                if (op & SLJIT_SET_O) {
                    221:                        FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(overflow_ra) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
                    222:                        FAIL_IF(push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
                    223:                        return push_inst(compiler, MOVZ | SA(0) | TA(TMP_EREG1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
                    224:                }
                    225:                return SLJIT_SUCCESS;
                    226: 
                    227:        case SLJIT_SUBC:
                    228:                if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
                    229:                        FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
                    230:                        src2 = TMP_REG2;
                    231:                        flags &= ~SRC2_IMM;
                    232:                }
                    233: 
                    234:                if (flags & SRC2_IMM) {
                    235:                        if (op & SLJIT_SET_C)
                    236:                                FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(TMP_EREG1) | IMM(-src2), TMP_EREG1));
                    237:                        /* dst may be the same as src1 or src2. */
                    238:                        FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst)));
                    239:                }
                    240:                else {
                    241:                        if (op & SLJIT_SET_C)
                    242:                                FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
                    243:                        /* dst may be the same as src1 or src2. */
                    244:                        FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst)));
                    245:                }
                    246: 
                    247:                if (op & SLJIT_SET_C)
                    248:                        FAIL_IF(push_inst(compiler, MOVZ | SA(ULESS_FLAG) | T(dst) | DA(TMP_EREG1), TMP_EREG1));
                    249: 
                    250:                FAIL_IF(push_inst(compiler, SUBU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
                    251: 
                    252:                if (op & SLJIT_SET_C)
                    253:                        FAIL_IF(push_inst(compiler, ADDU | SA(TMP_EREG1) | TA(0) | DA(ULESS_FLAG), ULESS_FLAG));
                    254: 
                    255:                return SLJIT_SUCCESS;
                    256: 
                    257:        case SLJIT_MUL:
                    258:                SLJIT_ASSERT(!(flags & SRC2_IMM));
                    259:                if (!(op & SLJIT_SET_O)) {
                    260: #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
                    261:                        return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
                    262: #else
                    263:                        FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
                    264:                        return push_inst(compiler, MFLO | D(dst), DR(dst));
                    265: #endif
                    266:                }
                    267:                FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
                    268:                FAIL_IF(push_inst(compiler, MFHI | DA(TMP_EREG1), TMP_EREG1));
                    269:                FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
                    270:                FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(TMP_EREG2) | SH_IMM(31), TMP_EREG2));
                    271:                return push_inst(compiler, SUBU | SA(TMP_EREG1) | TA(TMP_EREG2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
                    272: 
                    273:        case SLJIT_AND:
                    274:                EMIT_LOGICAL(ANDI, AND);
                    275:                return SLJIT_SUCCESS;
                    276: 
                    277:        case SLJIT_OR:
                    278:                EMIT_LOGICAL(ORI, OR);
                    279:                return SLJIT_SUCCESS;
                    280: 
                    281:        case SLJIT_XOR:
                    282:                EMIT_LOGICAL(XORI, XOR);
                    283:                return SLJIT_SUCCESS;
                    284: 
                    285:        case SLJIT_SHL:
                    286:                EMIT_SHIFT(SLL, SLLV);
                    287:                return SLJIT_SUCCESS;
                    288: 
                    289:        case SLJIT_LSHR:
                    290:                EMIT_SHIFT(SRL, SRLV);
                    291:                return SLJIT_SUCCESS;
                    292: 
                    293:        case SLJIT_ASHR:
                    294:                EMIT_SHIFT(SRA, SRAV);
                    295:                return SLJIT_SUCCESS;
                    296: 
                    297:        case SLJIT_MOV:
                    298:        case SLJIT_MOV_UI:
                    299:        case SLJIT_MOV_SI:
                    300:                SLJIT_ASSERT(src1 == TMP_REG1);
                    301:                if (dst != src2)
                    302:                        return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst));
                    303:                return SLJIT_SUCCESS;
                    304: 
                    305:        case SLJIT_MOV_UB:
                    306:        case SLJIT_MOV_SB:
                    307:                SLJIT_ASSERT(src1 == TMP_REG1);
                    308:                if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
                    309:                        if (op == SLJIT_MOV_SB) {
                    310: #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
                    311:                                return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
                    312: #else
                    313:                                FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
                    314:                                return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));
                    315: #endif
                    316:                        }
                    317:                        return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
                    318:                }
                    319:                else if (dst != src2)
                    320:                        SLJIT_ASSERT_STOP();
                    321:                return SLJIT_SUCCESS;
                    322: 
                    323:        case SLJIT_MOV_UH:
                    324:        case SLJIT_MOV_SH:
                    325:                SLJIT_ASSERT(src1 == TMP_REG1);
                    326:                if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
                    327:                        if (op == SLJIT_MOV_SH) {
                    328: #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
                    329:                                return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
                    330: #else
                    331:                                FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
                    332:                                return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));
                    333: #endif
                    334:                        }
                    335:                        return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
                    336:                }
                    337:                else if (dst != src2)
                    338:                        SLJIT_ASSERT_STOP();
                    339:                return SLJIT_SUCCESS;
                    340: 
                    341:        case SLJIT_NOT:
                    342:                SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
                    343:                if (op & SLJIT_SET_E)
                    344:                        FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
                    345:                if (CHECK_FLAGS(SLJIT_SET_E))
                    346:                        FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst)));
                    347:                return SLJIT_SUCCESS;
                    348: 
                    349:        case SLJIT_CLZ:
                    350:                SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
                    351: #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
                    352:                if (op & SLJIT_SET_E)
                    353:                        FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
                    354:                if (CHECK_FLAGS(SLJIT_SET_E))
                    355:                        FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst)));
                    356: #else
                    357:                if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) {
                    358:                        FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG));
                    359:                        return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG);
                    360:                }
                    361:                /* Nearly all instructions are unmovable in the following sequence. */
                    362:                FAIL_IF(push_inst(compiler, ADDU_W | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
                    363:                /* Check zero. */
                    364:                FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(6), UNMOVABLE_INS));
                    365:                FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS));
                    366:                /* Check sign bit. */
                    367:                FAIL_IF(push_inst(compiler, BLTZ | S(TMP_REG1) | IMM(4), UNMOVABLE_INS));
                    368:                FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(0), UNMOVABLE_INS));
                    369:                /* Loop for searching the highest bit. */
                    370:                FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1)));
                    371:                FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS));
                    372:                FAIL_IF(push_inst(compiler, ADDIU_W | S(dst) | T(dst) | IMM(1), UNMOVABLE_INS));
                    373:                if (op & SLJIT_SET_E)
                    374:                        return push_inst(compiler, ADDU_W | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG);
                    375: #endif
                    376:                return SLJIT_SUCCESS;
                    377:        }
                    378: 
                    379:        SLJIT_ASSERT_STOP();
                    380:        return SLJIT_SUCCESS;
                    381: }
                    382: 
                    383: static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value)
                    384: {
                    385:        FAIL_IF(push_inst(compiler, LUI | T(reg) | IMM(init_value >> 16), DR(reg)));
                    386:        return push_inst(compiler, ORI | S(reg) | T(reg) | IMM(init_value), DR(reg));
                    387: }
                    388: 
                    389: SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
                    390: {
                    391:        sljit_ins *inst = (sljit_ins*)addr;
                    392: 
                    393:        inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
                    394:        inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff);
                    395:        SLJIT_CACHE_FLUSH(inst, inst + 2);
                    396: }
                    397: 
                    398: SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
                    399: {
                    400:        sljit_ins *inst = (sljit_ins*)addr;
                    401: 
                    402:        inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
                    403:        inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
                    404:        SLJIT_CACHE_FLUSH(inst, inst + 2);
                    405: }

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