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