QtBase  v6.3.1
sljitNativePPC_64.c
Go to the documentation of this file.
1 /*
2  * Stack-less Just-In-Time compiler
3  *
4  * Copyright 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 /* ppc 64-bit arch dependent functions. */
28 
29 #if defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)
30 #define ASM_SLJIT_CLZ(src, dst) \
31  __asm__ volatile ( "cntlzd %0, %1" : "=r"(dst) : "r"(src) )
32 #elif defined(__xlc__)
33 #error "Please enable GCC syntax for inline assembly statements"
34 #else
35 #error "Must implement count leading zeroes"
36 #endif
37 
38 #define PUSH_RLDICR(reg, shift) \
39  push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1))
40 
41 static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)
42 {
43  sljit_uw tmp;
45  sljit_uw tmp2;
46  sljit_uw shift2;
47 
48  if (imm <= SIMM_MAX && imm >= SIMM_MIN)
49  return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));
50 
51  if (!(imm & ~0xffff))
52  return push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm));
53 
54  if (imm <= 0x7fffffffl && imm >= -0x80000000l) {
55  FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16)));
56  return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;
57  }
58 
59  /* Count leading zeroes. */
60  tmp = (sljit_uw)((imm >= 0) ? imm : ~imm);
61  ASM_SLJIT_CLZ(tmp, shift);
62  SLJIT_ASSERT(shift > 0);
63  shift--;
64  tmp = ((sljit_uw)imm << shift);
65 
66  if ((tmp & ~0xffff000000000000ul) == 0) {
67  FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | (sljit_ins)(tmp >> 48)));
68  shift += 15;
69  return PUSH_RLDICR(reg, shift);
70  }
71 
72  if ((tmp & ~0xffffffff00000000ul) == 0) {
73  FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | (sljit_ins)(tmp >> 48)));
74  FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp >> 32)));
75  shift += 31;
76  return PUSH_RLDICR(reg, shift);
77  }
78 
79  /* Cut out the 16 bit from immediate. */
80  shift += 15;
81  tmp2 = (sljit_uw)imm & (((sljit_uw)1 << (63 - shift)) - 1);
82 
83  if (tmp2 <= 0xffff) {
84  FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | (sljit_ins)(tmp >> 48)));
85  FAIL_IF(PUSH_RLDICR(reg, shift));
86  return push_inst(compiler, ORI | S(reg) | A(reg) | (sljit_ins)tmp2);
87  }
88 
89  if (tmp2 <= 0xffffffff) {
90  FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
91  FAIL_IF(PUSH_RLDICR(reg, shift));
92  FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | (sljit_ins)(tmp2 >> 16)));
93  return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp2)) : SLJIT_SUCCESS;
94  }
95 
96  ASM_SLJIT_CLZ(tmp2, shift2);
97  tmp2 <<= shift2;
98 
99  if ((tmp2 & ~0xffff000000000000ul) == 0) {
100  FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | (sljit_ins)(tmp >> 48)));
101  shift2 += 15;
102  shift += (63 - shift2);
103  FAIL_IF(PUSH_RLDICR(reg, shift));
104  FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | (sljit_ins)(tmp2 >> 48)));
105  return PUSH_RLDICR(reg, shift2);
106  }
107 
108  /* The general version. */
109  FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | (sljit_ins)((sljit_uw)imm >> 48)));
110  FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm >> 32)));
111  FAIL_IF(PUSH_RLDICR(reg, 31));
112  FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(imm >> 16)));
113  return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm));
114 }
115 
116 /* Simplified mnemonics: clrldi. */
117 #define INS_CLEAR_LEFT(dst, src, from) \
118  (RLDICL | S(src) | A(dst) | ((from) << 6) | (1 << 5))
119 
120 /* Sign extension for integer operations. */
121 #define UN_EXTS() \
122  if ((flags & (ALT_SIGN_EXT | REG2_SOURCE)) == (ALT_SIGN_EXT | REG2_SOURCE)) { \
123  FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \
124  src2 = TMP_REG2; \
125  }
126 
127 #define BIN_EXTS() \
128  if (flags & ALT_SIGN_EXT) { \
129  if (flags & REG1_SOURCE) { \
130  FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \
131  src1 = TMP_REG1; \
132  } \
133  if (flags & REG2_SOURCE) { \
134  FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \
135  src2 = TMP_REG2; \
136  } \
137  }
138 
139 #define BIN_IMM_EXTS() \
140  if ((flags & (ALT_SIGN_EXT | REG1_SOURCE)) == (ALT_SIGN_EXT | REG1_SOURCE)) { \
141  FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \
142  src1 = TMP_REG1; \
143  }
144 
145 static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
146  sljit_s32 dst, sljit_s32 src1, sljit_s32 src2)
147 {
148  switch (op) {
149  case SLJIT_MOV:
150  case SLJIT_MOV_P:
151  SLJIT_ASSERT(src1 == TMP_REG1);
152  if (dst != src2)
153  return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));
154  return SLJIT_SUCCESS;
155 
156  case SLJIT_MOV_U32:
157  case SLJIT_MOV_S32:
158  SLJIT_ASSERT(src1 == TMP_REG1);
159  if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
160  if (op == SLJIT_MOV_S32)
161  return push_inst(compiler, EXTSW | S(src2) | A(dst));
162  return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 0));
163  }
164  else {
165  SLJIT_ASSERT(dst == src2);
166  }
167  return SLJIT_SUCCESS;
168 
169  case SLJIT_MOV_U8:
170  case SLJIT_MOV_S8:
171  SLJIT_ASSERT(src1 == TMP_REG1);
172  if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
173  if (op == SLJIT_MOV_S8)
174  return push_inst(compiler, EXTSB | S(src2) | A(dst));
175  return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));
176  }
177  else if ((flags & REG_DEST) && op == SLJIT_MOV_S8)
178  return push_inst(compiler, EXTSB | S(src2) | A(dst));
179  else {
180  SLJIT_ASSERT(dst == src2);
181  }
182  return SLJIT_SUCCESS;
183 
184  case SLJIT_MOV_U16:
185  case SLJIT_MOV_S16:
186  SLJIT_ASSERT(src1 == TMP_REG1);
187  if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
188  if (op == SLJIT_MOV_S16)
189  return push_inst(compiler, EXTSH | S(src2) | A(dst));
190  return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));
191  }
192  else {
193  SLJIT_ASSERT(dst == src2);
194  }
195  return SLJIT_SUCCESS;
196 
197  case SLJIT_NOT:
198  SLJIT_ASSERT(src1 == TMP_REG1);
199  UN_EXTS();
200  return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
201 
202  case SLJIT_CLZ:
203  SLJIT_ASSERT(src1 == TMP_REG1);
204  if (flags & ALT_FORM1)
205  return push_inst(compiler, CNTLZW | S(src2) | A(dst));
206  return push_inst(compiler, CNTLZD | S(src2) | A(dst));
207 
208  case SLJIT_ADD:
209  if (flags & ALT_FORM1) {
210  if (flags & ALT_SIGN_EXT) {
211  FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, src1, 32, 31, 1)));
212  src1 = TMP_REG1;
213  FAIL_IF(push_inst(compiler, RLDI(TMP_REG2, src2, 32, 31, 1)));
214  src2 = TMP_REG2;
215  }
216  /* Setting XER SO is not enough, CR SO is also needed. */
217  FAIL_IF(push_inst(compiler, ADD | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2)));
218  if (flags & ALT_SIGN_EXT)
219  return push_inst(compiler, RLDI(dst, dst, 32, 32, 0));
220  return SLJIT_SUCCESS;
221  }
222 
223  if (flags & ALT_FORM2) {
224  /* Flags does not set: BIN_IMM_EXTS unnecessary. */
225  SLJIT_ASSERT(src2 == TMP_REG2);
226 
227  if (flags & ALT_FORM3)
228  return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);
229 
230  if (flags & ALT_FORM4) {
231  FAIL_IF(push_inst(compiler, ADDIS | D(dst) | A(src1) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1))));
232  src1 = dst;
233  }
234 
235  return push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff));
236  }
237  if (flags & ALT_FORM3) {
238  SLJIT_ASSERT(src2 == TMP_REG2);
239  BIN_IMM_EXTS();
240  return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm);
241  }
242  if (flags & ALT_FORM4) {
243  if (flags & ALT_FORM5)
244  FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm));
245  else
246  FAIL_IF(push_inst(compiler, ADD | D(dst) | A(src1) | B(src2)));
247  return push_inst(compiler, CMPI | A(dst) | 0);
248  }
249  if (!(flags & ALT_SET_FLAGS))
250  return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));
251  BIN_EXTS();
252  if (flags & ALT_FORM5)
253  return push_inst(compiler, ADDC | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
254  return push_inst(compiler, ADD | RC(flags) | D(dst) | A(src1) | B(src2));
255 
256  case SLJIT_ADDC:
257  BIN_EXTS();
258  return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2));
259 
260  case SLJIT_SUB:
261  if (flags & ALT_FORM1) {
262  if (flags & ALT_FORM2) {
263  FAIL_IF(push_inst(compiler, CMPLI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm));
264  if (!(flags & ALT_FORM3))
265  return SLJIT_SUCCESS;
266  return push_inst(compiler, ADDI | D(dst) | A(src1) | (-compiler->imm & 0xffff));
267  }
268  FAIL_IF(push_inst(compiler, CMPL | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)));
269  if (!(flags & ALT_FORM3))
270  return SLJIT_SUCCESS;
271  return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
272  }
273 
274  if (flags & ALT_FORM2) {
275  if (flags & ALT_FORM3) {
276  FAIL_IF(push_inst(compiler, CMPI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm));
277  if (!(flags & ALT_FORM4))
278  return SLJIT_SUCCESS;
279  return push_inst(compiler, ADDI | D(dst) | A(src1) | (-compiler->imm & 0xffff));
280  }
281  FAIL_IF(push_inst(compiler, CMP | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)));
282  if (!(flags & ALT_FORM4))
283  return SLJIT_SUCCESS;
284  return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
285  }
286 
287  if (flags & ALT_FORM3) {
288  if (flags & ALT_SIGN_EXT) {
289  if (src1 != TMP_ZERO) {
290  FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, src1, 32, 31, 1)));
291  src1 = TMP_REG1;
292  }
293  if (src2 != TMP_ZERO) {
294  FAIL_IF(push_inst(compiler, RLDI(TMP_REG2, src2, 32, 31, 1)));
295  src2 = TMP_REG2;
296  }
297  }
298 
299  /* Setting XER SO is not enough, CR SO is also needed. */
300  if (src1 != TMP_ZERO)
301  FAIL_IF(push_inst(compiler, SUBF | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1)));
302  else
303  FAIL_IF(push_inst(compiler, NEG | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src2)));
304 
305  if (flags & ALT_SIGN_EXT)
306  return push_inst(compiler, RLDI(dst, dst, 32, 32, 0));
307  return SLJIT_SUCCESS;
308  }
309 
310  if (flags & ALT_FORM4) {
311  /* Flags does not set: BIN_IMM_EXTS unnecessary. */
312  SLJIT_ASSERT(src2 == TMP_REG2);
313  return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm);
314  }
315 
316  if (!(flags & ALT_SET_FLAGS)) {
317  SLJIT_ASSERT(src1 != TMP_ZERO);
318  return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
319  }
320 
321  BIN_EXTS();
322  if (flags & ALT_FORM5)
323  return push_inst(compiler, SUBFC | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
324 
325  if (src1 != TMP_ZERO)
326  return push_inst(compiler, SUBF | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
327  return push_inst(compiler, NEG | RC(ALT_SET_FLAGS) | D(dst) | A(src2));
328 
329  case SLJIT_SUBC:
330  BIN_EXTS();
331  return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1));
332 
333  case SLJIT_MUL:
334  if (flags & ALT_FORM1) {
335  SLJIT_ASSERT(src2 == TMP_REG2);
336  return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm);
337  }
338  BIN_EXTS();
339  if (flags & ALT_FORM2)
340  return push_inst(compiler, MULLW | OE(flags) | RC(flags) | D(dst) | A(src2) | B(src1));
341  return push_inst(compiler, MULLD | OE(flags) | RC(flags) | D(dst) | A(src2) | B(src1));
342 
343  case SLJIT_AND:
344  if (flags & ALT_FORM1) {
345  SLJIT_ASSERT(src2 == TMP_REG2);
346  return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm);
347  }
348  if (flags & ALT_FORM2) {
349  SLJIT_ASSERT(src2 == TMP_REG2);
350  return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm);
351  }
352  return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2));
353 
354  case SLJIT_OR:
355  if (flags & ALT_FORM1) {
356  SLJIT_ASSERT(src2 == TMP_REG2);
357  return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm);
358  }
359  if (flags & ALT_FORM2) {
360  SLJIT_ASSERT(src2 == TMP_REG2);
361  return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm);
362  }
363  if (flags & ALT_FORM3) {
364  SLJIT_ASSERT(src2 == TMP_REG2);
365  FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm)));
366  return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));
367  }
368  return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2));
369 
370  case SLJIT_XOR:
371  if (flags & ALT_FORM1) {
372  SLJIT_ASSERT(src2 == TMP_REG2);
373  return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm);
374  }
375  if (flags & ALT_FORM2) {
376  SLJIT_ASSERT(src2 == TMP_REG2);
377  return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm);
378  }
379  if (flags & ALT_FORM3) {
380  SLJIT_ASSERT(src2 == TMP_REG2);
381  FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm)));
382  return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));
383  }
384  return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2));
385 
386  case SLJIT_SHL:
387  if (flags & ALT_FORM1) {
388  SLJIT_ASSERT(src2 == TMP_REG2);
389  if (flags & ALT_FORM2) {
390  compiler->imm &= 0x1f;
391  return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1));
392  }
393  compiler->imm &= 0x3f;
394  return push_inst(compiler, RLDI(dst, src1, compiler->imm, 63 - compiler->imm, 1) | RC(flags));
395  }
396  return push_inst(compiler, ((flags & ALT_FORM2) ? SLW : SLD) | RC(flags) | S(src1) | A(dst) | B(src2));
397 
398  case SLJIT_LSHR:
399  if (flags & ALT_FORM1) {
400  SLJIT_ASSERT(src2 == TMP_REG2);
401  if (flags & ALT_FORM2) {
402  compiler->imm &= 0x1f;
403  return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1));
404  }
405  compiler->imm &= 0x3f;
406  return push_inst(compiler, RLDI(dst, src1, 64 - compiler->imm, compiler->imm, 0) | RC(flags));
407  }
408  return push_inst(compiler, ((flags & ALT_FORM2) ? SRW : SRD) | RC(flags) | S(src1) | A(dst) | B(src2));
409 
410  case SLJIT_ASHR:
411  if (flags & ALT_FORM1) {
412  SLJIT_ASSERT(src2 == TMP_REG2);
413  if (flags & ALT_FORM2) {
414  compiler->imm &= 0x1f;
415  return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11));
416  }
417  compiler->imm &= 0x3f;
418  return push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4));
419  }
420  return push_inst(compiler, ((flags & ALT_FORM2) ? SRAW : SRAD) | RC(flags) | S(src1) | A(dst) | B(src2));
421  }
422 
424  return SLJIT_SUCCESS;
425 }
426 
427 static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src)
428 {
429  sljit_s32 arg_count = 0;
430  sljit_s32 word_arg_count = 0;
431  sljit_s32 types = 0;
432  sljit_s32 reg = 0;
433 
434  if (src)
435  reg = *src & REG_MASK;
436 
437  arg_types >>= SLJIT_ARG_SHIFT;
438 
439  while (arg_types) {
440  types = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);
441 
442  switch (arg_types & SLJIT_ARG_MASK) {
443  case SLJIT_ARG_TYPE_F64:
444  case SLJIT_ARG_TYPE_F32:
445  arg_count++;
446  break;
447  default:
448  arg_count++;
449  word_arg_count++;
450 
451  if (arg_count != word_arg_count && arg_count == reg) {
452  FAIL_IF(push_inst(compiler, OR | S(reg) | A(TMP_CALL_REG) | B(reg)));
453  *src = TMP_CALL_REG;
454  }
455  break;
456  }
457 
458  arg_types >>= SLJIT_ARG_SHIFT;
459  }
460 
461  while (types) {
462  switch (types & SLJIT_ARG_MASK) {
463  case SLJIT_ARG_TYPE_F64:
464  case SLJIT_ARG_TYPE_F32:
465  arg_count--;
466  break;
467  default:
468  if (arg_count != word_arg_count)
469  FAIL_IF(push_inst(compiler, OR | S(word_arg_count) | A(arg_count) | B(word_arg_count)));
470 
471  arg_count--;
472  word_arg_count--;
473  break;
474  }
475 
477  }
478 
479  return SLJIT_SUCCESS;
480 }
481 
482 static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value)
483 {
484  FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 48)));
485  FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value >> 32)));
486  FAIL_IF(PUSH_RLDICR(reg, 31));
487  FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(init_value >> 16)));
488  return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
489 }
490 
492 {
493  sljit_ins *inst = (sljit_ins*)addr;
494  SLJIT_UNUSED_ARG(executable_offset);
495 
496  SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 0);
497  inst[0] = (inst[0] & 0xffff0000u) | ((sljit_ins)(new_target >> 48) & 0xffff);
498  inst[1] = (inst[1] & 0xffff0000u) | ((sljit_ins)(new_target >> 32) & 0xffff);
499  inst[3] = (inst[3] & 0xffff0000u) | ((sljit_ins)(new_target >> 16) & 0xffff);
500  inst[4] = (inst[4] & 0xffff0000u) | ((sljit_ins)new_target & 0xffff);
501  SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 1);
502  inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
503  SLJIT_CACHE_FLUSH(inst, inst + 5);
504 }
505 
507 {
508  sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
509 }
#define S(cp)
set set set set set set set macro pixldst1 op
bool int shift
GLsizei GLenum GLenum * types
GLenum src
GLenum GLenum dst
GLbitfield flags
#define SLJIT_UNREACHABLE()
#define SLJIT_API_FUNC_ATTRIBUTE
signed int sljit_s32
#define SLJIT_ASSERT(x)
#define SLJIT_UNUSED_ARG(arg)
unsigned long int sljit_uw
long int sljit_sw
#define SLJIT_INLINE
#define SLJIT_CACHE_FLUSH(from, to)
#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
#define FAIL_IF(expr)
Definition: sljitLir.c:55
#define SLJIT_XOR
Definition: sljitLir.h:1039
#define SLJIT_ARG_TYPE_F32
Definition: sljitLir.h:331
#define SLJIT_ADD
Definition: sljitLir.h:1015
#define SLJIT_MOV_U16
Definition: sljitLir.h:979
#define SLJIT_ARG_TYPE_F64
Definition: sljitLir.h:329
#define SLJIT_NOT
Definition: sljitLir.h:999
#define SLJIT_MOV_S8
Definition: sljitLir.h:976
#define SLJIT_SUB
Definition: sljitLir.h:1023
#define SLJIT_ASHR
Definition: sljitLir.h:1060
#define SLJIT_SUCCESS
Definition: sljitLir.h:98
#define SLJIT_MUL
Definition: sljitLir.h:1030
#define SLJIT_OR
Definition: sljitLir.h:1036
#define SLJIT_AND
Definition: sljitLir.h:1033
#define SLJIT_ARG_SHIFT
Definition: sljitLir.h:333
#define SLJIT_MOV_U32
Definition: sljitLir.h:986
#define SLJIT_MOV_S16
Definition: sljitLir.h:982
#define SLJIT_MOV_U8
Definition: sljitLir.h:973
#define SLJIT_ADDC
Definition: sljitLir.h:1018
#define SLJIT_CLZ
Definition: sljitLir.h:1004
#define SLJIT_SUBC
Definition: sljitLir.h:1026
#define SLJIT_LSHR
Definition: sljitLir.h:1053
#define SLJIT_MOV_S32
Definition: sljitLir.h:989
#define SLJIT_SHL
Definition: sljitLir.h:1046
#define SLJIT_MOV_P
Definition: sljitLir.h:996
#define SLJIT_MOV
Definition: sljitLir.h:971
#define TMP_REG2
#define CMP
#define TMP_REG1
#define ADD
#define AND
#define ADDI
#define ADDE
#define ANDI
#define TMP_ZERO
sljit_u32 sljit_ins
#define CMPI
#define NOR
#define XORI
#define REG_DEST
#define OR
#define XOR
#define SIMM_MIN
#define REG2_SOURCE
#define IMM(imm)
#define ORI
#define BIN_EXTS()
#define PUSH_RLDICR(reg, shift)
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
#define UN_EXTS()
#define BIN_IMM_EXTS()
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
#define INS_CLEAR_LEFT(dst, src, from)
#define SLW
#define XORIS
#define ALT_FORM2
#define SRADI
#define ORIS
#define CRD(d)
#define EXTSB
#define SRAWI
#define TMP_CALL_REG
#define CMPLI
#define ALT_FORM3
#define RLWINM
#define SLD
#define SUBFIC
#define SRW
#define CNTLZD
#define ALT_SET_FLAGS
#define OE(flags)
#define SRAD
#define SRAW
#define SUBFC
#define SUBF
#define MULLI
#define ADDIC
#define MULLD
#define NEG
#define EXTSW
#define ADDC
#define SRD
#define CMPL
#define CNTLZW
#define EXTSH
#define ALT_SIGN_EXT
#define SUBFE
#define ALT_FORM1
#define ADDIS
#define ANDIS
#define RLDI(dst, src, sh, mb, type)
#define ALT_FORM4
#define MULLW
#define ALT_FORM5