File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / pcre / sljit / sljitNativeMIPS_32.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 08:25:57 2013 UTC (10 years, 11 months ago) by misho
Branches: pcre, MAIN
CVS tags: v8_34, v8_33, HEAD
8.33

    1: /*
    2:  *    Stack-less Just-In-Time compiler
    3:  *
    4:  *    Copyright 2009-2012 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 sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw 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 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)
   71: {
   72: 	sljit_si overflow_ra = 0;
   73: 
   74: 	switch (GET_OPCODE(op)) {
   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: 
  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: 
  382: static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value)
  383: {
  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));
  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: 
  397: SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
  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>