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 
sljit_get_platform_name(void)27 SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void)
28 {
29 	return "SPARC" SLJIT_CPUINFO;
30 }
31 
32 /* Length of an instruction word
33    Both for sparc-32 and sparc-64 */
34 typedef sljit_ui sljit_ins;
35 
sparc_cache_flush(sljit_ins * from,sljit_ins * to)36 static void sparc_cache_flush(sljit_ins *from, sljit_ins *to)
37 {
38 #if defined(__SUNPRO_C) && __SUNPRO_C < 0x590
39 	__asm (
40 		/* if (from == to) return */
41 		"cmp %i0, %i1\n"
42 		"be .leave\n"
43 		"nop\n"
44 
45 		/* loop until from >= to */
46 		".mainloop:\n"
47 		"flush %i0\n"
48 		"add %i0, 8, %i0\n"
49 		"cmp %i0, %i1\n"
50 		"bcs .mainloop\n"
51 		"nop\n"
52 
53 		/* The comparison was done above. */
54 		"bne .leave\n"
55 		/* nop is not necessary here, since the
56 		   sub operation has no side effect. */
57 		"sub %i0, 4, %i0\n"
58 		"flush %i0\n"
59 		".leave:"
60 	);
61 #else
62 	if (SLJIT_UNLIKELY(from == to))
63 		return;
64 
65 	do {
66 		__asm__ volatile (
67 			"flush %0\n"
68 			: : "r"(from)
69 		);
70 		/* Operates at least on doubleword. */
71 		from += 2;
72 	} while (from < to);
73 
74 	if (from == to) {
75 		/* Flush the last word. */
76 		from --;
77 		__asm__ volatile (
78 			"flush %0\n"
79 			: : "r"(from)
80 		);
81 	}
82 #endif
83 }
84 
85 /* TMP_REG2 is not used by getput_arg */
86 #define TMP_REG1	(SLJIT_NUMBER_OF_REGISTERS + 2)
87 #define TMP_REG2	(SLJIT_NUMBER_OF_REGISTERS + 3)
88 #define TMP_REG3	(SLJIT_NUMBER_OF_REGISTERS + 4)
89 #define TMP_LINK	(SLJIT_NUMBER_OF_REGISTERS + 5)
90 
91 #define TMP_FREG1	(0)
92 #define TMP_FREG2	((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) << 1)
93 
94 static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
95 	0, 8, 9, 10, 13, 29, 28, 27, 23, 22, 21, 20, 19, 18, 17, 16, 26, 25, 24, 14, 1, 11, 12, 15
96 };
97 
98 /* --------------------------------------------------------------------- */
99 /*  Instrucion forms                                                     */
100 /* --------------------------------------------------------------------- */
101 
102 #define D(d)		(reg_map[d] << 25)
103 #define DA(d)		((d) << 25)
104 #define S1(s1)		(reg_map[s1] << 14)
105 #define S2(s2)		(reg_map[s2])
106 #define S1A(s1)		((s1) << 14)
107 #define S2A(s2)		(s2)
108 #define IMM_ARG		0x2000
109 #define DOP(op)		((op) << 5)
110 #define IMM(imm)	(((imm) & 0x1fff) | IMM_ARG)
111 
112 #define DR(dr)		(reg_map[dr])
113 #define OPC1(opcode)	((opcode) << 30)
114 #define OPC2(opcode)	((opcode) << 22)
115 #define OPC3(opcode)	((opcode) << 19)
116 #define SET_FLAGS	OPC3(0x10)
117 
118 #define ADD		(OPC1(0x2) | OPC3(0x00))
119 #define ADDC		(OPC1(0x2) | OPC3(0x08))
120 #define AND		(OPC1(0x2) | OPC3(0x01))
121 #define ANDN		(OPC1(0x2) | OPC3(0x05))
122 #define CALL		(OPC1(0x1))
123 #define FABSS		(OPC1(0x2) | OPC3(0x34) | DOP(0x09))
124 #define FADDD		(OPC1(0x2) | OPC3(0x34) | DOP(0x42))
125 #define FADDS		(OPC1(0x2) | OPC3(0x34) | DOP(0x41))
126 #define FCMPD		(OPC1(0x2) | OPC3(0x35) | DOP(0x52))
127 #define FCMPS		(OPC1(0x2) | OPC3(0x35) | DOP(0x51))
128 #define FDIVD		(OPC1(0x2) | OPC3(0x34) | DOP(0x4e))
129 #define FDIVS		(OPC1(0x2) | OPC3(0x34) | DOP(0x4d))
130 #define FDTOI		(OPC1(0x2) | OPC3(0x34) | DOP(0xd2))
131 #define FDTOS		(OPC1(0x2) | OPC3(0x34) | DOP(0xc6))
132 #define FITOD		(OPC1(0x2) | OPC3(0x34) | DOP(0xc8))
133 #define FITOS		(OPC1(0x2) | OPC3(0x34) | DOP(0xc4))
134 #define FMOVS		(OPC1(0x2) | OPC3(0x34) | DOP(0x01))
135 #define FMULD		(OPC1(0x2) | OPC3(0x34) | DOP(0x4a))
136 #define FMULS		(OPC1(0x2) | OPC3(0x34) | DOP(0x49))
137 #define FNEGS		(OPC1(0x2) | OPC3(0x34) | DOP(0x05))
138 #define FSTOD		(OPC1(0x2) | OPC3(0x34) | DOP(0xc9))
139 #define FSTOI		(OPC1(0x2) | OPC3(0x34) | DOP(0xd1))
140 #define FSUBD		(OPC1(0x2) | OPC3(0x34) | DOP(0x46))
141 #define FSUBS		(OPC1(0x2) | OPC3(0x34) | DOP(0x45))
142 #define JMPL		(OPC1(0x2) | OPC3(0x38))
143 #define NOP		(OPC1(0x0) | OPC2(0x04))
144 #define OR		(OPC1(0x2) | OPC3(0x02))
145 #define ORN		(OPC1(0x2) | OPC3(0x06))
146 #define RDY		(OPC1(0x2) | OPC3(0x28) | S1A(0))
147 #define RESTORE		(OPC1(0x2) | OPC3(0x3d))
148 #define SAVE		(OPC1(0x2) | OPC3(0x3c))
149 #define SETHI		(OPC1(0x0) | OPC2(0x04))
150 #define SLL		(OPC1(0x2) | OPC3(0x25))
151 #define SLLX		(OPC1(0x2) | OPC3(0x25) | (1 << 12))
152 #define SRA		(OPC1(0x2) | OPC3(0x27))
153 #define SRAX		(OPC1(0x2) | OPC3(0x27) | (1 << 12))
154 #define SRL		(OPC1(0x2) | OPC3(0x26))
155 #define SRLX		(OPC1(0x2) | OPC3(0x26) | (1 << 12))
156 #define SUB		(OPC1(0x2) | OPC3(0x04))
157 #define SUBC		(OPC1(0x2) | OPC3(0x0c))
158 #define TA		(OPC1(0x2) | OPC3(0x3a) | (8 << 25))
159 #define WRY		(OPC1(0x2) | OPC3(0x30) | DA(0))
160 #define XOR		(OPC1(0x2) | OPC3(0x03))
161 #define XNOR		(OPC1(0x2) | OPC3(0x07))
162 
163 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
164 #define MAX_DISP	(0x1fffff)
165 #define MIN_DISP	(-0x200000)
166 #define DISP_MASK	(0x3fffff)
167 
168 #define BICC		(OPC1(0x0) | OPC2(0x2))
169 #define FBFCC		(OPC1(0x0) | OPC2(0x6))
170 #define SLL_W		SLL
171 #define SDIV		(OPC1(0x2) | OPC3(0x0f))
172 #define SMUL		(OPC1(0x2) | OPC3(0x0b))
173 #define UDIV		(OPC1(0x2) | OPC3(0x0e))
174 #define UMUL		(OPC1(0x2) | OPC3(0x0a))
175 #else
176 #define SLL_W		SLLX
177 #endif
178 
179 #define SIMM_MAX	(0x0fff)
180 #define SIMM_MIN	(-0x1000)
181 
182 /* dest_reg is the absolute name of the register
183    Useful for reordering instructions in the delay slot. */
push_inst(struct sljit_compiler * compiler,sljit_ins ins,sljit_si delay_slot)184 static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_si delay_slot)
185 {
186 	sljit_ins *ptr;
187 	SLJIT_ASSERT((delay_slot & DST_INS_MASK) == UNMOVABLE_INS
188 		|| (delay_slot & DST_INS_MASK) == MOVABLE_INS
189 		|| (delay_slot & DST_INS_MASK) == ((ins >> 25) & 0x1f));
190 	ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
191 	FAIL_IF(!ptr);
192 	*ptr = ins;
193 	compiler->size++;
194 	compiler->delay_slot = delay_slot;
195 	return SLJIT_SUCCESS;
196 }
197 
detect_jump_type(struct sljit_jump * jump,sljit_ins * code_ptr,sljit_ins * code)198 static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
199 {
200 	sljit_sw diff;
201 	sljit_uw target_addr;
202 	sljit_ins *inst;
203 	sljit_ins saved_inst;
204 
205 	if (jump->flags & SLJIT_REWRITABLE_JUMP)
206 		return code_ptr;
207 
208 	if (jump->flags & JUMP_ADDR)
209 		target_addr = jump->u.target;
210 	else {
211 		SLJIT_ASSERT(jump->flags & JUMP_LABEL);
212 		target_addr = (sljit_uw)(code + jump->u.label->size);
213 	}
214 	inst = (sljit_ins*)jump->addr;
215 
216 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
217 	if (jump->flags & IS_CALL) {
218 		/* Call is always patchable on sparc 32. */
219 		jump->flags |= PATCH_CALL;
220 		if (jump->flags & IS_MOVABLE) {
221 			inst[0] = inst[-1];
222 			inst[-1] = CALL;
223 			jump->addr -= sizeof(sljit_ins);
224 			return inst;
225 		}
226 		inst[0] = CALL;
227 		inst[1] = NOP;
228 		return inst + 1;
229 	}
230 #else
231 	/* Both calls and BPr instructions shall not pass this point. */
232 #error "Implementation required"
233 #endif
234 
235 	if (jump->flags & IS_COND)
236 		inst--;
237 
238 	if (jump->flags & IS_MOVABLE) {
239 		diff = ((sljit_sw)target_addr - (sljit_sw)(inst - 1)) >> 2;
240 		if (diff <= MAX_DISP && diff >= MIN_DISP) {
241 			jump->flags |= PATCH_B;
242 			inst--;
243 			if (jump->flags & IS_COND) {
244 				saved_inst = inst[0];
245 				inst[0] = inst[1] ^ (1 << 28);
246 				inst[1] = saved_inst;
247 			} else {
248 				inst[1] = inst[0];
249 				inst[0] = BICC | DA(0x8);
250 			}
251 			jump->addr = (sljit_uw)inst;
252 			return inst + 1;
253 		}
254 	}
255 
256 	diff = ((sljit_sw)target_addr - (sljit_sw)(inst)) >> 2;
257 	if (diff <= MAX_DISP && diff >= MIN_DISP) {
258 		jump->flags |= PATCH_B;
259 		if (jump->flags & IS_COND)
260 			inst[0] ^= (1 << 28);
261 		else
262 			inst[0] = BICC | DA(0x8);
263 		inst[1] = NOP;
264 		jump->addr = (sljit_uw)inst;
265 		return inst + 1;
266 	}
267 
268 	return code_ptr;
269 }
270 
sljit_generate_code(struct sljit_compiler * compiler)271 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
272 {
273 	struct sljit_memory_fragment *buf;
274 	sljit_ins *code;
275 	sljit_ins *code_ptr;
276 	sljit_ins *buf_ptr;
277 	sljit_ins *buf_end;
278 	sljit_uw word_count;
279 	sljit_uw addr;
280 
281 	struct sljit_label *label;
282 	struct sljit_jump *jump;
283 	struct sljit_const *const_;
284 
285 	CHECK_ERROR_PTR();
286 	check_sljit_generate_code(compiler);
287 	reverse_buf(compiler);
288 
289 	code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
290 	PTR_FAIL_WITH_EXEC_IF(code);
291 	buf = compiler->buf;
292 
293 	code_ptr = code;
294 	word_count = 0;
295 	label = compiler->labels;
296 	jump = compiler->jumps;
297 	const_ = compiler->consts;
298 	do {
299 		buf_ptr = (sljit_ins*)buf->memory;
300 		buf_end = buf_ptr + (buf->used_size >> 2);
301 		do {
302 			*code_ptr = *buf_ptr++;
303 			SLJIT_ASSERT(!label || label->size >= word_count);
304 			SLJIT_ASSERT(!jump || jump->addr >= word_count);
305 			SLJIT_ASSERT(!const_ || const_->addr >= word_count);
306 			/* These structures are ordered by their address. */
307 			if (label && label->size == word_count) {
308 				/* Just recording the address. */
309 				label->addr = (sljit_uw)code_ptr;
310 				label->size = code_ptr - code;
311 				label = label->next;
312 			}
313 			if (jump && jump->addr == word_count) {
314 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
315 				jump->addr = (sljit_uw)(code_ptr - 3);
316 #else
317 				jump->addr = (sljit_uw)(code_ptr - 6);
318 #endif
319 				code_ptr = detect_jump_type(jump, code_ptr, code);
320 				jump = jump->next;
321 			}
322 			if (const_ && const_->addr == word_count) {
323 				/* Just recording the address. */
324 				const_->addr = (sljit_uw)code_ptr;
325 				const_ = const_->next;
326 			}
327 			code_ptr ++;
328 			word_count ++;
329 		} while (buf_ptr < buf_end);
330 
331 		buf = buf->next;
332 	} while (buf);
333 
334 	if (label && label->size == word_count) {
335 		label->addr = (sljit_uw)code_ptr;
336 		label->size = code_ptr - code;
337 		label = label->next;
338 	}
339 
340 	SLJIT_ASSERT(!label);
341 	SLJIT_ASSERT(!jump);
342 	SLJIT_ASSERT(!const_);
343 	SLJIT_ASSERT(code_ptr - code <= (sljit_si)compiler->size);
344 
345 	jump = compiler->jumps;
346 	while (jump) {
347 		do {
348 			addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
349 			buf_ptr = (sljit_ins*)jump->addr;
350 
351 			if (jump->flags & PATCH_CALL) {
352 				addr = (sljit_sw)(addr - jump->addr) >> 2;
353 				SLJIT_ASSERT((sljit_sw)addr <= 0x1fffffff && (sljit_sw)addr >= -0x20000000);
354 				buf_ptr[0] = CALL | (addr & 0x3fffffff);
355 				break;
356 			}
357 			if (jump->flags & PATCH_B) {
358 				addr = (sljit_sw)(addr - jump->addr) >> 2;
359 				SLJIT_ASSERT((sljit_sw)addr <= MAX_DISP && (sljit_sw)addr >= MIN_DISP);
360 				buf_ptr[0] = (buf_ptr[0] & ~DISP_MASK) | (addr & DISP_MASK);
361 				break;
362 			}
363 
364 			/* Set the fields of immediate loads. */
365 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
366 			buf_ptr[0] = (buf_ptr[0] & 0xffc00000) | ((addr >> 10) & 0x3fffff);
367 			buf_ptr[1] = (buf_ptr[1] & 0xfffffc00) | (addr & 0x3ff);
368 #else
369 #error "Implementation required"
370 #endif
371 		} while (0);
372 		jump = jump->next;
373 	}
374 
375 
376 	compiler->error = SLJIT_ERR_COMPILED;
377 	compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
378 	SLJIT_CACHE_FLUSH(code, code_ptr);
379 	return code;
380 }
381 
382 /* --------------------------------------------------------------------- */
383 /*  Entry, exit                                                          */
384 /* --------------------------------------------------------------------- */
385 
386 /* Creates an index in data_transfer_insts array. */
387 #define LOAD_DATA	0x01
388 #define WORD_DATA	0x00
389 #define BYTE_DATA	0x02
390 #define HALF_DATA	0x04
391 #define INT_DATA	0x06
392 #define SIGNED_DATA	0x08
393 /* Separates integer and floating point registers */
394 #define GPR_REG		0x0f
395 #define DOUBLE_DATA	0x10
396 #define SINGLE_DATA	0x12
397 
398 #define MEM_MASK	0x1f
399 
400 #define WRITE_BACK	0x00020
401 #define ARG_TEST	0x00040
402 #define ALT_KEEP_CACHE	0x00080
403 #define CUMULATIVE_OP	0x00100
404 #define IMM_OP		0x00200
405 #define SRC2_IMM	0x00400
406 
407 #define REG_DEST	0x00800
408 #define REG2_SOURCE	0x01000
409 #define SLOW_SRC1	0x02000
410 #define SLOW_SRC2	0x04000
411 #define SLOW_DEST	0x08000
412 
413 /* SET_FLAGS (0x10 << 19) also belong here! */
414 
415 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
416 #include "sljitNativeSPARC_32.c"
417 #else
418 #include "sljitNativeSPARC_64.c"
419 #endif
420 
sljit_emit_enter(struct sljit_compiler * compiler,sljit_si options,sljit_si args,sljit_si scratches,sljit_si saveds,sljit_si fscratches,sljit_si fsaveds,sljit_si local_size)421 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
422 	sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
423 	sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
424 {
425 	CHECK_ERROR();
426 	check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
427 
428 	compiler->options = options;
429 	compiler->scratches = scratches;
430 	compiler->saveds = saveds;
431 	compiler->fscratches = fscratches;
432 	compiler->fsaveds = fsaveds;
433 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
434 	compiler->logical_local_size = local_size;
435 #endif
436 
437 	local_size = (local_size + FIXED_LOCALS_OFFSET + 7) & ~0x7;
438 	compiler->local_size = local_size;
439 
440 	if (local_size <= SIMM_MAX) {
441 		FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_SP) | S1(SLJIT_SP) | IMM(-local_size), UNMOVABLE_INS));
442 	}
443 	else {
444 		FAIL_IF(load_immediate(compiler, TMP_REG1, -local_size));
445 		FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_SP) | S1(SLJIT_SP) | S2(TMP_REG1), UNMOVABLE_INS));
446 	}
447 
448 	/* Arguments are in their appropriate registers. */
449 
450 	return SLJIT_SUCCESS;
451 }
452 
sljit_set_context(struct sljit_compiler * compiler,sljit_si options,sljit_si args,sljit_si scratches,sljit_si saveds,sljit_si fscratches,sljit_si fsaveds,sljit_si local_size)453 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler,
454 	sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
455 	sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
456 {
457 	CHECK_ERROR_VOID();
458 	check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
459 
460 	compiler->options = options;
461 	compiler->scratches = scratches;
462 	compiler->saveds = saveds;
463 	compiler->fscratches = fscratches;
464 	compiler->fsaveds = fsaveds;
465 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
466 	compiler->logical_local_size = local_size;
467 #endif
468 
469 	compiler->local_size = (local_size + FIXED_LOCALS_OFFSET + 7) & ~0x7;
470 }
471 
sljit_emit_return(struct sljit_compiler * compiler,sljit_si op,sljit_si src,sljit_sw srcw)472 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
473 {
474 	CHECK_ERROR();
475 	check_sljit_emit_return(compiler, op, src, srcw);
476 
477 	if (op != SLJIT_MOV || !FAST_IS_REG(src)) {
478 		FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
479 		src = SLJIT_R0;
480 	}
481 
482 	FAIL_IF(push_inst(compiler, JMPL | D(0) | S1A(31) | IMM(8), UNMOVABLE_INS));
483 	return push_inst(compiler, RESTORE | D(SLJIT_R0) | S1(src) | S2(0), UNMOVABLE_INS);
484 }
485 
486 /* --------------------------------------------------------------------- */
487 /*  Operators                                                            */
488 /* --------------------------------------------------------------------- */
489 
490 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
491 #define ARCH_32_64(a, b)	a
492 #else
493 #define ARCH_32_64(a, b)	b
494 #endif
495 
496 static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = {
497 /* u w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */),
498 /* u w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */),
499 /* u b s */ OPC1(3) | OPC3(0x05) /* stb */,
500 /* u b l */ OPC1(3) | OPC3(0x01) /* ldub */,
501 /* u h s */ OPC1(3) | OPC3(0x06) /* sth */,
502 /* u h l */ OPC1(3) | OPC3(0x02) /* lduh */,
503 /* u i s */ OPC1(3) | OPC3(0x04) /* stw */,
504 /* u i l */ OPC1(3) | OPC3(0x00) /* lduw */,
505 
506 /* s w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */),
507 /* s w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */),
508 /* s b s */ OPC1(3) | OPC3(0x05) /* stb */,
509 /* s b l */ OPC1(3) | OPC3(0x09) /* ldsb */,
510 /* s h s */ OPC1(3) | OPC3(0x06) /* sth */,
511 /* s h l */ OPC1(3) | OPC3(0x0a) /* ldsh */,
512 /* s i s */ OPC1(3) | OPC3(0x04) /* stw */,
513 /* s i l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x08) /* ldsw */),
514 
515 /* d   s */ OPC1(3) | OPC3(0x27),
516 /* d   l */ OPC1(3) | OPC3(0x23),
517 /* s   s */ OPC1(3) | OPC3(0x24),
518 /* s   l */ OPC1(3) | OPC3(0x20),
519 };
520 
521 #undef ARCH_32_64
522 
523 /* Can perform an operation using at most 1 instruction. */
getput_arg_fast(struct sljit_compiler * compiler,sljit_si flags,sljit_si reg,sljit_si arg,sljit_sw argw)524 static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
525 {
526 	SLJIT_ASSERT(arg & SLJIT_MEM);
527 
528 	if (!(flags & WRITE_BACK) || !(arg & REG_MASK)) {
529 		if ((!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN)
530 				|| ((arg & OFFS_REG_MASK) && (argw & 0x3) == 0)) {
531 			/* Works for both absoulte and relative addresses (immediate case). */
532 			if (SLJIT_UNLIKELY(flags & ARG_TEST))
533 				return 1;
534 			FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK]
535 				| ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg))
536 				| S1(arg & REG_MASK) | ((arg & OFFS_REG_MASK) ? S2(OFFS_REG(arg)) : IMM(argw)),
537 				((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS));
538 			return -1;
539 		}
540 	}
541 	return 0;
542 }
543 
544 /* See getput_arg below.
545    Note: can_cache is called only for binary operators. Those
546    operators always uses word arguments without write back. */
can_cache(sljit_si arg,sljit_sw argw,sljit_si next_arg,sljit_sw next_argw)547 static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
548 {
549 	SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
550 
551 	/* Simple operation except for updates. */
552 	if (arg & OFFS_REG_MASK) {
553 		argw &= 0x3;
554 		SLJIT_ASSERT(argw);
555 		next_argw &= 0x3;
556 		if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == next_argw)
557 			return 1;
558 		return 0;
559 	}
560 
561 	if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN))
562 		return 1;
563 	return 0;
564 }
565 
566 /* Emit the necessary instructions. See can_cache above. */
getput_arg(struct sljit_compiler * compiler,sljit_si flags,sljit_si reg,sljit_si arg,sljit_sw argw,sljit_si next_arg,sljit_sw next_argw)567 static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
568 {
569 	sljit_si base, arg2, delay_slot;
570 	sljit_ins dest;
571 
572 	SLJIT_ASSERT(arg & SLJIT_MEM);
573 	if (!(next_arg & SLJIT_MEM)) {
574 		next_arg = 0;
575 		next_argw = 0;
576 	}
577 
578 	base = arg & REG_MASK;
579 	if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
580 		argw &= 0x3;
581 		SLJIT_ASSERT(argw != 0);
582 
583 		/* Using the cache. */
584 		if (((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) && (argw == compiler->cache_argw))
585 			arg2 = TMP_REG3;
586 		else {
587 			if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == (next_argw & 0x3)) {
588 				compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
589 				compiler->cache_argw = argw;
590 				arg2 = TMP_REG3;
591 			}
592 			else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base && reg != OFFS_REG(arg))
593 				arg2 = reg;
594 			else /* It must be a mov operation, so tmp1 must be free to use. */
595 				arg2 = TMP_REG1;
596 			FAIL_IF(push_inst(compiler, SLL_W | D(arg2) | S1(OFFS_REG(arg)) | IMM_ARG | argw, DR(arg2)));
597 		}
598 	}
599 	else {
600 		/* Using the cache. */
601 		if ((compiler->cache_arg == SLJIT_MEM) && (argw - compiler->cache_argw) <= SIMM_MAX && (argw - compiler->cache_argw) >= SIMM_MIN) {
602 			if (argw != compiler->cache_argw) {
603 				FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | S1(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
604 				compiler->cache_argw = argw;
605 			}
606 			arg2 = TMP_REG3;
607 		} else {
608 			if ((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN) {
609 				compiler->cache_arg = SLJIT_MEM;
610 				compiler->cache_argw = argw;
611 				arg2 = TMP_REG3;
612 			}
613 			else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base)
614 				arg2 = reg;
615 			else /* It must be a mov operation, so tmp1 must be free to use. */
616 				arg2 = TMP_REG1;
617 			FAIL_IF(load_immediate(compiler, arg2, argw));
618 		}
619 	}
620 
621 	dest = ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg));
622 	delay_slot = ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS;
623 	if (!base)
624 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(arg2) | IMM(0), delay_slot);
625 	if (!(flags & WRITE_BACK))
626 		return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot);
627 	FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot));
628 	return push_inst(compiler, ADD | D(base) | S1(base) | S2(arg2), DR(base));
629 }
630 
emit_op_mem(struct sljit_compiler * compiler,sljit_si flags,sljit_si reg,sljit_si arg,sljit_sw argw)631 static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
632 {
633 	if (getput_arg_fast(compiler, flags, reg, arg, argw))
634 		return compiler->error;
635 	compiler->cache_arg = 0;
636 	compiler->cache_argw = 0;
637 	return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
638 }
639 
emit_op_mem2(struct sljit_compiler * compiler,sljit_si flags,sljit_si reg,sljit_si arg1,sljit_sw arg1w,sljit_si arg2,sljit_sw arg2w)640 static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w)
641 {
642 	if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
643 		return compiler->error;
644 	return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
645 }
646 
emit_op(struct sljit_compiler * compiler,sljit_si op,sljit_si flags,sljit_si dst,sljit_sw dstw,sljit_si src1,sljit_sw src1w,sljit_si src2,sljit_sw src2w)647 static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags,
648 	sljit_si dst, sljit_sw dstw,
649 	sljit_si src1, sljit_sw src1w,
650 	sljit_si src2, sljit_sw src2w)
651 {
652 	/* arg1 goes to TMP_REG1 or src reg
653 	   arg2 goes to TMP_REG2, imm or src reg
654 	   TMP_REG3 can be used for caching
655 	   result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
656 	sljit_si dst_r = TMP_REG2;
657 	sljit_si src1_r;
658 	sljit_sw src2_r = 0;
659 	sljit_si sugg_src2_r = TMP_REG2;
660 
661 	if (!(flags & ALT_KEEP_CACHE)) {
662 		compiler->cache_arg = 0;
663 		compiler->cache_argw = 0;
664 	}
665 
666 	if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
667 		if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM))
668 			return SLJIT_SUCCESS;
669 	}
670 	else if (FAST_IS_REG(dst)) {
671 		dst_r = dst;
672 		flags |= REG_DEST;
673 		if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
674 			sugg_src2_r = dst_r;
675 	}
676 	else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw))
677 		flags |= SLOW_DEST;
678 
679 	if (flags & IMM_OP) {
680 		if ((src2 & SLJIT_IMM) && src2w) {
681 			if (src2w <= SIMM_MAX && src2w >= SIMM_MIN) {
682 				flags |= SRC2_IMM;
683 				src2_r = src2w;
684 			}
685 		}
686 		if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) {
687 			if (src1w <= SIMM_MAX && src1w >= SIMM_MIN) {
688 				flags |= SRC2_IMM;
689 				src2_r = src1w;
690 
691 				/* And swap arguments. */
692 				src1 = src2;
693 				src1w = src2w;
694 				src2 = SLJIT_IMM;
695 				/* src2w = src2_r unneeded. */
696 			}
697 		}
698 	}
699 
700 	/* Source 1. */
701 	if (FAST_IS_REG(src1))
702 		src1_r = src1;
703 	else if (src1 & SLJIT_IMM) {
704 		if (src1w) {
705 			FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
706 			src1_r = TMP_REG1;
707 		}
708 		else
709 			src1_r = 0;
710 	}
711 	else {
712 		if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w))
713 			FAIL_IF(compiler->error);
714 		else
715 			flags |= SLOW_SRC1;
716 		src1_r = TMP_REG1;
717 	}
718 
719 	/* Source 2. */
720 	if (FAST_IS_REG(src2)) {
721 		src2_r = src2;
722 		flags |= REG2_SOURCE;
723 		if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
724 			dst_r = src2_r;
725 	}
726 	else if (src2 & SLJIT_IMM) {
727 		if (!(flags & SRC2_IMM)) {
728 			if (src2w) {
729 				FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w));
730 				src2_r = sugg_src2_r;
731 			}
732 			else {
733 				src2_r = 0;
734 				if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM))
735 					dst_r = 0;
736 			}
737 		}
738 	}
739 	else {
740 		if (getput_arg_fast(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w))
741 			FAIL_IF(compiler->error);
742 		else
743 			flags |= SLOW_SRC2;
744 		src2_r = sugg_src2_r;
745 	}
746 
747 	if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
748 		SLJIT_ASSERT(src2_r == TMP_REG2);
749 		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
750 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));
751 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
752 		}
753 		else {
754 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
755 			FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
756 		}
757 	}
758 	else if (flags & SLOW_SRC1)
759 		FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
760 	else if (flags & SLOW_SRC2)
761 		FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
762 
763 	FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
764 
765 	if (dst & SLJIT_MEM) {
766 		if (!(flags & SLOW_DEST)) {
767 			getput_arg_fast(compiler, flags, dst_r, dst, dstw);
768 			return compiler->error;
769 		}
770 		return getput_arg(compiler, flags, dst_r, dst, dstw, 0, 0);
771 	}
772 
773 	return SLJIT_SUCCESS;
774 }
775 
sljit_emit_op0(struct sljit_compiler * compiler,sljit_si op)776 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
777 {
778 	CHECK_ERROR();
779 	check_sljit_emit_op0(compiler, op);
780 
781 	op = GET_OPCODE(op);
782 	switch (op) {
783 	case SLJIT_BREAKPOINT:
784 		return push_inst(compiler, TA, UNMOVABLE_INS);
785 	case SLJIT_NOP:
786 		return push_inst(compiler, NOP, UNMOVABLE_INS);
787 	case SLJIT_UMUL:
788 	case SLJIT_SMUL:
789 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
790 		FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? UMUL : SMUL) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));
791 		return push_inst(compiler, RDY | D(SLJIT_R1), DR(SLJIT_R1));
792 #else
793 #error "Implementation required"
794 #endif
795 	case SLJIT_UDIV:
796 	case SLJIT_SDIV:
797 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
798 		if (op == SLJIT_UDIV)
799 			FAIL_IF(push_inst(compiler, WRY | S1(0), MOVABLE_INS));
800 		else {
801 			FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_R0) | IMM(31), DR(TMP_REG1)));
802 			FAIL_IF(push_inst(compiler, WRY | S1(TMP_REG1), MOVABLE_INS));
803 		}
804 		FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_R0), DR(TMP_REG2)));
805 		FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));
806 		FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_R1) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R1)));
807 		FAIL_IF(push_inst(compiler, SUB | D(SLJIT_R1) | S1(TMP_REG2) | S2(SLJIT_R1), DR(SLJIT_R1)));
808 		return SLJIT_SUCCESS;
809 #else
810 #error "Implementation required"
811 #endif
812 	}
813 
814 	return SLJIT_SUCCESS;
815 }
816 
sljit_emit_op1(struct sljit_compiler * compiler,sljit_si op,sljit_si dst,sljit_sw dstw,sljit_si src,sljit_sw srcw)817 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
818 	sljit_si dst, sljit_sw dstw,
819 	sljit_si src, sljit_sw srcw)
820 {
821 	sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0;
822 
823 	CHECK_ERROR();
824 	check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
825 	ADJUST_LOCAL_OFFSET(dst, dstw);
826 	ADJUST_LOCAL_OFFSET(src, srcw);
827 
828 	op = GET_OPCODE(op);
829 	switch (op) {
830 	case SLJIT_MOV:
831 	case SLJIT_MOV_P:
832 		return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
833 
834 	case SLJIT_MOV_UI:
835 		return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
836 
837 	case SLJIT_MOV_SI:
838 		return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
839 
840 	case SLJIT_MOV_UB:
841 		return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw);
842 
843 	case SLJIT_MOV_SB:
844 		return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw);
845 
846 	case SLJIT_MOV_UH:
847 		return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw);
848 
849 	case SLJIT_MOV_SH:
850 		return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw);
851 
852 	case SLJIT_MOVU:
853 	case SLJIT_MOVU_P:
854 		return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
855 
856 	case SLJIT_MOVU_UI:
857 		return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
858 
859 	case SLJIT_MOVU_SI:
860 		return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
861 
862 	case SLJIT_MOVU_UB:
863 		return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw);
864 
865 	case SLJIT_MOVU_SB:
866 		return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw);
867 
868 	case SLJIT_MOVU_UH:
869 		return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw);
870 
871 	case SLJIT_MOVU_SH:
872 		return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw);
873 
874 	case SLJIT_NOT:
875 	case SLJIT_CLZ:
876 		return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
877 
878 	case SLJIT_NEG:
879 		return emit_op(compiler, SLJIT_SUB, flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw);
880 	}
881 
882 	return SLJIT_SUCCESS;
883 }
884 
sljit_emit_op2(struct sljit_compiler * compiler,sljit_si op,sljit_si dst,sljit_sw dstw,sljit_si src1,sljit_sw src1w,sljit_si src2,sljit_sw src2w)885 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
886 	sljit_si dst, sljit_sw dstw,
887 	sljit_si src1, sljit_sw src1w,
888 	sljit_si src2, sljit_sw src2w)
889 {
890 	sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0;
891 
892 	CHECK_ERROR();
893 	check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
894 	ADJUST_LOCAL_OFFSET(dst, dstw);
895 	ADJUST_LOCAL_OFFSET(src1, src1w);
896 	ADJUST_LOCAL_OFFSET(src2, src2w);
897 
898 	op = GET_OPCODE(op);
899 	switch (op) {
900 	case SLJIT_ADD:
901 	case SLJIT_ADDC:
902 	case SLJIT_MUL:
903 	case SLJIT_AND:
904 	case SLJIT_OR:
905 	case SLJIT_XOR:
906 		return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
907 
908 	case SLJIT_SUB:
909 	case SLJIT_SUBC:
910 		return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
911 
912 	case SLJIT_SHL:
913 	case SLJIT_LSHR:
914 	case SLJIT_ASHR:
915 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
916 		if (src2 & SLJIT_IMM)
917 			src2w &= 0x1f;
918 #else
919 		SLJIT_ASSERT_STOP();
920 #endif
921 		return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
922 	}
923 
924 	return SLJIT_SUCCESS;
925 }
926 
sljit_get_register_index(sljit_si reg)927 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
928 {
929 	check_sljit_get_register_index(reg);
930 	return reg_map[reg];
931 }
932 
sljit_get_float_register_index(sljit_si reg)933 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
934 {
935 	check_sljit_get_float_register_index(reg);
936 	return reg << 1;
937 }
938 
sljit_emit_op_custom(struct sljit_compiler * compiler,void * instruction,sljit_si size)939 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
940 	void *instruction, sljit_si size)
941 {
942 	CHECK_ERROR();
943 	check_sljit_emit_op_custom(compiler, instruction, size);
944 	SLJIT_ASSERT(size == 4);
945 
946 	return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS);
947 }
948 
949 /* --------------------------------------------------------------------- */
950 /*  Floating point operators                                             */
951 /* --------------------------------------------------------------------- */
952 
sljit_is_fpu_available(void)953 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
954 {
955 #ifdef SLJIT_IS_FPU_AVAILABLE
956 	return SLJIT_IS_FPU_AVAILABLE;
957 #else
958 	/* Available by default. */
959 	return 1;
960 #endif
961 }
962 
963 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 7))
964 #define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double)
965 #define FLOAT_TMP_MEM_OFFSET (22 * sizeof(sljit_sw))
966 
sljit_emit_fop1_convw_fromd(struct sljit_compiler * compiler,sljit_si op,sljit_si dst,sljit_sw dstw,sljit_si src,sljit_sw srcw)967 static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op,
968 	sljit_si dst, sljit_sw dstw,
969 	sljit_si src, sljit_sw srcw)
970 {
971 	if (src & SLJIT_MEM) {
972 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
973 		src = TMP_FREG1;
974 	}
975 	else
976 		src <<= 1;
977 
978 	FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOI, FDTOI) | DA(TMP_FREG1) | S2A(src), MOVABLE_INS));
979 
980 	if (dst == SLJIT_UNUSED)
981 		return SLJIT_SUCCESS;
982 
983 	if (FAST_IS_REG(dst)) {
984 		FAIL_IF(emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
985 		return emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET);
986 	}
987 
988 	/* Store the integer value from a VFP register. */
989 	return emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, dst, dstw, 0, 0);
990 }
991 
sljit_emit_fop1_convd_fromw(struct sljit_compiler * compiler,sljit_si op,sljit_si dst,sljit_sw dstw,sljit_si src,sljit_sw srcw)992 static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op,
993 	sljit_si dst, sljit_sw dstw,
994 	sljit_si src, sljit_sw srcw)
995 {
996 	sljit_si dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
997 
998 	if (src & SLJIT_IMM) {
999 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1000 		if (GET_OPCODE(op) == SLJIT_CONVD_FROMI)
1001 			srcw = (sljit_si)srcw;
1002 #endif
1003 		FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
1004 		src = TMP_REG1;
1005 		srcw = 0;
1006 	}
1007 
1008 	if (FAST_IS_REG(src)) {
1009 		FAIL_IF(emit_op_mem2(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
1010 		src = SLJIT_MEM1(SLJIT_SP);
1011 		srcw = FLOAT_TMP_MEM_OFFSET;
1012 	}
1013 
1014 	FAIL_IF(emit_op_mem2(compiler, SINGLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
1015 	FAIL_IF(push_inst(compiler, SELECT_FOP(op, FITOS, FITOD) | DA(dst_r) | S2A(TMP_FREG1), MOVABLE_INS));
1016 
1017 	if (dst & SLJIT_MEM)
1018 		return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
1019 	return SLJIT_SUCCESS;
1020 }
1021 
sljit_emit_fop1_cmp(struct sljit_compiler * compiler,sljit_si op,sljit_si src1,sljit_sw src1w,sljit_si src2,sljit_sw src2w)1022 static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op,
1023 	sljit_si src1, sljit_sw src1w,
1024 	sljit_si src2, sljit_sw src2w)
1025 {
1026 	if (src1 & SLJIT_MEM) {
1027 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
1028 		src1 = TMP_FREG1;
1029 	}
1030 	else
1031 		src1 <<= 1;
1032 
1033 	if (src2 & SLJIT_MEM) {
1034 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));
1035 		src2 = TMP_FREG2;
1036 	}
1037 	else
1038 		src2 <<= 1;
1039 
1040 	return push_inst(compiler, SELECT_FOP(op, FCMPS, FCMPD) | S1A(src1) | S2A(src2), FCC_IS_SET | MOVABLE_INS);
1041 }
1042 
sljit_emit_fop1(struct sljit_compiler * compiler,sljit_si op,sljit_si dst,sljit_sw dstw,sljit_si src,sljit_sw srcw)1043 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
1044 	sljit_si dst, sljit_sw dstw,
1045 	sljit_si src, sljit_sw srcw)
1046 {
1047 	sljit_si dst_r;
1048 
1049 	CHECK_ERROR();
1050 	compiler->cache_arg = 0;
1051 	compiler->cache_argw = 0;
1052 
1053 	SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
1054 	SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
1055 
1056 	if (GET_OPCODE(op) == SLJIT_CONVD_FROMS)
1057 		op ^= SLJIT_SINGLE_OP;
1058 
1059 	dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
1060 
1061 	if (src & SLJIT_MEM) {
1062 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw));
1063 		src = dst_r;
1064 	}
1065 	else
1066 		src <<= 1;
1067 
1068 	switch (GET_OPCODE(op)) {
1069 	case SLJIT_MOVD:
1070 		if (src != dst_r) {
1071 			if (dst_r != TMP_FREG1) {
1072 				FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r) | S2A(src), MOVABLE_INS));
1073 				if (!(op & SLJIT_SINGLE_OP))
1074 					FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
1075 			}
1076 			else
1077 				dst_r = src;
1078 		}
1079 		break;
1080 	case SLJIT_NEGD:
1081 		FAIL_IF(push_inst(compiler, FNEGS | DA(dst_r) | S2A(src), MOVABLE_INS));
1082 		if (dst_r != src && !(op & SLJIT_SINGLE_OP))
1083 			FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
1084 		break;
1085 	case SLJIT_ABSD:
1086 		FAIL_IF(push_inst(compiler, FABSS | DA(dst_r) | S2A(src), MOVABLE_INS));
1087 		if (dst_r != src && !(op & SLJIT_SINGLE_OP))
1088 			FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
1089 		break;
1090 	case SLJIT_CONVD_FROMS:
1091 		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOD, FDTOS) | DA(dst_r) | S2A(src), MOVABLE_INS));
1092 		op ^= SLJIT_SINGLE_OP;
1093 		break;
1094 	}
1095 
1096 	if (dst & SLJIT_MEM)
1097 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0));
1098 	return SLJIT_SUCCESS;
1099 }
1100 
sljit_emit_fop2(struct sljit_compiler * compiler,sljit_si op,sljit_si dst,sljit_sw dstw,sljit_si src1,sljit_sw src1w,sljit_si src2,sljit_sw src2w)1101 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
1102 	sljit_si dst, sljit_sw dstw,
1103 	sljit_si src1, sljit_sw src1w,
1104 	sljit_si src2, sljit_sw src2w)
1105 {
1106 	sljit_si dst_r, flags = 0;
1107 
1108 	CHECK_ERROR();
1109 	check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
1110 	ADJUST_LOCAL_OFFSET(dst, dstw);
1111 	ADJUST_LOCAL_OFFSET(src1, src1w);
1112 	ADJUST_LOCAL_OFFSET(src2, src2w);
1113 
1114 	compiler->cache_arg = 0;
1115 	compiler->cache_argw = 0;
1116 
1117 	dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG2;
1118 
1119 	if (src1 & SLJIT_MEM) {
1120 		if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {
1121 			FAIL_IF(compiler->error);
1122 			src1 = TMP_FREG1;
1123 		} else
1124 			flags |= SLOW_SRC1;
1125 	}
1126 	else
1127 		src1 <<= 1;
1128 
1129 	if (src2 & SLJIT_MEM) {
1130 		if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) {
1131 			FAIL_IF(compiler->error);
1132 			src2 = TMP_FREG2;
1133 		} else
1134 			flags |= SLOW_SRC2;
1135 	}
1136 	else
1137 		src2 <<= 1;
1138 
1139 	if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
1140 		if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
1141 			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w));
1142 			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
1143 		}
1144 		else {
1145 			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
1146 			FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
1147 		}
1148 	}
1149 	else if (flags & SLOW_SRC1)
1150 		FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
1151 	else if (flags & SLOW_SRC2)
1152 		FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
1153 
1154 	if (flags & SLOW_SRC1)
1155 		src1 = TMP_FREG1;
1156 	if (flags & SLOW_SRC2)
1157 		src2 = TMP_FREG2;
1158 
1159 	switch (GET_OPCODE(op)) {
1160 	case SLJIT_ADDD:
1161 		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADDD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
1162 		break;
1163 
1164 	case SLJIT_SUBD:
1165 		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUBD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
1166 		break;
1167 
1168 	case SLJIT_MULD:
1169 		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMULD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
1170 		break;
1171 
1172 	case SLJIT_DIVD:
1173 		FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIVD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
1174 		break;
1175 	}
1176 
1177 	if (dst_r == TMP_FREG2)
1178 		FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));
1179 
1180 	return SLJIT_SUCCESS;
1181 }
1182 
1183 #undef FLOAT_DATA
1184 #undef SELECT_FOP
1185 
1186 /* --------------------------------------------------------------------- */
1187 /*  Other instructions                                                   */
1188 /* --------------------------------------------------------------------- */
1189 
sljit_emit_fast_enter(struct sljit_compiler * compiler,sljit_si dst,sljit_sw dstw)1190 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
1191 {
1192 	CHECK_ERROR();
1193 	check_sljit_emit_fast_enter(compiler, dst, dstw);
1194 	ADJUST_LOCAL_OFFSET(dst, dstw);
1195 
1196 	/* For UNUSED dst. Uncommon, but possible. */
1197 	if (dst == SLJIT_UNUSED)
1198 		return SLJIT_SUCCESS;
1199 
1200 	if (FAST_IS_REG(dst))
1201 		return push_inst(compiler, OR | D(dst) | S1(0) | S2(TMP_LINK), DR(dst));
1202 
1203 	/* Memory. */
1204 	return emit_op_mem(compiler, WORD_DATA, TMP_LINK, dst, dstw);
1205 }
1206 
sljit_emit_fast_return(struct sljit_compiler * compiler,sljit_si src,sljit_sw srcw)1207 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
1208 {
1209 	CHECK_ERROR();
1210 	check_sljit_emit_fast_return(compiler, src, srcw);
1211 	ADJUST_LOCAL_OFFSET(src, srcw);
1212 
1213 	if (FAST_IS_REG(src))
1214 		FAIL_IF(push_inst(compiler, OR | D(TMP_LINK) | S1(0) | S2(src), DR(TMP_LINK)));
1215 	else if (src & SLJIT_MEM)
1216 		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_LINK, src, srcw));
1217 	else if (src & SLJIT_IMM)
1218 		FAIL_IF(load_immediate(compiler, TMP_LINK, srcw));
1219 
1220 	FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(TMP_LINK) | IMM(8), UNMOVABLE_INS));
1221 	return push_inst(compiler, NOP, UNMOVABLE_INS);
1222 }
1223 
1224 /* --------------------------------------------------------------------- */
1225 /*  Conditional instructions                                             */
1226 /* --------------------------------------------------------------------- */
1227 
sljit_emit_label(struct sljit_compiler * compiler)1228 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
1229 {
1230 	struct sljit_label *label;
1231 
1232 	CHECK_ERROR_PTR();
1233 	check_sljit_emit_label(compiler);
1234 
1235 	if (compiler->last_label && compiler->last_label->size == compiler->size)
1236 		return compiler->last_label;
1237 
1238 	label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
1239 	PTR_FAIL_IF(!label);
1240 	set_label(label, compiler);
1241 	compiler->delay_slot = UNMOVABLE_INS;
1242 	return label;
1243 }
1244 
get_cc(sljit_si type)1245 static sljit_ins get_cc(sljit_si type)
1246 {
1247 	switch (type) {
1248 	case SLJIT_C_EQUAL:
1249 	case SLJIT_C_MUL_NOT_OVERFLOW:
1250 		return DA(0x1);
1251 
1252 	case SLJIT_C_NOT_EQUAL:
1253 	case SLJIT_C_MUL_OVERFLOW:
1254 		return DA(0x9);
1255 
1256 	case SLJIT_C_LESS:
1257 		return DA(0x5);
1258 
1259 	case SLJIT_C_GREATER_EQUAL:
1260 		return DA(0xd);
1261 
1262 	case SLJIT_C_GREATER:
1263 		return DA(0xc);
1264 
1265 	case SLJIT_C_LESS_EQUAL:
1266 		return DA(0x4);
1267 
1268 	case SLJIT_C_SIG_LESS:
1269 		return DA(0x3);
1270 
1271 	case SLJIT_C_SIG_GREATER_EQUAL:
1272 		return DA(0xb);
1273 
1274 	case SLJIT_C_SIG_GREATER:
1275 		return DA(0xa);
1276 
1277 	case SLJIT_C_SIG_LESS_EQUAL:
1278 		return DA(0x2);
1279 
1280 	case SLJIT_C_OVERFLOW:
1281 		return DA(0x7);
1282 
1283 	case SLJIT_C_NOT_OVERFLOW:
1284 		return DA(0xf);
1285 
1286 	case SLJIT_C_FLOAT_EQUAL:
1287 		return DA(0x9);
1288 
1289 	case SLJIT_C_FLOAT_NOT_EQUAL: /* Unordered. */
1290 		return DA(0x1);
1291 
1292 	case SLJIT_C_FLOAT_LESS:
1293 		return DA(0x4);
1294 
1295 	case SLJIT_C_FLOAT_GREATER_EQUAL: /* Unordered. */
1296 		return DA(0xc);
1297 
1298 	case SLJIT_C_FLOAT_LESS_EQUAL:
1299 		return DA(0xd);
1300 
1301 	case SLJIT_C_FLOAT_GREATER: /* Unordered. */
1302 		return DA(0x5);
1303 
1304 	case SLJIT_C_FLOAT_UNORDERED:
1305 		return DA(0x7);
1306 
1307 	case SLJIT_C_FLOAT_ORDERED:
1308 		return DA(0xf);
1309 
1310 	default:
1311 		SLJIT_ASSERT_STOP();
1312 		return DA(0x8);
1313 	}
1314 }
1315 
sljit_emit_jump(struct sljit_compiler * compiler,sljit_si type)1316 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type)
1317 {
1318 	struct sljit_jump *jump;
1319 
1320 	CHECK_ERROR_PTR();
1321 	check_sljit_emit_jump(compiler, type);
1322 
1323 	jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
1324 	PTR_FAIL_IF(!jump);
1325 	set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
1326 	type &= 0xff;
1327 
1328 	if (type < SLJIT_C_FLOAT_EQUAL) {
1329 		jump->flags |= IS_COND;
1330 		if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & ICC_IS_SET))
1331 			jump->flags |= IS_MOVABLE;
1332 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
1333 		PTR_FAIL_IF(push_inst(compiler, BICC | get_cc(type ^ 1) | 5, UNMOVABLE_INS));
1334 #else
1335 #error "Implementation required"
1336 #endif
1337 	}
1338 	else if (type < SLJIT_JUMP) {
1339 		jump->flags |= IS_COND;
1340 		if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & FCC_IS_SET))
1341 			jump->flags |= IS_MOVABLE;
1342 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
1343 		PTR_FAIL_IF(push_inst(compiler, FBFCC | get_cc(type ^ 1) | 5, UNMOVABLE_INS));
1344 #else
1345 #error "Implementation required"
1346 #endif
1347 	} else {
1348 		if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS)
1349 			jump->flags |= IS_MOVABLE;
1350 		if (type >= SLJIT_FAST_CALL)
1351 			jump->flags |= IS_CALL;
1352 	}
1353 
1354 	PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
1355 	PTR_FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(TMP_REG2) | IMM(0), UNMOVABLE_INS));
1356 	jump->addr = compiler->size;
1357 	PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
1358 
1359 	return jump;
1360 }
1361 
sljit_emit_ijump(struct sljit_compiler * compiler,sljit_si type,sljit_si src,sljit_sw srcw)1362 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw)
1363 {
1364 	struct sljit_jump *jump = NULL;
1365 	sljit_si src_r;
1366 
1367 	CHECK_ERROR();
1368 	check_sljit_emit_ijump(compiler, type, src, srcw);
1369 	ADJUST_LOCAL_OFFSET(src, srcw);
1370 
1371 	if (FAST_IS_REG(src))
1372 		src_r = src;
1373 	else if (src & SLJIT_IMM) {
1374 		jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
1375 		FAIL_IF(!jump);
1376 		set_jump(jump, compiler, JUMP_ADDR);
1377 		jump->u.target = srcw;
1378 		if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS)
1379 			jump->flags |= IS_MOVABLE;
1380 		if (type >= SLJIT_FAST_CALL)
1381 			jump->flags |= IS_CALL;
1382 
1383 		FAIL_IF(emit_const(compiler, TMP_REG2, 0));
1384 		src_r = TMP_REG2;
1385 	}
1386 	else {
1387 		FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw));
1388 		src_r = TMP_REG2;
1389 	}
1390 
1391 	FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(src_r) | IMM(0), UNMOVABLE_INS));
1392 	if (jump)
1393 		jump->addr = compiler->size;
1394 	return push_inst(compiler, NOP, UNMOVABLE_INS);
1395 }
1396 
sljit_emit_op_flags(struct sljit_compiler * compiler,sljit_si op,sljit_si dst,sljit_sw dstw,sljit_si src,sljit_sw srcw,sljit_si type)1397 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op,
1398 	sljit_si dst, sljit_sw dstw,
1399 	sljit_si src, sljit_sw srcw,
1400 	sljit_si type)
1401 {
1402 	sljit_si reg, flags = (GET_FLAGS(op) ? SET_FLAGS : 0);
1403 
1404 	CHECK_ERROR();
1405 	check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type);
1406 	ADJUST_LOCAL_OFFSET(dst, dstw);
1407 
1408 	if (dst == SLJIT_UNUSED)
1409 		return SLJIT_SUCCESS;
1410 
1411 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
1412 	op = GET_OPCODE(op);
1413 	reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;
1414 
1415 	compiler->cache_arg = 0;
1416 	compiler->cache_argw = 0;
1417 	if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
1418 		ADJUST_LOCAL_OFFSET(src, srcw);
1419 		FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw));
1420 		src = TMP_REG1;
1421 		srcw = 0;
1422 	}
1423 
1424 	if (type < SLJIT_C_FLOAT_EQUAL)
1425 		FAIL_IF(push_inst(compiler, BICC | get_cc(type) | 3, UNMOVABLE_INS));
1426 	else
1427 		FAIL_IF(push_inst(compiler, FBFCC | get_cc(type) | 3, UNMOVABLE_INS));
1428 
1429 	FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(1), UNMOVABLE_INS));
1430 	FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(0), UNMOVABLE_INS));
1431 
1432 	if (op >= SLJIT_ADD)
1433 		return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0);
1434 
1435 	return (reg == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS;
1436 #else
1437 #error "Implementation required"
1438 #endif
1439 }
1440 
sljit_emit_const(struct sljit_compiler * compiler,sljit_si dst,sljit_sw dstw,sljit_sw init_value)1441 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)
1442 {
1443 	sljit_si reg;
1444 	struct sljit_const *const_;
1445 
1446 	CHECK_ERROR_PTR();
1447 	check_sljit_emit_const(compiler, dst, dstw, init_value);
1448 	ADJUST_LOCAL_OFFSET(dst, dstw);
1449 
1450 	const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
1451 	PTR_FAIL_IF(!const_);
1452 	set_const(const_, compiler);
1453 
1454 	reg = SLOW_IS_REG(dst) ? dst : TMP_REG2;
1455 
1456 	PTR_FAIL_IF(emit_const(compiler, reg, init_value));
1457 
1458 	if (dst & SLJIT_MEM)
1459 		PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
1460 	return const_;
1461 }
1462