Home | History | Annotate | Line # | Download | only in sljit_src
sljitNativeMIPS_32.c revision 1.1.1.1
      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_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 }
    406