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

  ViewVC Help
Powered by ViewVC 1.1.5