Annotation of embedaddon/pcre/sljit/sljitNativeMIPS_32.c, revision 1.1.1.1
1.1 misho 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>