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

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12