File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / pcre / sljit / sljitNativeMIPS_32.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:05:52 2012 UTC (12 years, 4 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    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>