1f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* 2f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * Stack-less Just-In-Time compiler 3f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 4f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. 5f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 6f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * Redistribution and use in source and binary forms, with or without modification, are 7f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * permitted provided that the following conditions are met: 8f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 9f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 1. Redistributions of source code must retain the above copyright notice, this list of 10f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * conditions and the following disclaimer. 11f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 12f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 2. Redistributions in binary form must reproduce the above copyright notice, this list 13f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * of conditions and the following disclaimer in the documentation and/or other materials 14f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * provided with the distribution. 15f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * 16f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 17f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich */ 26f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 27f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich/* mips 64-bit arch dependent functions. */ 28f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 29f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm) 30f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 31f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_si shift = 32; 32f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_si shift2; 33f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_si inv = 0; 34f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_ins ins; 35f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_uw uimm; 36f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 37f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(imm & ~0xffff)) 38f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); 39f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 40f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (imm < 0 && imm >= SIMM_MIN) 41f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); 42f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 43f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (imm <= 0x7fffffffl && imm >= -0x80000000l) { 44f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar)); 45f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS; 46f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 47f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 48f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Zero extended number. */ 49f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich uimm = imm; 50f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (imm < 0) { 51f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich uimm = ~imm; 52f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inv = 1; 53f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 54f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 55f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich while (!(uimm & 0xff00000000000000l)) { 56f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich shift -= 8; 57f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich uimm <<= 8; 58f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 59f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 60f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(uimm & 0xf000000000000000l)) { 61f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich shift -= 4; 62f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich uimm <<= 4; 63f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 64f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 65f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(uimm & 0xc000000000000000l)) { 66f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich shift -= 2; 67f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich uimm <<= 2; 68f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 69f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 70f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((sljit_sw)uimm < 0) { 71f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich uimm >>= 1; 72f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich shift += 1; 73f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 74f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(((uimm & 0xc000000000000000l) == 0x4000000000000000l) && (shift > 0) && (shift <= 32)); 75f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 76f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (inv) 77f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich uimm = ~uimm; 78f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 79f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(uimm >> 48), dst_ar)); 80f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (uimm & 0x0000ffff00000000l) 81f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 32), dst_ar)); 82f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 83f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich imm &= (1l << shift) - 1; 84f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(imm & ~0xffff)) { 85f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ins = (shift == 32) ? DSLL32 : DSLL; 86f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (shift < 32) 87f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ins |= SH_IMM(shift); 88f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ins | TA(dst_ar) | DA(dst_ar), dst_ar)); 89f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar); 90f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 91f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 92f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Double shifts needs to be performed. */ 93f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich uimm <<= 32; 94f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich shift2 = shift - 16; 95f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 96f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich while (!(uimm & 0xf000000000000000l)) { 97f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich shift2 -= 4; 98f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich uimm <<= 4; 99f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 100f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 101f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(uimm & 0xc000000000000000l)) { 102f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich shift2 -= 2; 103f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich uimm <<= 2; 104f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 105f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 106f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(uimm & 0x8000000000000000l)) { 107f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich shift2--; 108f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich uimm <<= 1; 109f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 110f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 111f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT((uimm & 0x8000000000000000l) && (shift2 > 0) && (shift2 <= 16)); 112f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 113f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift - shift2), dst_ar)); 114f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 48), dst_ar)); 115f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift2), dst_ar)); 116f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 117f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich imm &= (1l << shift2) - 1; 118f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar); 119f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 120f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 121f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define SELECT_OP(a, b) \ 122f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich (!(op & SLJIT_INT_OP) ? a : b) 123f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 124f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define EMIT_LOGICAL(op_imm, op_norm) \ 125f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (flags & SRC2_IMM) { \ 126f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_E) \ 127f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \ 128f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (CHECK_FLAGS(SLJIT_SET_E)) \ 129f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \ 130f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } \ 131f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { \ 132f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_E) \ 133f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ 134f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (CHECK_FLAGS(SLJIT_SET_E)) \ 135f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \ 136f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 137f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 138f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#define EMIT_SHIFT(op_dimm, op_dimm32, op_imm, op_dv, op_v) \ 139f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (flags & SRC2_IMM) { \ 140f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src2 >= 32) { \ 141f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(!(op & SLJIT_INT_OP)); \ 142f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ins = op_dimm32; \ 143f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src2 -= 32; \ 144f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } \ 145f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else \ 146f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ins = (op & SLJIT_INT_OP) ? op_imm : op_dimm; \ 147f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_E) \ 148f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \ 149f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (CHECK_FLAGS(SLJIT_SET_E)) \ 150f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \ 151f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } \ 152f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { \ 153f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich ins = (op & SLJIT_INT_OP) ? op_v : op_dv; \ 154f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_E) \ 155f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ 156f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (CHECK_FLAGS(SLJIT_SET_E)) \ 157f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | D(dst), DR(dst))); \ 158f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 159f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 160f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, 161f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_si dst, sljit_si src1, sljit_sw src2) 162f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 163f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_ins ins; 164f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 165f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich switch (GET_OPCODE(op)) { 166f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MOV: 167f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MOV_P: 168f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); 169f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (dst != src2) 170f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(dst), DR(dst)); 171f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 172f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 173f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MOV_UB: 174f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MOV_SB: 175f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); 176f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { 177f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op == SLJIT_MOV_SB) { 178f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst))); 179f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst)); 180f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 181f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst)); 182f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 183f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else if (dst != src2) 184f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT_STOP(); 185f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 186f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 187f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MOV_UH: 188f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MOV_SH: 189f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); 190f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { 191f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op == SLJIT_MOV_SH) { 192f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst))); 193f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst)); 194f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 195f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst)); 196f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 197f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else if (dst != src2) 198f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT_STOP(); 199f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 200f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 201f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MOV_UI: 202f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(!(op & SLJIT_INT_OP)); 203f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst))); 204f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst)); 205f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 206f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MOV_SI: 207f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); 208f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst)); 209f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 210f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_NOT: 211f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); 212f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_E) 213f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); 214f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (CHECK_FLAGS(SLJIT_SET_E)) 215f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst))); 216f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 217f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 218f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_CLZ: 219f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); 220f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) 221f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_E) 222f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG)); 223f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (CHECK_FLAGS(SLJIT_SET_E)) 224f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | T(dst) | D(dst), DR(dst))); 225f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else 226f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) { 227f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG)); 228f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG); 229f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 230f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Nearly all instructions are unmovable in the following sequence. */ 231f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); 232f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Check zero. */ 233f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS)); 234f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM((op & SLJIT_INT_OP) ? 32 : 64), UNMOVABLE_INS)); 235f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(dst) | IMM(-1), DR(dst))); 236f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Loop for searching the highest bit. */ 237f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(dst) | IMM(1), DR(dst))); 238f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS)); 239f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DSLL, SLL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS)); 240f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_E) 241f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG); 242f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif 243f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 244f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 245f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_ADD: 246f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (flags & SRC2_IMM) { 247f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_O) { 248f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src2 >= 0) 249f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 250f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else 251f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 252f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 253f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_E) 254f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); 255f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & (SLJIT_SET_C | SLJIT_SET_O)) { 256f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src2 >= 0) 257f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); 258f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { 259f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); 260f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); 261f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 262f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 263f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* dst may be the same as src1 or src2. */ 264f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (CHECK_FLAGS(SLJIT_SET_E)) 265f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst))); 266f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 267f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { 268f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_O) 269f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 270f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_E) 271f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); 272f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & (SLJIT_SET_C | SLJIT_SET_O)) 273f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG)); 274f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* dst may be the same as src1 or src2. */ 275f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (CHECK_FLAGS(SLJIT_SET_E)) 276f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst))); 277f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 278f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 279f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* a + b >= a | b (otherwise, the carry should be set to 1). */ 280f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & (SLJIT_SET_C | SLJIT_SET_O)) 281f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); 282f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(op & SLJIT_SET_O)) 283f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 284f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1))); 285f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 286f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 287f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, SELECT_OP(DSRL32, SLL) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG); 288f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 289f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_ADDC: 290f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (flags & SRC2_IMM) { 291f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_C) { 292f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src2 >= 0) 293f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG)); 294f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { 295f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG)); 296f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, OR | S(src1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 297f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 298f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 299f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst))); 300f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } else { 301f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_C) 302f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 303f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* dst may be the same as src1 or src2. */ 304f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst))); 305f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 306f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_C) 307f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 308f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 309f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); 310f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(op & SLJIT_SET_C)) 311f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 312f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 313f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Set ULESS_FLAG (dst == 0) && (ULESS_FLAG == 1). */ 314f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); 315f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* Set carry flag. */ 316f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, OR | SA(ULESS_FLAG) | TA(OVERFLOW_FLAG) | DA(ULESS_FLAG), ULESS_FLAG); 317f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 318f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_SUB: 319f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_MIN)) { 320f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2))); 321f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src2 = TMP_REG2; 322f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags &= ~SRC2_IMM; 323f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 324f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 325f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (flags & SRC2_IMM) { 326f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_O) { 327f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (src2 >= 0) 328f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 329f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else 330f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 331f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 332f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_E) 333f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG)); 334f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & (SLJIT_SET_C | SLJIT_SET_O)) 335f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); 336f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* dst may be the same as src1 or src2. */ 337f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (CHECK_FLAGS(SLJIT_SET_E)) 338f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst))); 339f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 340f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { 341f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_O) 342f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 343f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_E) 344f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); 345f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & (SLJIT_SET_U | SLJIT_SET_C | SLJIT_SET_O)) 346f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG)); 347f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_U) 348f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG)); 349f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_S) { 350f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG)); 351f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG)); 352f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 353f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* dst may be the same as src1 or src2. */ 354f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C)) 355f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst))); 356f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 357f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 358f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(op & SLJIT_SET_O)) 359f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 360f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1))); 361f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 362f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 363f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, SELECT_OP(DSRL32, SRL) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG); 364f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 365f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_SUBC: 366f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if ((flags & SRC2_IMM) && src2 == SIMM_MIN) { 367f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2))); 368f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich src2 = TMP_REG2; 369f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich flags &= ~SRC2_IMM; 370f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 371f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 372f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (flags & SRC2_IMM) { 373f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_C) 374f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OVERFLOW_FLAG) | IMM(src2), OVERFLOW_FLAG)); 375f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* dst may be the same as src1 or src2. */ 376f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst))); 377f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 378f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich else { 379f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_C) 380f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); 381f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich /* dst may be the same as src1 or src2. */ 382f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst))); 383f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 384f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 385f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_SET_C) 386f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(LESS_FLAG), LESS_FLAG)); 387f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 388f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); 389f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(OVERFLOW_FLAG) | TA(LESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG) : SLJIT_SUCCESS; 390f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 391f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_MUL: 392f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT(!(flags & SRC2_IMM)); 393f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (!(op & SLJIT_SET_O)) { 394f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) 395f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich if (op & SLJIT_INT_OP) 396f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)); 397f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS)); 398f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, MFLO | D(dst), DR(dst)); 399f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#else 400f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS)); 401f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, MFLO | D(dst), DR(dst)); 402f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich#endif 403f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 404f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS)); 405f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, MFHI | DA(ULESS_FLAG), ULESS_FLAG)); 406f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst))); 407f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(UGREATER_FLAG) | SH_IMM(31), UGREATER_FLAG)); 408f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(ULESS_FLAG) | TA(UGREATER_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG); 409f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 410f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_AND: 411f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich EMIT_LOGICAL(ANDI, AND); 412f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 413f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 414f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_OR: 415f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich EMIT_LOGICAL(ORI, OR); 416f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 417f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 418f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_XOR: 419f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich EMIT_LOGICAL(XORI, XOR); 420f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 421f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 422f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_SHL: 423f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich EMIT_SHIFT(DSLL, DSLL32, SLL, DSLLV, SLLV); 424f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 425f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 426f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_LSHR: 427f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich EMIT_SHIFT(DSRL, DSRL32, SRL, DSRLV, SRLV); 428f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 429f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 430f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich case SLJIT_ASHR: 431f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich EMIT_SHIFT(DSRA, DSRA32, SRA, DSRAV, SRAV); 432f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 433f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich } 434f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 435f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_ASSERT_STOP(); 436f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return SLJIT_SUCCESS; 437f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 438f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 439f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevichstatic SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value) 440f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 441f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 48), DR(dst))); 442f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 32), DR(dst))); 443f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst))); 444f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 16), DR(dst))); 445f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst))); 446f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst)); 447f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 448f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 449f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichSLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) 450f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 451f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_ins *inst = (sljit_ins*)addr; 452f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 453f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff); 454f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff); 455f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff); 456f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inst[5] = (inst[5] & 0xffff0000) | (new_addr & 0xffff); 457f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_CACHE_FLUSH(inst, inst + 6); 458f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 459f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 460f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick KralevichSLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) 461f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich{ 462f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich sljit_ins *inst = (sljit_ins*)addr; 463f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich 464f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff); 465f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff); 466f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff); 467f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich inst[5] = (inst[5] & 0xffff0000) | (new_constant & 0xffff); 468f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich SLJIT_CACHE_FLUSH(inst, inst + 6); 469f73ff17bddb7dc18ff9044773dd65d040e8f4fcfNick Kralevich} 470