/[pcre]/code/trunk/sljit/sljitNativePPC_common.c
ViewVC logotype

Contents of /code/trunk/sljit/sljitNativePPC_common.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1280 - (show annotations)
Fri Mar 15 06:58:31 2013 UTC (6 years, 7 months ago) by zherczeg
File MIME type: text/plain
File size: 66317 byte(s)
JIT compiler update.
1 /*
2 * Stack-less Just-In-Time compiler
3 *
4 * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without modification, are
7 * permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice, this list of
10 * conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
13 * of conditions and the following disclaimer in the documentation and/or other materials
14 * provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19 * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void)
28 {
29 return "PowerPC" SLJIT_CPUINFO;
30 }
31
32 /* Length of an instruction word.
33 Both for ppc-32 and ppc-64. */
34 typedef sljit_ui sljit_ins;
35
36 #ifdef _AIX
37 #include <sys/cache.h>
38 #endif
39
40 static void ppc_cache_flush(sljit_ins *from, sljit_ins *to)
41 {
42 #ifdef _AIX
43 _sync_cache_range((caddr_t)from, (int)((size_t)to - (size_t)from));
44 #elif defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)
45 # if defined(_ARCH_PWR) || defined(_ARCH_PWR2)
46 /* Cache flush for POWER architecture. */
47 while (from < to) {
48 __asm__ volatile (
49 "clf 0, %0\n"
50 "dcs\n"
51 : : "r"(from)
52 );
53 from++;
54 }
55 __asm__ volatile ( "ics" );
56 # elif defined(_ARCH_COM) && !defined(_ARCH_PPC)
57 # error "Cache flush is not implemented for PowerPC/POWER common mode."
58 # else
59 /* Cache flush for PowerPC architecture. */
60 while (from < to) {
61 __asm__ volatile (
62 "dcbf 0, %0\n"
63 "sync\n"
64 "icbi 0, %0\n"
65 : : "r"(from)
66 );
67 from++;
68 }
69 __asm__ volatile ( "isync" );
70 # endif
71 # ifdef __xlc__
72 # warning "This file may fail to compile if -qfuncsect is used"
73 # endif
74 #elif defined(__xlc__)
75 #error "Please enable GCC syntax for inline assembly statements with -qasm=gcc"
76 #else
77 #error "This platform requires a cache flush implementation."
78 #endif /* _AIX */
79 }
80
81 #define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
82 #define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
83 #define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
84 #define ZERO_REG (SLJIT_NO_REGISTERS + 4)
85
86 #define TMP_FREG1 (0)
87 #define TMP_FREG2 (SLJIT_FLOAT_REG6 + 1)
88
89 static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = {
90 0, 3, 4, 5, 6, 7, 30, 29, 28, 27, 26, 1, 8, 9, 10, 31
91 };
92
93 /* --------------------------------------------------------------------- */
94 /* Instrucion forms */
95 /* --------------------------------------------------------------------- */
96 #define D(d) (reg_map[d] << 21)
97 #define S(s) (reg_map[s] << 21)
98 #define A(a) (reg_map[a] << 16)
99 #define B(b) (reg_map[b] << 11)
100 #define C(c) (reg_map[c] << 6)
101 #define FD(fd) ((fd) << 21)
102 #define FA(fa) ((fa) << 16)
103 #define FB(fb) ((fb) << 11)
104 #define FC(fc) ((fc) << 6)
105 #define IMM(imm) ((imm) & 0xffff)
106 #define CRD(d) ((d) << 21)
107
108 /* Instruction bit sections.
109 OE and Rc flag (see ALT_SET_FLAGS). */
110 #define OERC(flags) (((flags & ALT_SET_FLAGS) >> 10) | (flags & ALT_SET_FLAGS))
111 /* Rc flag (see ALT_SET_FLAGS). */
112 #define RC(flags) ((flags & ALT_SET_FLAGS) >> 10)
113 #define HI(opcode) ((opcode) << 26)
114 #define LO(opcode) ((opcode) << 1)
115
116 #define ADD (HI(31) | LO(266))
117 #define ADDC (HI(31) | LO(10))
118 #define ADDE (HI(31) | LO(138))
119 #define ADDI (HI(14))
120 #define ADDIC (HI(13))
121 #define ADDIS (HI(15))
122 #define ADDME (HI(31) | LO(234))
123 #define AND (HI(31) | LO(28))
124 #define ANDI (HI(28))
125 #define ANDIS (HI(29))
126 #define Bx (HI(18))
127 #define BCx (HI(16))
128 #define BCCTR (HI(19) | LO(528) | (3 << 11))
129 #define BLR (HI(19) | LO(16) | (0x14 << 21))
130 #define CNTLZD (HI(31) | LO(58))
131 #define CNTLZW (HI(31) | LO(26))
132 #define CMP (HI(31) | LO(0))
133 #define CMPI (HI(11))
134 #define CMPL (HI(31) | LO(32))
135 #define CMPLI (HI(10))
136 #define CROR (HI(19) | LO(449))
137 #define DIVD (HI(31) | LO(489))
138 #define DIVDU (HI(31) | LO(457))
139 #define DIVW (HI(31) | LO(491))
140 #define DIVWU (HI(31) | LO(459))
141 #define EXTSB (HI(31) | LO(954))
142 #define EXTSH (HI(31) | LO(922))
143 #define EXTSW (HI(31) | LO(986))
144 #define FABS (HI(63) | LO(264))
145 #define FADD (HI(63) | LO(21))
146 #define FADDS (HI(59) | LO(21))
147 #define FCMPU (HI(63) | LO(0))
148 #define FDIV (HI(63) | LO(18))
149 #define FDIVS (HI(59) | LO(18))
150 #define FMR (HI(63) | LO(72))
151 #define FMUL (HI(63) | LO(25))
152 #define FMULS (HI(59) | LO(25))
153 #define FNEG (HI(63) | LO(40))
154 #define FSUB (HI(63) | LO(20))
155 #define FSUBS (HI(59) | LO(20))
156 #define LD (HI(58) | 0)
157 #define LWZ (HI(32))
158 #define MFCR (HI(31) | LO(19))
159 #define MFLR (HI(31) | LO(339) | 0x80000)
160 #define MFXER (HI(31) | LO(339) | 0x10000)
161 #define MTCTR (HI(31) | LO(467) | 0x90000)
162 #define MTLR (HI(31) | LO(467) | 0x80000)
163 #define MTXER (HI(31) | LO(467) | 0x10000)
164 #define MULHD (HI(31) | LO(73))
165 #define MULHDU (HI(31) | LO(9))
166 #define MULHW (HI(31) | LO(75))
167 #define MULHWU (HI(31) | LO(11))
168 #define MULLD (HI(31) | LO(233))
169 #define MULLI (HI(7))
170 #define MULLW (HI(31) | LO(235))
171 #define NEG (HI(31) | LO(104))
172 #define NOP (HI(24))
173 #define NOR (HI(31) | LO(124))
174 #define OR (HI(31) | LO(444))
175 #define ORI (HI(24))
176 #define ORIS (HI(25))
177 #define RLDICL (HI(30))
178 #define RLWINM (HI(21))
179 #define SLD (HI(31) | LO(27))
180 #define SLW (HI(31) | LO(24))
181 #define SRAD (HI(31) | LO(794))
182 #define SRADI (HI(31) | LO(413 << 1))
183 #define SRAW (HI(31) | LO(792))
184 #define SRAWI (HI(31) | LO(824))
185 #define SRD (HI(31) | LO(539))
186 #define SRW (HI(31) | LO(536))
187 #define STD (HI(62) | 0)
188 #define STDU (HI(62) | 1)
189 #define STDUX (HI(31) | LO(181))
190 #define STW (HI(36))
191 #define STWU (HI(37))
192 #define STWUX (HI(31) | LO(183))
193 #define SUBF (HI(31) | LO(40))
194 #define SUBFC (HI(31) | LO(8))
195 #define SUBFE (HI(31) | LO(136))
196 #define SUBFIC (HI(8))
197 #define XOR (HI(31) | LO(316))
198 #define XORI (HI(26))
199 #define XORIS (HI(27))
200
201 #define SIMM_MAX (0x7fff)
202 #define SIMM_MIN (-0x8000)
203 #define UIMM_MAX (0xffff)
204
205 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
206 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func)
207 {
208 sljit_sw* ptrs;
209 if (func_ptr)
210 *func_ptr = (void*)context;
211 ptrs = (sljit_sw*)func;
212 context->addr = addr ? addr : ptrs[0];
213 context->r2 = ptrs[1];
214 context->r11 = ptrs[2];
215 }
216 #endif
217
218 static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins)
219 {
220 sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
221 FAIL_IF(!ptr);
222 *ptr = ins;
223 compiler->size++;
224 return SLJIT_SUCCESS;
225 }
226
227 static SLJIT_INLINE sljit_si optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
228 {
229 sljit_sw diff;
230 sljit_uw target_addr;
231
232 if (jump->flags & SLJIT_REWRITABLE_JUMP)
233 return 0;
234
235 if (jump->flags & JUMP_ADDR)
236 target_addr = jump->u.target;
237 else {
238 SLJIT_ASSERT(jump->flags & JUMP_LABEL);
239 target_addr = (sljit_uw)(code + jump->u.label->size);
240 }
241 diff = ((sljit_sw)target_addr - (sljit_sw)(code_ptr)) & ~0x3l;
242
243 if (jump->flags & UNCOND_B) {
244 if (diff <= 0x01ffffff && diff >= -0x02000000) {
245 jump->flags |= PATCH_B;
246 return 1;
247 }
248 if (target_addr <= 0x03ffffff) {
249 jump->flags |= PATCH_B | ABSOLUTE_B;
250 return 1;
251 }
252 }
253 else {
254 if (diff <= 0x7fff && diff >= -0x8000) {
255 jump->flags |= PATCH_B;
256 return 1;
257 }
258 if (target_addr <= 0xffff) {
259 jump->flags |= PATCH_B | ABSOLUTE_B;
260 return 1;
261 }
262 }
263 return 0;
264 }
265
266 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
267 {
268 struct sljit_memory_fragment *buf;
269 sljit_ins *code;
270 sljit_ins *code_ptr;
271 sljit_ins *buf_ptr;
272 sljit_ins *buf_end;
273 sljit_uw word_count;
274 sljit_uw addr;
275
276 struct sljit_label *label;
277 struct sljit_jump *jump;
278 struct sljit_const *const_;
279
280 CHECK_ERROR_PTR();
281 check_sljit_generate_code(compiler);
282 reverse_buf(compiler);
283
284 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
285 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
286 compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
287 #else
288 compiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
289 #endif
290 #endif
291 code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
292 PTR_FAIL_WITH_EXEC_IF(code);
293 buf = compiler->buf;
294
295 code_ptr = code;
296 word_count = 0;
297 label = compiler->labels;
298 jump = compiler->jumps;
299 const_ = compiler->consts;
300 do {
301 buf_ptr = (sljit_ins*)buf->memory;
302 buf_end = buf_ptr + (buf->used_size >> 2);
303 do {
304 *code_ptr = *buf_ptr++;
305 SLJIT_ASSERT(!label || label->size >= word_count);
306 SLJIT_ASSERT(!jump || jump->addr >= word_count);
307 SLJIT_ASSERT(!const_ || const_->addr >= word_count);
308 /* These structures are ordered by their address. */
309 if (label && label->size == word_count) {
310 /* Just recording the address. */
311 label->addr = (sljit_uw)code_ptr;
312 label->size = code_ptr - code;
313 label = label->next;
314 }
315 if (jump && jump->addr == word_count) {
316 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
317 jump->addr = (sljit_uw)(code_ptr - 3);
318 #else
319 jump->addr = (sljit_uw)(code_ptr - 6);
320 #endif
321 if (optimize_jump(jump, code_ptr, code)) {
322 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
323 code_ptr[-3] = code_ptr[0];
324 code_ptr -= 3;
325 #else
326 code_ptr[-6] = code_ptr[0];
327 code_ptr -= 6;
328 #endif
329 }
330 jump = jump->next;
331 }
332 if (const_ && const_->addr == word_count) {
333 /* Just recording the address. */
334 const_->addr = (sljit_uw)code_ptr;
335 const_ = const_->next;
336 }
337 code_ptr ++;
338 word_count ++;
339 } while (buf_ptr < buf_end);
340
341 buf = buf->next;
342 } while (buf);
343
344 if (label && label->size == word_count) {
345 label->addr = (sljit_uw)code_ptr;
346 label->size = code_ptr - code;
347 label = label->next;
348 }
349
350 SLJIT_ASSERT(!label);
351 SLJIT_ASSERT(!jump);
352 SLJIT_ASSERT(!const_);
353 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
354 SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins)));
355 #else
356 SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
357 #endif
358
359 jump = compiler->jumps;
360 while (jump) {
361 do {
362 addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
363 buf_ptr = (sljit_ins*)jump->addr;
364 if (jump->flags & PATCH_B) {
365 if (jump->flags & UNCOND_B) {
366 if (!(jump->flags & ABSOLUTE_B)) {
367 addr = addr - jump->addr;
368 SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000);
369 *buf_ptr = Bx | (addr & 0x03fffffc) | ((*buf_ptr) & 0x1);
370 }
371 else {
372 SLJIT_ASSERT(addr <= 0x03ffffff);
373 *buf_ptr = Bx | (addr & 0x03fffffc) | 0x2 | ((*buf_ptr) & 0x1);
374 }
375 }
376 else {
377 if (!(jump->flags & ABSOLUTE_B)) {
378 addr = addr - jump->addr;
379 SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000);
380 *buf_ptr = BCx | (addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001);
381 }
382 else {
383 addr = addr & ~0x3l;
384 SLJIT_ASSERT(addr <= 0xffff);
385 *buf_ptr = BCx | (addr & 0xfffc) | 0x2 | ((*buf_ptr) & 0x03ff0001);
386 }
387
388 }
389 break;
390 }
391 /* Set the fields of immediate loads. */
392 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
393 buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
394 buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
395 #else
396 buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff);
397 buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff);
398 buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff);
399 buf_ptr[4] = (buf_ptr[4] & 0xffff0000) | (addr & 0xffff);
400 #endif
401 } while (0);
402 jump = jump->next;
403 }
404
405 compiler->error = SLJIT_ERR_COMPILED;
406 compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
407 SLJIT_CACHE_FLUSH(code, code_ptr);
408
409 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
410 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
411 if (((sljit_sw)code_ptr) & 0x4)
412 code_ptr++;
413 sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code);
414 return code_ptr;
415 #else
416 sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code);
417 return code_ptr;
418 #endif
419 #else
420 return code;
421 #endif
422 }
423
424 /* --------------------------------------------------------------------- */
425 /* Entry, exit */
426 /* --------------------------------------------------------------------- */
427
428 /* inp_flags: */
429
430 /* Creates an index in data_transfer_insts array. */
431 #define LOAD_DATA 0x01
432 #define INDEXED 0x02
433 #define WRITE_BACK 0x04
434 #define WORD_DATA 0x00
435 #define BYTE_DATA 0x08
436 #define HALF_DATA 0x10
437 #define INT_DATA 0x18
438 #define SIGNED_DATA 0x20
439 /* Separates integer and floating point registers */
440 #define GPR_REG 0x3f
441 #define DOUBLE_DATA 0x40
442
443 #define MEM_MASK 0x7f
444
445 /* Other inp_flags. */
446
447 #define ARG_TEST 0x000100
448 /* Integer opertion and set flags -> requires exts on 64 bit systems. */
449 #define ALT_SIGN_EXT 0x000200
450 /* This flag affects the RC() and OERC() macros. */
451 #define ALT_SET_FLAGS 0x000400
452 #define ALT_KEEP_CACHE 0x000800
453 #define ALT_FORM1 0x010000
454 #define ALT_FORM2 0x020000
455 #define ALT_FORM3 0x040000
456 #define ALT_FORM4 0x080000
457 #define ALT_FORM5 0x100000
458 #define ALT_FORM6 0x200000
459
460 /* Source and destination is register. */
461 #define REG_DEST 0x000001
462 #define REG1_SOURCE 0x000002
463 #define REG2_SOURCE 0x000004
464 /* getput_arg_fast returned true. */
465 #define FAST_DEST 0x000008
466 /* Multiple instructions are required. */
467 #define SLOW_DEST 0x000010
468 /*
469 ALT_SIGN_EXT 0x000200
470 ALT_SET_FLAGS 0x000400
471 ALT_FORM1 0x010000
472 ...
473 ALT_FORM6 0x200000 */
474
475 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
476 #include "sljitNativePPC_32.c"
477 #else
478 #include "sljitNativePPC_64.c"
479 #endif
480
481 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
482 #define STACK_STORE STW
483 #define STACK_LOAD LWZ
484 #else
485 #define STACK_STORE STD
486 #define STACK_LOAD LD
487 #endif
488
489 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
490 {
491 CHECK_ERROR();
492 check_sljit_emit_enter(compiler, args, scratches, saveds, local_size);
493
494 compiler->scratches = scratches;
495 compiler->saveds = saveds;
496 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
497 compiler->logical_local_size = local_size;
498 #endif
499
500 FAIL_IF(push_inst(compiler, MFLR | D(0)));
501 FAIL_IF(push_inst(compiler, STACK_STORE | S(ZERO_REG) | A(SLJIT_LOCALS_REG) | IMM(-(sljit_si)(sizeof(sljit_sw))) ));
502 if (saveds >= 1)
503 FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG1) | A(SLJIT_LOCALS_REG) | IMM(-2 * (sljit_si)(sizeof(sljit_sw))) ));
504 if (saveds >= 2)
505 FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG2) | A(SLJIT_LOCALS_REG) | IMM(-3 * (sljit_si)(sizeof(sljit_sw))) ));
506 if (saveds >= 3)
507 FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG3) | A(SLJIT_LOCALS_REG) | IMM(-4 * (sljit_si)(sizeof(sljit_sw))) ));
508 if (saveds >= 4)
509 FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG1) | A(SLJIT_LOCALS_REG) | IMM(-5 * (sljit_si)(sizeof(sljit_sw))) ));
510 if (saveds >= 5)
511 FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG2) | A(SLJIT_LOCALS_REG) | IMM(-6 * (sljit_si)(sizeof(sljit_sw))) ));
512 FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_LOCALS_REG) | IMM(sizeof(sljit_sw)) ));
513
514 FAIL_IF(push_inst(compiler, ADDI | D(ZERO_REG) | A(0) | 0));
515 if (args >= 1)
516 FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG1) | A(SLJIT_SAVED_REG1) | B(SLJIT_SCRATCH_REG1)));
517 if (args >= 2)
518 FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG2) | A(SLJIT_SAVED_REG2) | B(SLJIT_SCRATCH_REG2)));
519 if (args >= 3)
520 FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG3) | A(SLJIT_SAVED_REG3) | B(SLJIT_SCRATCH_REG3)));
521
522 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
523 compiler->local_size = (1 + saveds + 6 + 8) * sizeof(sljit_sw) + local_size;
524 #else
525 compiler->local_size = (1 + saveds + 2) * sizeof(sljit_sw) + local_size;
526 #endif
527 compiler->local_size = (compiler->local_size + 15) & ~0xf;
528
529 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
530 if (compiler->local_size <= SIMM_MAX)
531 FAIL_IF(push_inst(compiler, STWU | S(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | IMM(-compiler->local_size)));
532 else {
533 FAIL_IF(load_immediate(compiler, 0, -compiler->local_size));
534 FAIL_IF(push_inst(compiler, STWUX | S(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | B(0)));
535 }
536 #else
537 if (compiler->local_size <= SIMM_MAX)
538 FAIL_IF(push_inst(compiler, STDU | S(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | IMM(-compiler->local_size)));
539 else {
540 FAIL_IF(load_immediate(compiler, 0, -compiler->local_size));
541 FAIL_IF(push_inst(compiler, STDUX | S(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | B(0)));
542 }
543 #endif
544
545 return SLJIT_SUCCESS;
546 }
547
548 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
549 {
550 CHECK_ERROR_VOID();
551 check_sljit_set_context(compiler, args, scratches, saveds, local_size);
552
553 compiler->scratches = scratches;
554 compiler->saveds = saveds;
555 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
556 compiler->logical_local_size = local_size;
557 #endif
558
559 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
560 compiler->local_size = (1 + saveds + 6 + 8) * sizeof(sljit_sw) + local_size;
561 #else
562 compiler->local_size = (1 + saveds + 2) * sizeof(sljit_sw) + local_size;
563 #endif
564 compiler->local_size = (compiler->local_size + 15) & ~0xf;
565 }
566
567 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
568 {
569 CHECK_ERROR();
570 check_sljit_emit_return(compiler, op, src, srcw);
571
572 FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
573
574 if (compiler->local_size <= SIMM_MAX)
575 FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | IMM(compiler->local_size)));
576 else {
577 FAIL_IF(load_immediate(compiler, 0, compiler->local_size));
578 FAIL_IF(push_inst(compiler, ADD | D(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | B(0)));
579 }
580
581 FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_LOCALS_REG) | IMM(sizeof(sljit_sw))));
582 if (compiler->saveds >= 5)
583 FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG2) | A(SLJIT_LOCALS_REG) | IMM(-6 * (sljit_si)(sizeof(sljit_sw))) ));
584 if (compiler->saveds >= 4)
585 FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG1) | A(SLJIT_LOCALS_REG) | IMM(-5 * (sljit_si)(sizeof(sljit_sw))) ));
586 if (compiler->saveds >= 3)
587 FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG3) | A(SLJIT_LOCALS_REG) | IMM(-4 * (sljit_si)(sizeof(sljit_sw))) ));
588 if (compiler->saveds >= 2)
589 FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG2) | A(SLJIT_LOCALS_REG) | IMM(-3 * (sljit_si)(sizeof(sljit_sw))) ));
590 if (compiler->saveds >= 1)
591 FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG1) | A(SLJIT_LOCALS_REG) | IMM(-2 * (sljit_si)(sizeof(sljit_sw))) ));
592 FAIL_IF(push_inst(compiler, STACK_LOAD | D(ZERO_REG) | A(SLJIT_LOCALS_REG) | IMM(-(sljit_si)(sizeof(sljit_sw))) ));
593
594 FAIL_IF(push_inst(compiler, MTLR | S(0)));
595 FAIL_IF(push_inst(compiler, BLR));
596
597 return SLJIT_SUCCESS;
598 }
599
600 #undef STACK_STORE
601 #undef STACK_LOAD
602
603 /* --------------------------------------------------------------------- */
604 /* Operators */
605 /* --------------------------------------------------------------------- */
606
607 /* i/x - immediate/indexed form
608 n/w - no write-back / write-back (1 bit)
609 s/l - store/load (1 bit)
610 u/s - signed/unsigned (1 bit)
611 w/b/h/i - word/byte/half/int allowed (2 bit)
612 It contans 32 items, but not all are different. */
613
614 /* 64 bit only: [reg+imm] must be aligned to 4 bytes. */
615 #define ADDR_MODE2 0x10000
616 /* 64-bit only: there is no lwau instruction. */
617 #define UPDATE_REQ 0x20000
618
619 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
620 #define ARCH_32_64(a, b) a
621 #define INST_CODE_AND_DST(inst, flags, reg) \
622 ((inst) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
623 #else
624 #define ARCH_32_64(a, b) b
625 #define INST_CODE_AND_DST(inst, flags, reg) \
626 (((inst) & ~(ADDR_MODE2 | UPDATE_REQ)) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg)))
627 #endif
628
629 static SLJIT_CONST sljit_ins data_transfer_insts[64 + 8] = {
630
631 /* -------- Unsigned -------- */
632
633 /* Word. */
634
635 /* u w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | ADDR_MODE2 | 0x0 /* std */),
636 /* u w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x0 /* ld */),
637 /* u w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
638 /* u w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
639
640 /* u w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | ADDR_MODE2 | 0x1 /* stdu */),
641 /* u w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | 0x1 /* ldu */),
642 /* u w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
643 /* u w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
644
645 /* Byte. */
646
647 /* u b n i s */ HI(38) /* stb */,
648 /* u b n i l */ HI(34) /* lbz */,
649 /* u b n x s */ HI(31) | LO(215) /* stbx */,
650 /* u b n x l */ HI(31) | LO(87) /* lbzx */,
651
652 /* u b w i s */ HI(39) /* stbu */,
653 /* u b w i l */ HI(35) /* lbzu */,
654 /* u b w x s */ HI(31) | LO(247) /* stbux */,
655 /* u b w x l */ HI(31) | LO(119) /* lbzux */,
656
657 /* Half. */
658
659 /* u h n i s */ HI(44) /* sth */,
660 /* u h n i l */ HI(40) /* lhz */,
661 /* u h n x s */ HI(31) | LO(407) /* sthx */,
662 /* u h n x l */ HI(31) | LO(279) /* lhzx */,
663
664 /* u h w i s */ HI(45) /* sthu */,
665 /* u h w i l */ HI(41) /* lhzu */,
666 /* u h w x s */ HI(31) | LO(439) /* sthux */,
667 /* u h w x l */ HI(31) | LO(311) /* lhzux */,
668
669 /* Int. */
670
671 /* u i n i s */ HI(36) /* stw */,
672 /* u i n i l */ HI(32) /* lwz */,
673 /* u i n x s */ HI(31) | LO(151) /* stwx */,
674 /* u i n x l */ HI(31) | LO(23) /* lwzx */,
675
676 /* u i w i s */ HI(37) /* stwu */,
677 /* u i w i l */ HI(33) /* lwzu */,
678 /* u i w x s */ HI(31) | LO(183) /* stwux */,
679 /* u i w x l */ HI(31) | LO(55) /* lwzux */,
680
681 /* -------- Signed -------- */
682
683 /* Word. */
684
685 /* s w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | ADDR_MODE2 | 0x0 /* std */),
686 /* s w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x0 /* ld */),
687 /* s w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
688 /* s w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
689
690 /* s w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | ADDR_MODE2 | 0x1 /* stdu */),
691 /* s w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | 0x1 /* ldu */),
692 /* s w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
693 /* s w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
694
695 /* Byte. */
696
697 /* s b n i s */ HI(38) /* stb */,
698 /* s b n i l */ HI(34) /* lbz */ /* EXTS_REQ */,
699 /* s b n x s */ HI(31) | LO(215) /* stbx */,
700 /* s b n x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */,
701
702 /* s b w i s */ HI(39) /* stbu */,
703 /* s b w i l */ HI(35) /* lbzu */ /* EXTS_REQ */,
704 /* s b w x s */ HI(31) | LO(247) /* stbux */,
705 /* s b w x l */ HI(31) | LO(119) /* lbzux */ /* EXTS_REQ */,
706
707 /* Half. */
708
709 /* s h n i s */ HI(44) /* sth */,
710 /* s h n i l */ HI(42) /* lha */,
711 /* s h n x s */ HI(31) | LO(407) /* sthx */,
712 /* s h n x l */ HI(31) | LO(343) /* lhax */,
713
714 /* s h w i s */ HI(45) /* sthu */,
715 /* s h w i l */ HI(43) /* lhau */,
716 /* s h w x s */ HI(31) | LO(439) /* sthux */,
717 /* s h w x l */ HI(31) | LO(375) /* lhaux */,
718
719 /* Int. */
720
721 /* s i n i s */ HI(36) /* stw */,
722 /* s i n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x2 /* lwa */),
723 /* s i n x s */ HI(31) | LO(151) /* stwx */,
724 /* s i n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */),
725
726 /* s i w i s */ HI(37) /* stwu */,
727 /* s i w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | UPDATE_REQ | 0x2 /* lwa */),
728 /* s i w x s */ HI(31) | LO(183) /* stwux */,
729 /* s i w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */),
730
731 /* -------- Double -------- */
732
733 /* d n i s */ HI(54) /* stfd */,
734 /* d n i l */ HI(50) /* lfd */,
735 /* d n x s */ HI(31) | LO(727) /* stfdx */,
736 /* d n x l */ HI(31) | LO(599) /* lfdx */,
737
738 /* s n i s */ HI(52) /* stfs */,
739 /* s n i l */ HI(48) /* lfs */,
740 /* s n x s */ HI(31) | LO(663) /* stfsx */,
741 /* s n x l */ HI(31) | LO(535) /* lfsx */,
742
743 };
744
745 #undef ARCH_32_64
746
747 /* Simple cases, (no caching is required). */
748 static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw)
749 {
750 sljit_ins inst;
751 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
752 sljit_si tmp_reg;
753 #endif
754
755 SLJIT_ASSERT(arg & SLJIT_MEM);
756 if (!(arg & 0xf)) {
757 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
758 if (argw <= SIMM_MAX && argw >= SIMM_MIN) {
759 if (inp_flags & ARG_TEST)
760 return 1;
761
762 inst = data_transfer_insts[(inp_flags & ~WRITE_BACK) & MEM_MASK];
763 SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
764 push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | IMM(argw));
765 return -1;
766 }
767 #else
768 inst = data_transfer_insts[(inp_flags & ~WRITE_BACK) & MEM_MASK];
769 if (argw <= SIMM_MAX && argw >= SIMM_MIN &&
770 (!(inst & ADDR_MODE2) || (argw & 0x3) == 0)) {
771 if (inp_flags & ARG_TEST)
772 return 1;
773
774 push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | IMM(argw));
775 return -1;
776 }
777 #endif
778 return 0;
779 }
780
781 if (!(arg & 0xf0)) {
782 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
783 if (argw <= SIMM_MAX && argw >= SIMM_MIN) {
784 if (inp_flags & ARG_TEST)
785 return 1;
786
787 inst = data_transfer_insts[inp_flags & MEM_MASK];
788 SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
789 push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | IMM(argw));
790 return -1;
791 }
792 #else
793 inst = data_transfer_insts[inp_flags & MEM_MASK];
794 if (argw <= SIMM_MAX && argw >= SIMM_MIN && (!(inst & ADDR_MODE2) || (argw & 0x3) == 0)) {
795 if (inp_flags & ARG_TEST)
796 return 1;
797
798 if ((inp_flags & WRITE_BACK) && (inst & UPDATE_REQ)) {
799 tmp_reg = (inp_flags & LOAD_DATA) ? (arg & 0xf) : TMP_REG3;
800 if (push_inst(compiler, ADDI | D(tmp_reg) | A(arg & 0xf) | IMM(argw)))
801 return -1;
802 arg = tmp_reg | SLJIT_MEM;
803 argw = 0;
804 }
805 push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | IMM(argw));
806 return -1;
807 }
808 #endif
809 }
810 else if (!(argw & 0x3)) {
811 if (inp_flags & ARG_TEST)
812 return 1;
813 inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
814 SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
815 push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | B((arg >> 4) & 0xf));
816 return -1;
817 }
818 return 0;
819 }
820
821 /* See getput_arg below.
822 Note: can_cache is called only for binary operators. Those operator always
823 uses word arguments without write back. */
824 static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
825 {
826 SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
827
828 if (!(arg & 0xf))
829 return (next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX);
830
831 if (arg & 0xf0)
832 return ((arg & 0xf0) == (next_arg & 0xf0) && (argw & 0x3) == (next_argw & 0x3));
833
834 if (argw <= SIMM_MAX && argw >= SIMM_MIN) {
835 if (arg == next_arg && (next_argw >= SIMM_MAX && next_argw <= SIMM_MIN))
836 return 1;
837 }
838
839 if (arg == next_arg && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX))
840 return 1;
841
842 return 0;
843 }
844
845 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
846 #define ADJUST_CACHED_IMM(imm) \
847 if ((inst & ADDR_MODE2) && (imm & 0x3)) { \
848 /* Adjust cached value. Fortunately this is really a rare case */ \
849 compiler->cache_argw += imm & 0x3; \
850 FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | (imm & 0x3))); \
851 imm &= ~0x3; \
852 }
853 #else
854 #define ADJUST_CACHED_IMM(imm)
855 #endif
856
857 /* Emit the necessary instructions. See can_cache above. */
858 static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
859 {
860 sljit_si tmp_r;
861 sljit_ins inst;
862
863 SLJIT_ASSERT(arg & SLJIT_MEM);
864
865 tmp_r = ((inp_flags & LOAD_DATA) && ((inp_flags) & MEM_MASK) <= GPR_REG) ? reg : TMP_REG1;
866 /* Special case for "mov reg, [reg, ... ]". */
867 if ((arg & 0xf) == tmp_r)
868 tmp_r = TMP_REG1;
869
870 if (!(arg & 0xf)) {
871 inst = data_transfer_insts[(inp_flags & ~WRITE_BACK) & MEM_MASK];
872 if ((compiler->cache_arg & SLJIT_IMM) && (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= SIMM_MAX || ((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= SIMM_MAX)) {
873 argw = argw - compiler->cache_argw;
874 ADJUST_CACHED_IMM(argw);
875 SLJIT_ASSERT(!(inst & UPDATE_REQ));
876 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(argw));
877 }
878
879 if ((next_arg & SLJIT_MEM) && (argw - next_argw <= SIMM_MAX || next_argw - argw <= SIMM_MAX)) {
880 SLJIT_ASSERT(inp_flags & LOAD_DATA);
881
882 compiler->cache_arg = SLJIT_IMM;
883 compiler->cache_argw = argw;
884 tmp_r = TMP_REG3;
885 }
886
887 FAIL_IF(load_immediate(compiler, tmp_r, argw));
888 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r));
889 }
890
891 if (SLJIT_UNLIKELY(arg & 0xf0)) {
892 argw &= 0x3;
893 /* Otherwise getput_arg_fast would capture it. */
894 SLJIT_ASSERT(argw);
895
896 if ((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg && argw == compiler->cache_argw)
897 tmp_r = TMP_REG3;
898 else {
899 if ((arg & 0xf0) == (next_arg & 0xf0) && argw == (next_argw & 0x3)) {
900 compiler->cache_arg = SLJIT_MEM | (arg & 0xf0);
901 compiler->cache_argw = argw;
902 tmp_r = TMP_REG3;
903 }
904 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
905 FAIL_IF(push_inst(compiler, RLWINM | S((arg >> 4) & 0xf) | A(tmp_r) | (argw << 11) | ((31 - argw) << 1)));
906 #else
907 FAIL_IF(push_inst(compiler, RLDI(tmp_r, (arg >> 4) & 0xf, argw, 63 - argw, 1)));
908 #endif
909 }
910 inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
911 SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
912 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | B(tmp_r));
913 }
914
915 inst = data_transfer_insts[inp_flags & MEM_MASK];
916
917 if (compiler->cache_arg == arg && ((sljit_uw)argw - (sljit_uw)compiler->cache_argw <= SIMM_MAX || (sljit_uw)compiler->cache_argw - (sljit_uw)argw <= SIMM_MAX)) {
918 SLJIT_ASSERT(!(inp_flags & WRITE_BACK));
919 argw = argw - compiler->cache_argw;
920 ADJUST_CACHED_IMM(argw);
921 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(argw));
922 }
923
924 if ((compiler->cache_arg & SLJIT_IMM) && compiler->cache_argw == argw) {
925 inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
926 SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
927 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | B(TMP_REG3));
928 }
929
930 if (argw == next_argw && (next_arg & SLJIT_MEM)) {
931 SLJIT_ASSERT(inp_flags & LOAD_DATA);
932 FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
933
934 compiler->cache_arg = SLJIT_IMM;
935 compiler->cache_argw = argw;
936
937 inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
938 SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
939 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | B(TMP_REG3));
940 }
941
942 if (arg == next_arg && !(inp_flags & WRITE_BACK) && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX)) {
943 SLJIT_ASSERT(inp_flags & LOAD_DATA);
944 FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
945 FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | A(TMP_REG3) | B(arg & 0xf)));
946
947 compiler->cache_arg = arg;
948 compiler->cache_argw = argw;
949
950 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3));
951 }
952
953 /* Get the indexed version instead of the normal one. */
954 inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
955 SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
956 FAIL_IF(load_immediate(compiler, tmp_r, argw));
957 return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | B(tmp_r));
958 }
959
960 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)
961 {
962 if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
963 return compiler->error;
964 return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
965 }
966
967 static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si input_flags,
968 sljit_si dst, sljit_sw dstw,
969 sljit_si src1, sljit_sw src1w,
970 sljit_si src2, sljit_sw src2w)
971 {
972 /* arg1 goes to TMP_REG1 or src reg
973 arg2 goes to TMP_REG2, imm or src reg
974 TMP_REG3 can be used for caching
975 result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
976 sljit_si dst_r;
977 sljit_si src1_r;
978 sljit_si src2_r;
979 sljit_si sugg_src2_r = TMP_REG2;
980 sljit_si flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS);
981
982 if (!(input_flags & ALT_KEEP_CACHE)) {
983 compiler->cache_arg = 0;
984 compiler->cache_argw = 0;
985 }
986
987 /* Destination check. */
988 if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
989 if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM))
990 return SLJIT_SUCCESS;
991 dst_r = TMP_REG2;
992 }
993 else if (dst <= ZERO_REG) {
994 dst_r = dst;
995 flags |= REG_DEST;
996 if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
997 sugg_src2_r = dst_r;
998 }
999 else {
1000 SLJIT_ASSERT(dst & SLJIT_MEM);
1001 if (getput_arg_fast(compiler, input_flags | ARG_TEST, TMP_REG2, dst, dstw)) {
1002 flags |= FAST_DEST;
1003 dst_r = TMP_REG2;
1004 }
1005 else {
1006 flags |= SLOW_DEST;
1007 dst_r = 0;
1008 }
1009 }
1010
1011 /* Source 1. */
1012 if (src1 <= ZERO_REG) {
1013 src1_r = src1;
1014 flags |= REG1_SOURCE;
1015 }
1016 else if (src1 & SLJIT_IMM) {
1017 FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
1018 src1_r = TMP_REG1;
1019 }
1020 else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w)) {
1021 FAIL_IF(compiler->error);
1022 src1_r = TMP_REG1;
1023 }
1024 else
1025 src1_r = 0;
1026
1027 /* Source 2. */
1028 if (src2 <= ZERO_REG) {
1029 src2_r = src2;
1030 flags |= REG2_SOURCE;
1031 if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
1032 dst_r = src2_r;
1033 }
1034 else if (src2 & SLJIT_IMM) {
1035 FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w));
1036 src2_r = sugg_src2_r;
1037 }
1038 else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) {
1039 FAIL_IF(compiler->error);
1040 src2_r = sugg_src2_r;
1041 }
1042 else
1043 src2_r = 0;
1044
1045 /* src1_r, src2_r and dst_r can be zero (=unprocessed).
1046 All arguments are complex addressing modes, and it is a binary operator. */
1047 if (src1_r == 0 && src2_r == 0 && dst_r == 0) {
1048 if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
1049 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));
1050 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
1051 }
1052 else {
1053 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
1054 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
1055 }
1056 src1_r = TMP_REG1;
1057 src2_r = TMP_REG2;
1058 }
1059 else if (src1_r == 0 && src2_r == 0) {
1060 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
1061 src1_r = TMP_REG1;
1062 }
1063 else if (src1_r == 0 && dst_r == 0) {
1064 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
1065 src1_r = TMP_REG1;
1066 }
1067 else if (src2_r == 0 && dst_r == 0) {
1068 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
1069 src2_r = sugg_src2_r;
1070 }
1071
1072 if (dst_r == 0)
1073 dst_r = TMP_REG2;
1074
1075 if (src1_r == 0) {
1076 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0));
1077 src1_r = TMP_REG1;
1078 }
1079
1080 if (src2_r == 0) {
1081 FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0));
1082 src2_r = sugg_src2_r;
1083 }
1084
1085 FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
1086
1087 if (flags & (FAST_DEST | SLOW_DEST)) {
1088 if (flags & FAST_DEST)
1089 FAIL_IF(getput_arg_fast(compiler, input_flags, dst_r, dst, dstw));
1090 else
1091 FAIL_IF(getput_arg(compiler, input_flags, dst_r, dst, dstw, 0, 0));
1092 }
1093 return SLJIT_SUCCESS;
1094 }
1095
1096 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
1097 {
1098 CHECK_ERROR();
1099 check_sljit_emit_op0(compiler, op);
1100
1101 switch (GET_OPCODE(op)) {
1102 case SLJIT_BREAKPOINT:
1103 case SLJIT_NOP:
1104 return push_inst(compiler, NOP);
1105 break;
1106 case SLJIT_UMUL:
1107 case SLJIT_SMUL:
1108 FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG1)));
1109 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1110 FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)));
1111 return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHDU : MULHD) | D(SLJIT_SCRATCH_REG2) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2));
1112 #else
1113 FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)));
1114 return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHWU : MULHW) | D(SLJIT_SCRATCH_REG2) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2));
1115 #endif
1116 case SLJIT_UDIV:
1117 case SLJIT_SDIV:
1118 FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG1)));
1119 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1120 if (op & SLJIT_INT_OP) {
1121 FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)));
1122 FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2)));
1123 return push_inst(compiler, SUBF | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG2) | B(TMP_REG1));
1124 }
1125 FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVDU : DIVD) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)));
1126 FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2)));
1127 return push_inst(compiler, SUBF | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG2) | B(TMP_REG1));
1128 #else
1129 FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)));
1130 FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2)));
1131 return push_inst(compiler, SUBF | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG2) | B(TMP_REG1));
1132 #endif
1133 }
1134
1135 return SLJIT_SUCCESS;
1136 }
1137
1138 #define EMIT_MOV(type, type_flags, type_cast) \
1139 emit_op(compiler, (src & SLJIT_IMM) ? SLJIT_MOV : type, flags | (type_flags), dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? type_cast srcw : srcw)
1140
1141 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
1142 sljit_si dst, sljit_sw dstw,
1143 sljit_si src, sljit_sw srcw)
1144 {
1145 sljit_si flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0;
1146 sljit_si op_flags = GET_ALL_FLAGS(op);
1147
1148 CHECK_ERROR();
1149 check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
1150 ADJUST_LOCAL_OFFSET(dst, dstw);
1151 ADJUST_LOCAL_OFFSET(src, srcw);
1152
1153 op = GET_OPCODE(op);
1154 if ((src & SLJIT_IMM) && srcw == 0)
1155 src = ZERO_REG;
1156
1157 if (op_flags & SLJIT_SET_O)
1158 FAIL_IF(push_inst(compiler, MTXER | S(ZERO_REG)));
1159
1160 if (op_flags & SLJIT_INT_OP) {
1161 if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) {
1162 if (src <= ZERO_REG && src == dst) {
1163 if (!TYPE_CAST_NEEDED(op))
1164 return SLJIT_SUCCESS;
1165 }
1166 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1167 if (op == SLJIT_MOV_SI && (src & SLJIT_MEM))
1168 op = SLJIT_MOV_UI;
1169 if (op == SLJIT_MOVU_SI && (src & SLJIT_MEM))
1170 op = SLJIT_MOVU_UI;
1171 if (op == SLJIT_MOV_UI && (src & SLJIT_IMM))
1172 op = SLJIT_MOV_SI;
1173 if (op == SLJIT_MOVU_UI && (src & SLJIT_IMM))
1174 op = SLJIT_MOVU_SI;
1175 #endif
1176 }
1177 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1178 else {
1179 /* Most operations expect sign extended arguments. */
1180 flags |= INT_DATA | SIGNED_DATA;
1181 if (src & SLJIT_IMM)
1182 srcw = (sljit_si)srcw;
1183 }
1184 #endif
1185 }
1186
1187 switch (op) {
1188 case SLJIT_MOV:
1189 case SLJIT_MOV_P:
1190 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1191 case SLJIT_MOV_UI:
1192 case SLJIT_MOV_SI:
1193 #endif
1194 return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
1195
1196 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1197 case SLJIT_MOV_UI:
1198 return EMIT_MOV(SLJIT_MOV_UI, INT_DATA, (sljit_ui));
1199
1200 case SLJIT_MOV_SI:
1201 return EMIT_MOV(SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, (sljit_si));
1202 #endif
1203
1204 case SLJIT_MOV_UB:
1205 return EMIT_MOV(SLJIT_MOV_UB, BYTE_DATA, (sljit_ub));
1206
1207 case SLJIT_MOV_SB:
1208 return EMIT_MOV(SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, (sljit_sb));
1209
1210 case SLJIT_MOV_UH:
1211 return EMIT_MOV(SLJIT_MOV_UH, HALF_DATA, (sljit_uh));
1212
1213 case SLJIT_MOV_SH:
1214 return EMIT_MOV(SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, (sljit_sh));
1215
1216 case SLJIT_MOVU:
1217 case SLJIT_MOVU_P:
1218 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
1219 case SLJIT_MOVU_UI:
1220 case SLJIT_MOVU_SI:
1221 #endif
1222 return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
1223
1224 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1225 case SLJIT_MOVU_UI:
1226 return EMIT_MOV(SLJIT_MOV_UI, INT_DATA | WRITE_BACK, (sljit_ui));
1227
1228 case SLJIT_MOVU_SI:
1229 return EMIT_MOV(SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, (sljit_si));
1230 #endif
1231
1232 case SLJIT_MOVU_UB:
1233 return EMIT_MOV(SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, (sljit_ub));
1234
1235 case SLJIT_MOVU_SB:
1236 return EMIT_MOV(SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, (sljit_sb));
1237
1238 case SLJIT_MOVU_UH:
1239 return EMIT_MOV(SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, (sljit_uh));
1240
1241 case SLJIT_MOVU_SH:
1242 return EMIT_MOV(SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, (sljit_sh));
1243
1244 case SLJIT_NOT:
1245 return emit_op(compiler, SLJIT_NOT, flags, dst, dstw, TMP_REG1, 0, src, srcw);
1246
1247 case SLJIT_NEG:
1248 return emit_op(compiler, SLJIT_NEG, flags, dst, dstw, TMP_REG1, 0, src, srcw);
1249
1250 case SLJIT_CLZ:
1251 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1252 return emit_op(compiler, SLJIT_CLZ, flags | (!(op_flags & SLJIT_INT_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw);
1253 #else
1254 return emit_op(compiler, SLJIT_CLZ, flags, dst, dstw, TMP_REG1, 0, src, srcw);
1255 #endif
1256 }
1257
1258 return SLJIT_SUCCESS;
1259 }
1260
1261 #undef EMIT_MOV
1262
1263 #define TEST_SL_IMM(src, srcw) \
1264 (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)
1265
1266 #define TEST_UL_IMM(src, srcw) \
1267 (((src) & SLJIT_IMM) && !((srcw) & ~0xffff))
1268
1269 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1270 #define TEST_SH_IMM(src, srcw) \
1271 (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= SLJIT_W(0x7fffffff) && (srcw) >= SLJIT_W(-0x80000000))
1272 #else
1273 #define TEST_SH_IMM(src, srcw) \
1274 (((src) & SLJIT_IMM) && !((srcw) & 0xffff))
1275 #endif
1276
1277 #define TEST_UH_IMM(src, srcw) \
1278 (((src) & SLJIT_IMM) && !((srcw) & ~0xffff0000))
1279
1280 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1281 #define TEST_ADD_IMM(src, srcw) \
1282 (((src) & SLJIT_IMM) && (srcw) <= SLJIT_W(0x7fff7fff) && (srcw) >= SLJIT_W(-0x80000000))
1283 #else
1284 #define TEST_ADD_IMM(src, srcw) \
1285 ((src) & SLJIT_IMM)
1286 #endif
1287
1288 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1289 #define TEST_UI_IMM(src, srcw) \
1290 (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff))
1291 #else
1292 #define TEST_UI_IMM(src, srcw) \
1293 ((src) & SLJIT_IMM)
1294 #endif
1295
1296 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
1297 sljit_si dst, sljit_sw dstw,
1298 sljit_si src1, sljit_sw src1w,
1299 sljit_si src2, sljit_sw src2w)
1300 {
1301 sljit_si flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0;
1302
1303 CHECK_ERROR();
1304 check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
1305 ADJUST_LOCAL_OFFSET(dst, dstw);
1306 ADJUST_LOCAL_OFFSET(src1, src1w);
1307 ADJUST_LOCAL_OFFSET(src2, src2w);
1308
1309 if ((src1 & SLJIT_IMM) && src1w == 0)
1310 src1 = ZERO_REG;
1311 if ((src2 & SLJIT_IMM) && src2w == 0)
1312 src2 = ZERO_REG;
1313
1314 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1315 if (op & SLJIT_INT_OP) {
1316 /* Most operations expect sign extended arguments. */
1317 flags |= INT_DATA | SIGNED_DATA;
1318 if (src1 & SLJIT_IMM)
1319 src1w = (sljit_si)(src1w);
1320 if (src2 & SLJIT_IMM)
1321 src2w = (sljit_si)(src2w);
1322 if (GET_FLAGS(op))
1323 flags |= ALT_SIGN_EXT;
1324 }
1325 #endif
1326 if (op & SLJIT_SET_O)
1327 FAIL_IF(push_inst(compiler, MTXER | S(ZERO_REG)));
1328 if (src2 == TMP_REG2)
1329 flags |= ALT_KEEP_CACHE;
1330
1331 switch (GET_OPCODE(op)) {
1332 case SLJIT_ADD:
1333 if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
1334 if (TEST_SL_IMM(src2, src2w)) {
1335 compiler->imm = src2w & 0xffff;
1336 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1337 }
1338 if (TEST_SL_IMM(src1, src1w)) {
1339 compiler->imm = src1w & 0xffff;
1340 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
1341 }
1342 if (TEST_SH_IMM(src2, src2w)) {
1343 compiler->imm = (src2w >> 16) & 0xffff;
1344 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1345 }
1346 if (TEST_SH_IMM(src1, src1w)) {
1347 compiler->imm = (src1w >> 16) & 0xffff;
1348 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
1349 }
1350 /* Range between -1 and -32768 is covered above. */
1351 if (TEST_ADD_IMM(src2, src2w)) {
1352 compiler->imm = src2w & 0xffffffff;
1353 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
1354 }
1355 if (TEST_ADD_IMM(src1, src1w)) {
1356 compiler->imm = src1w & 0xffffffff;
1357 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0);
1358 }
1359 }
1360 if (!(GET_FLAGS(op) & (SLJIT_SET_E | SLJIT_SET_O))) {
1361 if (TEST_SL_IMM(src2, src2w)) {
1362 compiler->imm = src2w & 0xffff;
1363 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1364 }
1365 if (TEST_SL_IMM(src1, src1w)) {
1366 compiler->imm = src1w & 0xffff;
1367 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
1368 }
1369 }
1370 return emit_op(compiler, SLJIT_ADD, flags, dst, dstw, src1, src1w, src2, src2w);
1371
1372 case SLJIT_ADDC:
1373 return emit_op(compiler, SLJIT_ADDC, flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w);
1374
1375 case SLJIT_SUB:
1376 if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
1377 if (TEST_SL_IMM(src2, -src2w)) {
1378 compiler->imm = (-src2w) & 0xffff;
1379 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1380 }
1381 if (TEST_SL_IMM(src1, src1w)) {
1382 compiler->imm = src1w & 0xffff;
1383 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
1384 }
1385 if (TEST_SH_IMM(src2, -src2w)) {
1386 compiler->imm = ((-src2w) >> 16) & 0xffff;
1387 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1388 }
1389 /* Range between -1 and -32768 is covered above. */
1390 if (TEST_ADD_IMM(src2, -src2w)) {
1391 compiler->imm = -src2w & 0xffffffff;
1392 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
1393 }
1394 }
1395 if (dst == SLJIT_UNUSED && (op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U)) && !(op & (SLJIT_SET_O | SLJIT_SET_C))) {
1396 if (!(op & SLJIT_SET_U)) {
1397 /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */
1398 if (TEST_SL_IMM(src2, src2w)) {
1399 compiler->imm = src2w & 0xffff;
1400 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1401 }
1402 if (GET_FLAGS(op) == SLJIT_SET_E && TEST_SL_IMM(src1, src1w)) {
1403 compiler->imm = src1w & 0xffff;
1404 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
1405 }
1406 }
1407 if (!(op & (SLJIT_SET_E | SLJIT_SET_S))) {
1408 /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */
1409 if (TEST_UL_IMM(src2, src2w)) {
1410 compiler->imm = src2w & 0xffff;
1411 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1412 }
1413 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w);
1414 }
1415 if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= 0x7fff) {
1416 compiler->imm = src2w;
1417 return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1418 }
1419 return emit_op(compiler, SLJIT_SUB, flags | ((op & SLJIT_SET_U) ? ALT_FORM4 : 0) | ((op & (SLJIT_SET_E | SLJIT_SET_S)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w);
1420 }
1421 if (!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O))) {
1422 if (TEST_SL_IMM(src2, -src2w)) {
1423 compiler->imm = (-src2w) & 0xffff;
1424 return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1425 }
1426 }
1427 /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */
1428 return emit_op(compiler, SLJIT_SUB, flags | (!(op & SLJIT_SET_U) ? 0 : ALT_FORM6), dst, dstw, src1, src1w, src2, src2w);
1429
1430 case SLJIT_SUBC:
1431 return emit_op(compiler, SLJIT_SUBC, flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w);
1432
1433 case SLJIT_MUL:
1434 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1435 if (op & SLJIT_INT_OP)
1436 flags |= ALT_FORM2;
1437 #endif
1438 if (!GET_FLAGS(op)) {
1439 if (TEST_SL_IMM(src2, src2w)) {
1440 compiler->imm = src2w & 0xffff;
1441 return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1442 }
1443 if (TEST_SL_IMM(src1, src1w)) {
1444 compiler->imm = src1w & 0xffff;
1445 return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
1446 }
1447 }
1448 return emit_op(compiler, SLJIT_MUL, flags, dst, dstw, src1, src1w, src2, src2w);
1449
1450 case SLJIT_AND:
1451 case SLJIT_OR:
1452 case SLJIT_XOR:
1453 /* Commutative unsigned operations. */
1454 if (!GET_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) {
1455 if (TEST_UL_IMM(src2, src2w)) {
1456 compiler->imm = src2w;
1457 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1458 }
1459 if (TEST_UL_IMM(src1, src1w)) {
1460 compiler->imm = src1w;
1461 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
1462 }
1463 if (TEST_UH_IMM(src2, src2w)) {
1464 compiler->imm = (src2w >> 16) & 0xffff;
1465 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
1466 }
1467 if (TEST_UH_IMM(src1, src1w)) {
1468 compiler->imm = (src1w >> 16) & 0xffff;
1469 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
1470 }
1471 }
1472 if (!GET_FLAGS(op) && GET_OPCODE(op) != SLJIT_AND) {
1473 if (TEST_UI_IMM(src2, src2w)) {
1474 compiler->imm = src2w;
1475 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
1476 }
1477 if (TEST_UI_IMM(src1, src1w)) {
1478 compiler->imm = src1w;
1479 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
1480 }
1481 }
1482 return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);
1483
1484 case SLJIT_ASHR:
1485 if (op & SLJIT_KEEP_FLAGS)
1486 flags |= ALT_FORM3;
1487 /* Fall through. */
1488 case SLJIT_SHL:
1489 case SLJIT_LSHR:
1490 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1491 if (op & SLJIT_INT_OP)
1492 flags |= ALT_FORM2;
1493 #endif
1494 if (src2 & SLJIT_IMM) {
1495 compiler->imm = src2w;
1496 return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
1497 }
1498 return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w);
1499 }
1500
1501 return SLJIT_SUCCESS;
1502 }
1503
1504 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
1505 {
1506 check_sljit_get_register_index(reg);
1507 return reg_map[reg];
1508 }
1509
1510 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
1511 {
1512 check_sljit_get_float_register_index(reg);
1513 return reg;
1514 }
1515
1516 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
1517 void *instruction, sljit_si size)
1518 {
1519 CHECK_ERROR();
1520 check_sljit_emit_op_custom(compiler, instruction, size);
1521 SLJIT_ASSERT(size == 4);
1522
1523 return push_inst(compiler, *(sljit_ins*)instruction);
1524 }
1525
1526 /* --------------------------------------------------------------------- */
1527 /* Floating point operators */
1528 /* --------------------------------------------------------------------- */
1529
1530 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
1531 {
1532 /* Always available. */
1533 return 1;
1534 }
1535
1536 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 6))
1537 #define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double)
1538
1539 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
1540 sljit_si dst, sljit_sw dstw,
1541 sljit_si src, sljit_sw srcw)
1542 {
1543 sljit_si dst_fr;
1544
1545 CHECK_ERROR();
1546 check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
1547 SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error);
1548
1549 compiler->cache_arg = 0;
1550 compiler->cache_argw = 0;
1551
1552 if (GET_OPCODE(op) == SLJIT_CMPD) {
1553 if (dst > SLJIT_FLOAT_REG6) {
1554 FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, dst, dstw, src, srcw));
1555 dst = TMP_FREG1;
1556 }
1557
1558 if (src > SLJIT_FLOAT_REG6) {
1559 FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src, srcw, 0, 0));
1560 src = TMP_FREG2;
1561 }
1562
1563 return push_inst(compiler, FCMPU | CRD(4) | FA(dst) | FB(src));
1564 }
1565
1566 dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : dst;
1567
1568 if (src > SLJIT_FLOAT_REG6) {
1569 FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_fr, src, srcw, dst, dstw));
1570 src = dst_fr;
1571 }
1572
1573 switch (GET_OPCODE(op)) {
1574 case SLJIT_MOVD:
1575 if (src != dst_fr && dst_fr != TMP_FREG1)
1576 FAIL_IF(push_inst(compiler, FMR | FD(dst_fr) | FB(src)));
1577 break;
1578 case SLJIT_NEGD:
1579 FAIL_IF(push_inst(compiler, FNEG | FD(dst_fr) | FB(src)));
1580 break;
1581 case SLJIT_ABSD:
1582 FAIL_IF(push_inst(compiler, FABS | FD(dst_fr) | FB(src)));
1583 break;
1584 }
1585
1586 if (dst_fr == TMP_FREG1) {
1587 if (GET_OPCODE(op) == SLJIT_MOVD)
1588 dst_fr = src;
1589 FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_fr, dst, dstw, 0, 0));
1590 }
1591
1592 return SLJIT_SUCCESS;
1593 }
1594
1595 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
1596 sljit_si dst, sljit_sw dstw,
1597 sljit_si src1, sljit_sw src1w,
1598 sljit_si src2, sljit_sw src2w)
1599 {
1600 sljit_si dst_fr, flags = 0;
1601
1602 CHECK_ERROR();
1603 check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
1604
1605 compiler->cache_arg = 0;
1606 compiler->cache_argw = 0;
1607
1608 dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG2 : dst;
1609
1610 if (src1 > SLJIT_FLOAT_REG6) {
1611 if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {
1612 FAIL_IF(compiler->error);
1613 src1 = TMP_FREG1;
1614 } else
1615 flags |= ALT_FORM1;
1616 }
1617
1618 if (src2 > SLJIT_FLOAT_REG6) {
1619 if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) {
1620 FAIL_IF(compiler->error);
1621 src2 = TMP_FREG2;
1622 } else
1623 flags |= ALT_FORM2;
1624 }
1625
1626 if ((flags & (ALT_FORM1 | ALT_FORM2)) == (ALT_FORM1 | ALT_FORM2)) {
1627 if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
1628 FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w));
1629 FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
1630 }
1631 else {
1632 FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
1633 FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
1634 }
1635 }
1636 else if (flags & ALT_FORM1)
1637 FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
1638 else if (flags & ALT_FORM2)
1639 FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
1640
1641 if (flags & ALT_FORM1)
1642 src1 = TMP_FREG1;
1643 if (flags & ALT_FORM2)
1644 src2 = TMP_FREG2;
1645
1646 switch (GET_OPCODE(op)) {
1647 case SLJIT_ADDD:
1648 FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_fr) | FA(src1) | FB(src2)));
1649 break;
1650
1651 case SLJIT_SUBD:
1652 FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_fr) | FA(src1) | FB(src2)));
1653 break;
1654
1655 case SLJIT_MULD:
1656 FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_fr) | FA(src1) | FC(src2) /* FMUL use FC as src2 */));
1657 break;
1658
1659 case SLJIT_DIVD:
1660 FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_fr) | FA(src1) | FB(src2)));
1661 break;
1662 }
1663
1664 if (dst_fr == TMP_FREG2)
1665 FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));
1666
1667 return SLJIT_SUCCESS;
1668 }
1669
1670 #undef FLOAT_DATA
1671 #undef SELECT_FOP
1672
1673 /* --------------------------------------------------------------------- */
1674 /* Other instructions */
1675 /* --------------------------------------------------------------------- */
1676
1677 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
1678 {
1679 CHECK_ERROR();
1680 check_sljit_emit_fast_enter(compiler, dst, dstw);
1681 ADJUST_LOCAL_OFFSET(dst, dstw);
1682
1683 /* For UNUSED dst. Uncommon, but possible. */
1684 if (dst == SLJIT_UNUSED)
1685 return SLJIT_SUCCESS;
1686
1687 if (dst <= ZERO_REG)
1688 return push_inst(compiler, MFLR | D(dst));
1689
1690 /* Memory. */
1691 FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2)));
1692 return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
1693 }
1694
1695 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
1696 {
1697 CHECK_ERROR();
1698 check_sljit_emit_fast_return(compiler, src, srcw);
1699 ADJUST_LOCAL_OFFSET(src, srcw);
1700
1701 if (src <= ZERO_REG)
1702 FAIL_IF(push_inst(compiler, MTLR | S(src)));
1703 else {
1704 if (src & SLJIT_MEM)
1705 FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
1706 else if (src & SLJIT_IMM)
1707 FAIL_IF(load_immediate(compiler, TMP_REG2, srcw));
1708 FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2)));
1709 }
1710 return push_inst(compiler, BLR);
1711 }
1712
1713 /* --------------------------------------------------------------------- */
1714 /* Conditional instructions */
1715 /* --------------------------------------------------------------------- */
1716
1717 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
1718 {
1719 struct sljit_label *label;
1720
1721 CHECK_ERROR_PTR();
1722 check_sljit_emit_label(compiler);
1723
1724 if (compiler->last_label && compiler->last_label->size == compiler->size)
1725 return compiler->last_label;
1726
1727 label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
1728 PTR_FAIL_IF(!label);
1729 set_label(label, compiler);
1730 return label;
1731 }
1732
1733 static sljit_ins get_bo_bi_flags(sljit_si type)
1734 {
1735 switch (type) {
1736 case SLJIT_C_EQUAL:
1737 return (12 << 21) | (2 << 16);
1738
1739 case SLJIT_C_NOT_EQUAL:
1740 return (4 << 21) | (2 << 16);
1741
1742 case SLJIT_C_LESS:
1743 case SLJIT_C_FLOAT_LESS:
1744 return (12 << 21) | ((4 + 0) << 16);
1745
1746 case SLJIT_C_GREATER_EQUAL:
1747 case SLJIT_C_FLOAT_GREATER_EQUAL:
1748 return (4 << 21) | ((4 + 0) << 16);
1749
1750 case SLJIT_C_GREATER:
1751 case SLJIT_C_FLOAT_GREATER:
1752 return (12 << 21) | ((4 + 1) << 16);
1753
1754 case SLJIT_C_LESS_EQUAL:
1755 case SLJIT_C_FLOAT_LESS_EQUAL:
1756 return (4 << 21) | ((4 + 1) << 16);
1757
1758 case SLJIT_C_SIG_LESS:
1759 return (12 << 21) | (0 << 16);
1760
1761 case SLJIT_C_SIG_GREATER_EQUAL:
1762 return (4 << 21) | (0 << 16);
1763
1764 case SLJIT_C_SIG_GREATER:
1765 return (12 << 21) | (1 << 16);
1766
1767 case SLJIT_C_SIG_LESS_EQUAL:
1768 return (4 << 21) | (1 << 16);
1769
1770 case SLJIT_C_OVERFLOW:
1771 case SLJIT_C_MUL_OVERFLOW:
1772 return (12 << 21) | (3 << 16);
1773
1774 case SLJIT_C_NOT_OVERFLOW:
1775 case SLJIT_C_MUL_NOT_OVERFLOW:
1776 return (4 << 21) | (3 << 16);
1777
1778 case SLJIT_C_FLOAT_EQUAL:
1779 return (12 << 21) | ((4 + 2) << 16);
1780
1781 case SLJIT_C_FLOAT_NOT_EQUAL:
1782 return (4 << 21) | ((4 + 2) << 16);
1783
1784 case SLJIT_C_FLOAT_UNORDERED:
1785 return (12 << 21) | ((4 + 3) << 16);
1786
1787 case SLJIT_C_FLOAT_ORDERED:
1788 return (4 << 21) | ((4 + 3) << 16);
1789
1790 default:
1791 SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
1792 return (20 << 21);
1793 }
1794 }
1795
1796 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type)
1797 {
1798 struct sljit_jump *jump;
1799 sljit_ins bo_bi_flags;
1800
1801 CHECK_ERROR_PTR();
1802 check_sljit_emit_jump(compiler, type);
1803
1804 bo_bi_flags = get_bo_bi_flags(type & 0xff);
1805 if (!bo_bi_flags)
1806 return NULL;
1807
1808 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
1809 PTR_FAIL_IF(!jump);
1810 set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
1811 type &= 0xff;
1812
1813 /* In PPC, we don't need to touch the arguments. */
1814 if (type >= SLJIT_JUMP)
1815 jump->flags |= UNCOND_B;
1816
1817 PTR_FAIL_IF(emit_const(compiler, TMP_REG1, 0));
1818 PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_REG1)));
1819 jump->addr = compiler->size;
1820 PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0)));
1821 return jump;
1822 }
1823
1824 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw)
1825 {
1826 struct sljit_jump *jump = NULL;
1827 sljit_si src_r;
1828
1829 CHECK_ERROR();
1830 check_sljit_emit_ijump(compiler, type, src, srcw);
1831 ADJUST_LOCAL_OFFSET(src, srcw);
1832
1833 if (src <= ZERO_REG)
1834 src_r = src;
1835 else if (src & SLJIT_IMM) {
1836 jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
1837 FAIL_IF(!jump);
1838 set_jump(jump, compiler, JUMP_ADDR | UNCOND_B);
1839 jump->u.target = srcw;
1840
1841 FAIL_IF(emit_const(compiler, TMP_REG2, 0));
1842 src_r = TMP_REG2;
1843 }
1844 else {
1845 FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
1846 src_r = TMP_REG2;
1847 }
1848
1849 FAIL_IF(push_inst(compiler, MTCTR | S(src_r)));
1850 if (jump)
1851 jump->addr = compiler->size;
1852 return push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0));
1853 }
1854
1855 /* Get a bit from CR, all other bits are zeroed. */
1856 #define GET_CR_BIT(bit, dst) \
1857 FAIL_IF(push_inst(compiler, MFCR | D(dst))); \
1858 FAIL_IF(push_inst(compiler, RLWINM | S(dst) | A(dst) | ((1 + (bit)) << 11) | (31 << 6) | (31 << 1)));
1859
1860 #define INVERT_BIT(dst) \
1861 FAIL_IF(push_inst(compiler, XORI | S(dst) | A(dst) | 0x1));
1862
1863 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op,
1864 sljit_si dst, sljit_sw dstw,
1865 sljit_si src, sljit_sw srcw,
1866 sljit_si type)
1867 {
1868 sljit_si reg, input_flags;
1869 sljit_si flags = GET_ALL_FLAGS(op);
1870
1871 CHECK_ERROR();
1872 check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type);
1873 ADJUST_LOCAL_OFFSET(dst, dstw);
1874
1875 if (dst == SLJIT_UNUSED)
1876 return SLJIT_SUCCESS;
1877
1878 op = GET_OPCODE(op);
1879 reg = (op < SLJIT_ADD && dst <= ZERO_REG) ? dst : TMP_REG2;
1880
1881 compiler->cache_arg = 0;
1882 compiler->cache_argw = 0;
1883 if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
1884 ADJUST_LOCAL_OFFSET(src, srcw);
1885 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1886 input_flags = (flags & SLJIT_INT_OP) ? INT_DATA : WORD_DATA;
1887 #else
1888 input_flags = WORD_DATA;
1889 #endif
1890 FAIL_IF(emit_op_mem2(compiler, input_flags | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw));
1891 src = TMP_REG1;
1892 srcw = 0;
1893 }
1894
1895 switch (type) {
1896 case SLJIT_C_EQUAL:
1897 GET_CR_BIT(2, reg);
1898 break;
1899
1900 case SLJIT_C_NOT_EQUAL:
1901 GET_CR_BIT(2, reg);
1902 INVERT_BIT(reg);
1903 break;
1904
1905 case SLJIT_C_LESS:
1906 case SLJIT_C_FLOAT_LESS:
1907 GET_CR_BIT(4 + 0, reg);
1908 break;
1909
1910 case SLJIT_C_GREATER_EQUAL:
1911 case SLJIT_C_FLOAT_GREATER_EQUAL:
1912 GET_CR_BIT(4 + 0, reg);
1913 INVERT_BIT(reg);
1914 break;
1915
1916 case SLJIT_C_GREATER:
1917 case SLJIT_C_FLOAT_GREATER:
1918 GET_CR_BIT(4 + 1, reg);
1919 break;
1920
1921 case SLJIT_C_LESS_EQUAL:
1922 case SLJIT_C_FLOAT_LESS_EQUAL:
1923 GET_CR_BIT(4 + 1, reg);
1924 INVERT_BIT(reg);
1925 break;
1926
1927 case SLJIT_C_SIG_LESS:
1928 GET_CR_BIT(0, reg);
1929 break;
1930
1931 case SLJIT_C_SIG_GREATER_EQUAL:
1932 GET_CR_BIT(0, reg);
1933 INVERT_BIT(reg);
1934 break;
1935
1936 case SLJIT_C_SIG_GREATER:
1937 GET_CR_BIT(1, reg);
1938 break;
1939
1940 case SLJIT_C_SIG_LESS_EQUAL:
1941 GET_CR_BIT(1, reg);
1942 INVERT_BIT(reg);
1943 break;
1944
1945 case SLJIT_C_OVERFLOW:
1946 case SLJIT_C_MUL_OVERFLOW:
1947 GET_CR_BIT(3, reg);
1948 break;
1949
1950 case SLJIT_C_NOT_OVERFLOW:
1951 case SLJIT_C_MUL_NOT_OVERFLOW:
1952 GET_CR_BIT(3, reg);
1953 INVERT_BIT(reg);
1954 break;
1955
1956 case SLJIT_C_FLOAT_EQUAL:
1957 GET_CR_BIT(4 + 2, reg);
1958 break;
1959
1960 case SLJIT_C_FLOAT_NOT_EQUAL:
1961 GET_CR_BIT(4 + 2, reg);
1962 INVERT_BIT(reg);
1963 break;
1964
1965 case SLJIT_C_FLOAT_UNORDERED:
1966 GET_CR_BIT(4 + 3, reg);
1967 break;
1968
1969 case SLJIT_C_FLOAT_ORDERED:
1970 GET_CR_BIT(4 + 3, reg);
1971 INVERT_BIT(reg);
1972 break;
1973
1974 default:
1975 SLJIT_ASSERT_STOP();
1976 break;
1977 }
1978
1979 if (op < SLJIT_ADD) {
1980 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
1981 if (op == SLJIT_MOV)
1982 input_flags = WORD_DATA;
1983 else {
1984 op = SLJIT_MOV_UI;
1985 input_flags = INT_DATA;
1986 }
1987 #else
1988 op = SLJIT_MOV;
1989 input_flags = WORD_DATA;
1990 #endif
1991 return (reg == TMP_REG2) ? emit_op(compiler, op, input_flags, dst, dstw, TMP_REG1, 0, TMP_REG2, 0) : SLJIT_SUCCESS;
1992 }
1993
1994 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1995 compiler->skip_checks = 1;
1996 #endif
1997 return sljit_emit_op2(compiler, op | flags, dst, dstw, src, srcw, TMP_REG2, 0);
1998 }
1999
2000 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)
2001 {
2002 struct sljit_const *const_;
2003 sljit_si reg;
2004
2005 CHECK_ERROR_PTR();
2006 check_sljit_emit_const(compiler, dst, dstw, init_value);
2007 ADJUST_LOCAL_OFFSET(dst, dstw);
2008
2009 const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
2010 PTR_FAIL_IF(!const_);
2011 set_const(const_, compiler);
2012
2013 reg = (dst <= ZERO_REG) ? dst : TMP_REG2;
2014
2015 PTR_FAIL_IF(emit_const(compiler, reg, init_value));
2016
2017 if (dst & SLJIT_MEM)
2018 PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
2019 return const_;
2020 }

  ViewVC Help
Powered by ViewVC 1.1.5