php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
sljitNativePPC_32.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 32-bit arch dependent functions. */
28
29static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)
30{
31 if (imm <= SIMM_MAX && imm >= SIMM_MIN)
32 return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));
33
34 if (!(imm & ~0xffff))
35 return push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm));
36
37 FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16)));
38 return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;
39}
40
41/* Simplified mnemonics: clrlwi. */
42#define INS_CLEAR_LEFT(dst, src, from) \
43 (RLWINM | S(src) | A(dst) | RLWI_MBE(from, 31))
44
45static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
46 sljit_s32 dst, sljit_s32 src1, sljit_s32 src2)
47{
48 sljit_u32 imm;
49
50 switch (op) {
51 case SLJIT_MOV:
52 case SLJIT_MOV_U32:
53 case SLJIT_MOV_S32:
54 case SLJIT_MOV_P:
55 SLJIT_ASSERT(src1 == TMP_REG1);
56 if (dst != src2)
57 return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));
58 return SLJIT_SUCCESS;
59
60 case SLJIT_MOV_U8:
61 case SLJIT_MOV_S8:
62 SLJIT_ASSERT(src1 == TMP_REG1);
63 if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
64 if (op == SLJIT_MOV_S8)
65 return push_inst(compiler, EXTSB | S(src2) | A(dst));
66 return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));
67 }
68 else if ((flags & REG_DEST) && op == SLJIT_MOV_S8)
69 return push_inst(compiler, EXTSB | S(src2) | A(dst));
70 else {
71 SLJIT_ASSERT(dst == src2);
72 }
73 return SLJIT_SUCCESS;
74
75 case SLJIT_MOV_U16:
76 case SLJIT_MOV_S16:
77 SLJIT_ASSERT(src1 == TMP_REG1);
78 if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
79 if (op == SLJIT_MOV_S16)
80 return push_inst(compiler, EXTSH | S(src2) | A(dst));
81 return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));
82 }
83 else {
84 SLJIT_ASSERT(dst == src2);
85 }
86 return SLJIT_SUCCESS;
87
88 case SLJIT_CLZ:
89 SLJIT_ASSERT(src1 == TMP_REG1);
90 return push_inst(compiler, CNTLZW | S(src2) | A(dst));
91
92 case SLJIT_CTZ:
93 SLJIT_ASSERT(src1 == TMP_REG1);
94 FAIL_IF(push_inst(compiler, NEG | D(TMP_REG1) | A(src2)));
95 FAIL_IF(push_inst(compiler, AND | S(src2) | A(dst) | B(TMP_REG1)));
96 FAIL_IF(push_inst(compiler, CNTLZW | S(dst) | A(dst)));
97 FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG1) | A(dst) | IMM(-32)));
98 /* The highest bits are set, if dst < 32, zero otherwise. */
99 FAIL_IF(push_inst(compiler, SRWI(27) | S(TMP_REG1) | A(TMP_REG1)));
100 return push_inst(compiler, XOR | S(dst) | A(dst) | B(TMP_REG1));
101
102 case SLJIT_ADD:
103 if (flags & ALT_FORM1) {
104 /* Setting XER SO is not enough, CR SO is also needed. */
105 return push_inst(compiler, ADD | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
106 }
107
108 if (flags & ALT_FORM2) {
109 /* Flags does not set: BIN_IMM_EXTS unnecessary. */
110 SLJIT_ASSERT(src2 == TMP_REG2);
111
112 if (flags & ALT_FORM3)
113 return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);
114
115 imm = compiler->imm;
116
117 if (flags & ALT_FORM4) {
118 FAIL_IF(push_inst(compiler, ADDIS | D(dst) | A(src1) | (((imm >> 16) & 0xffff) + ((imm >> 15) & 0x1))));
119 src1 = dst;
120 }
121
122 return push_inst(compiler, ADDI | D(dst) | A(src1) | (imm & 0xffff));
123 }
124 if (flags & ALT_FORM3) {
125 SLJIT_ASSERT(src2 == TMP_REG2);
126 return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm);
127 }
129 if (!(flags & ALT_SET_FLAGS))
130 return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));
131 if (flags & ALT_FORM5)
132 return push_inst(compiler, ADDC | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
133 return push_inst(compiler, ADD | RC(flags) | D(dst) | A(src1) | B(src2));
134
135 case SLJIT_ADDC:
136 return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2));
137
138 case SLJIT_SUB:
139 if (flags & ALT_FORM1) {
140 if (flags & ALT_FORM2) {
141 FAIL_IF(push_inst(compiler, CMPLI | CRD(0) | A(src1) | compiler->imm));
142 if (!(flags & ALT_FORM3))
143 return SLJIT_SUCCESS;
144 return push_inst(compiler, ADDI | D(dst) | A(src1) | (-compiler->imm & 0xffff));
145 }
146 FAIL_IF(push_inst(compiler, CMPL | CRD(0) | A(src1) | B(src2)));
147 if (!(flags & ALT_FORM3))
148 return SLJIT_SUCCESS;
149 return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
150 }
151
152 if (flags & ALT_FORM2) {
153 if (flags & ALT_FORM3) {
154 FAIL_IF(push_inst(compiler, CMPI | CRD(0) | A(src1) | compiler->imm));
155 if (!(flags & ALT_FORM4))
156 return SLJIT_SUCCESS;
157 return push_inst(compiler, ADDI | D(dst) | A(src1) | (-compiler->imm & 0xffff));
158 }
159 FAIL_IF(push_inst(compiler, CMP | CRD(0) | A(src1) | B(src2)));
160 if (!(flags & ALT_FORM4))
161 return SLJIT_SUCCESS;
162 return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
163 }
164
165 if (flags & ALT_FORM3) {
166 /* Setting XER SO is not enough, CR SO is also needed. */
167 if (src1 != TMP_ZERO)
168 return push_inst(compiler, SUBF | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
169 return push_inst(compiler, NEG | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src2));
170 }
171
172 if (flags & ALT_FORM4) {
173 /* Flags does not set: BIN_IMM_EXTS unnecessary. */
174 SLJIT_ASSERT(src2 == TMP_REG2);
175 return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm);
176 }
177
178 if (!(flags & ALT_SET_FLAGS)) {
179 SLJIT_ASSERT(src1 != TMP_ZERO);
180 return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
181 }
182
183 if (flags & ALT_FORM5)
184 return push_inst(compiler, SUBFC | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
185
186 if (src1 != TMP_ZERO)
187 return push_inst(compiler, SUBF | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
188 return push_inst(compiler, NEG | RC(ALT_SET_FLAGS) | D(dst) | A(src2));
189
190 case SLJIT_SUBC:
191 return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1));
192
193 case SLJIT_MUL:
194 if (flags & ALT_FORM1) {
195 SLJIT_ASSERT(src2 == TMP_REG2);
196 return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm);
197 }
198 return push_inst(compiler, MULLW | OE(flags) | RC(flags) | D(dst) | A(src2) | B(src1));
199
200 case SLJIT_AND:
201 if (flags & ALT_FORM1) {
202 SLJIT_ASSERT(src2 == TMP_REG2);
203 return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm);
204 }
205 if (flags & ALT_FORM2) {
206 SLJIT_ASSERT(src2 == TMP_REG2);
207 return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm);
208 }
209 return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2));
210
211 case SLJIT_OR:
212 if (flags & ALT_FORM1) {
213 SLJIT_ASSERT(src2 == TMP_REG2);
214 return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm);
215 }
216 if (flags & ALT_FORM2) {
217 SLJIT_ASSERT(src2 == TMP_REG2);
218 return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm);
219 }
220 if (flags & ALT_FORM3) {
221 SLJIT_ASSERT(src2 == TMP_REG2);
222 imm = compiler->imm;
223
224 FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(imm)));
225 return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(imm >> 16));
226 }
227 return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2));
228
229 case SLJIT_XOR:
230 if (flags & ALT_FORM1) {
231 SLJIT_ASSERT(src2 == TMP_REG2);
232 return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm);
233 }
234 if (flags & ALT_FORM2) {
235 SLJIT_ASSERT(src2 == TMP_REG2);
236 return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm);
237 }
238 if (flags & ALT_FORM3) {
239 SLJIT_ASSERT(src2 == TMP_REG2);
240 imm = compiler->imm;
241
242 FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(imm)));
243 return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(imm >> 16));
244 }
245 if (flags & ALT_FORM4) {
246 SLJIT_ASSERT(src1 == TMP_REG1);
247 return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
248 }
249 return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2));
250
251 case SLJIT_SHL:
252 case SLJIT_MSHL:
253 if (flags & ALT_FORM1) {
254 SLJIT_ASSERT(src2 == TMP_REG2);
255 imm = compiler->imm & 0x1f;
256 return push_inst(compiler, SLWI(imm) | RC(flags) | S(src1) | A(dst));
257 }
258
259 if (op == SLJIT_MSHL) {
260 FAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | 0x1f));
261 src2 = TMP_REG2;
262 }
263
264 return push_inst(compiler, SLW | RC(flags) | S(src1) | A(dst) | B(src2));
265
266 case SLJIT_LSHR:
267 case SLJIT_MLSHR:
268 if (flags & ALT_FORM1) {
269 SLJIT_ASSERT(src2 == TMP_REG2);
270 imm = compiler->imm & 0x1f;
271 /* Since imm can be 0, SRWI() cannot be used. */
272 return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | RLWI_SH((32 - imm) & 0x1f) | RLWI_MBE(imm, 31));
273 }
274
275 if (op == SLJIT_MLSHR) {
276 FAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | 0x1f));
277 src2 = TMP_REG2;
278 }
279
280 return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2));
281
282 case SLJIT_ASHR:
283 case SLJIT_MASHR:
284 if (flags & ALT_FORM1) {
285 SLJIT_ASSERT(src2 == TMP_REG2);
286 imm = compiler->imm & 0x1f;
287 return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (imm << 11));
288 }
289
290 if (op == SLJIT_MASHR) {
291 FAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | 0x1f));
292 src2 = TMP_REG2;
293 }
294
295 return push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2));
296
297 case SLJIT_ROTL:
298 case SLJIT_ROTR:
299 if (flags & ALT_FORM1) {
300 SLJIT_ASSERT(src2 == TMP_REG2);
301 imm = compiler->imm;
302
303 if (op == SLJIT_ROTR)
304 imm = (sljit_u32)(-(sljit_s32)imm);
305
306 imm &= 0x1f;
307 return push_inst(compiler, RLWINM | S(src1) | A(dst) | RLWI_SH(imm) | RLWI_MBE(0, 31));
308 }
309
310 if (op == SLJIT_ROTR) {
311 FAIL_IF(push_inst(compiler, SUBFIC | D(TMP_REG2) | A(src2) | 0));
312 src2 = TMP_REG2;
313 }
314
315 return push_inst(compiler, RLWNM | S(src1) | A(dst) | B(src2) | RLWI_MBE(0, 31));
316 }
317
319 return SLJIT_SUCCESS;
320}
321
322static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value)
323{
324 FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 16)));
325 return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
326}
327
328static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
329 sljit_s32 dst, sljit_sw dstw,
330 sljit_s32 src, sljit_sw srcw)
331{
332 sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
333 sljit_s32 invert_sign = 1;
334
335 if (src == SLJIT_IMM) {
336 FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ (sljit_sw)0x80000000));
337 src = TMP_REG1;
338 invert_sign = 0;
339 } else if (!FAST_IS_REG(src)) {
340 FAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
341 src = TMP_REG1;
342 }
343
344 /* First, a special double precision floating point value is constructed:
345 (2^53 + (src xor (2^31)))
346 The upper 32 bits of this number is a constant, and the lower 32 bits
347 is simply the value of the source argument. The xor 2^31 operation adds
348 0x80000000 to the source argument, which moves it into the 0 - 0xffffffff
349 range. Finally we substract 2^53 + 2^31 to get the converted value. */
350 FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330));
351 if (invert_sign)
352 FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000));
353 FAIL_IF(push_inst(compiler, STW | S(TMP_REG2) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI));
354 FAIL_IF(push_inst(compiler, STW | S(TMP_REG1) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));
355 FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000));
356 FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET));
357 FAIL_IF(push_inst(compiler, STW | S(TMP_REG1) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));
358 FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG2) | A(SLJIT_SP) | TMP_MEM_OFFSET));
359
360 FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2)));
361
362 if (op & SLJIT_32)
363 FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)));
364
365 if (dst & SLJIT_MEM)
366 return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);
367 return SLJIT_SUCCESS;
368}
369
370static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op,
371 sljit_s32 dst, sljit_sw dstw,
372 sljit_s32 src, sljit_sw srcw)
373{
374 sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
375
376 if (src == SLJIT_IMM) {
377 FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
378 src = TMP_REG1;
379 } else if (!FAST_IS_REG(src)) {
380 FAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
381 src = TMP_REG1;
382 }
383
384 /* First, a special double precision floating point value is constructed:
385 (2^53 + src)
386 The upper 32 bits of this number is a constant, and the lower 32 bits
387 is simply the value of the source argument. Finally we substract 2^53
388 to get the converted value. */
389 FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330));
390 FAIL_IF(push_inst(compiler, STW | S(src) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));
391 FAIL_IF(push_inst(compiler, STW | S(TMP_REG2) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI));
392
393 FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET));
394 FAIL_IF(push_inst(compiler, STW | S(TMP_ZERO) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));
395 FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG2) | A(SLJIT_SP) | TMP_MEM_OFFSET));
396
397 FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2)));
398
399 if (op & SLJIT_32)
400 FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)));
401
402 if (dst & SLJIT_MEM)
403 return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);
404 return SLJIT_SUCCESS;
405}
406
409{
410 union {
411 sljit_s32 imm[2];
413 } u;
414
415 CHECK_ERROR();
416 CHECK(check_sljit_emit_fset64(compiler, freg, value));
417
418 u.value = value;
419
420 if (u.imm[0] != 0)
421 FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm[0]));
422 if (u.imm[1] != 0)
423 FAIL_IF(load_immediate(compiler, TMP_REG2, u.imm[1]));
424
425 /* Saved in the same endianness. */
426 FAIL_IF(push_inst(compiler, STW | S(u.imm[0] != 0 ? TMP_REG1 : TMP_ZERO) | A(SLJIT_SP) | TMP_MEM_OFFSET));
427 FAIL_IF(push_inst(compiler, STW | S(u.imm[1] != 0 ? TMP_REG2 : TMP_ZERO) | A(SLJIT_SP) | (TMP_MEM_OFFSET + sizeof(sljit_s32))));
428 return push_inst(compiler, LFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET);
429}
430
432 sljit_s32 freg, sljit_s32 reg)
433{
434 sljit_s32 reg2 = 0;
435
436 CHECK_ERROR();
437 CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));
438
439 if (op & SLJIT_32) {
440 if (op == SLJIT_COPY32_TO_F32) {
441 FAIL_IF(push_inst(compiler, STW | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET));
442 return push_inst(compiler, LFS | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET);
443 }
444
445 FAIL_IF(push_inst(compiler, STFS | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET));
446 return push_inst(compiler, LWZ | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET);
447 }
448
449 if (reg & REG_PAIR_MASK) {
450 reg2 = REG_PAIR_SECOND(reg);
451 reg = REG_PAIR_FIRST(reg);
452 }
453
454 if (op == SLJIT_COPY_TO_F64) {
455 FAIL_IF(push_inst(compiler, STW | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI));
456
457 if (reg2 != 0)
458 FAIL_IF(push_inst(compiler, STW | S(reg2) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));
459 else
460 FAIL_IF(push_inst(compiler, STFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));
461
462 return push_inst(compiler, LFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET);
463 }
464
465 FAIL_IF(push_inst(compiler, STFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET));
466
467 if (reg2 != 0)
468 FAIL_IF(push_inst(compiler, LWZ | S(reg2) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));
469
470 return push_inst(compiler, LWZ | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI);
471}
472
474{
475 sljit_ins *inst = (sljit_ins *)addr;
476 SLJIT_UNUSED_ARG(executable_offset);
477
478 SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
479 SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI);
480 inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
481 inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
482 SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
483 inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
484 SLJIT_CACHE_FLUSH(inst, inst + 2);
485}
uint32_t u
Definition cdf.c:78
#define S(s, l, r)
Definition hash_gost.c:121
#define A(x, l, r)
Definition hash_gost.c:85
#define SLJIT_UNREACHABLE()
#define SLJIT_API_FUNC_ATTRIBUTE
unsigned int sljit_uw
signed int sljit_s32
unsigned int sljit_u32
#define SLJIT_ASSERT(x)
#define SLJIT_UNUSED_ARG(arg)
#define SLJIT_INLINE
#define SLJIT_CACHE_FLUSH(from, to)
double sljit_f64
int sljit_sw
#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
#define CHECK_ERROR()
Definition sljitLir.c:43
#define FAIL_IF(expr)
Definition sljitLir.c:55
#define SLJIT_XOR
Definition sljitLir.h:1227
#define SLJIT_SP
Definition sljitLir.h:214
#define SLJIT_ROTL
Definition sljitLir.h:1268
#define SLJIT_ADD
Definition sljitLir.h:1203
#define SLJIT_MOV_U16
Definition sljitLir.h:1133
#define SLJIT_32
Definition sljitLir.h:978
#define SLJIT_MSHL
Definition sljitLir.h:1239
#define SLJIT_MOV_S8
Definition sljitLir.h:1130
#define SLJIT_SUB
Definition sljitLir.h:1211
#define SLJIT_ASHR
Definition sljitLir.h:1258
#define SLJIT_SUCCESS
Definition sljitLir.h:101
#define SLJIT_IMM
Definition sljitLir.h:931
#define SLJIT_ROTR
Definition sljitLir.h:1273
#define SLJIT_CTZ
Definition sljitLir.h:1158
#define SLJIT_MUL
Definition sljitLir.h:1218
#define SLJIT_OR
Definition sljitLir.h:1224
#define SLJIT_AND
Definition sljitLir.h:1221
#define SLJIT_MOV_U32
Definition sljitLir.h:1140
#define SLJIT_MOV_S16
Definition sljitLir.h:1136
#define SLJIT_MEM
Definition sljitLir.h:927
#define SLJIT_MOV_U8
Definition sljitLir.h:1127
#define SLJIT_ADDC
Definition sljitLir.h:1206
#define SLJIT_CLZ
Definition sljitLir.h:1153
#define SLJIT_SUBC
Definition sljitLir.h:1214
#define SLJIT_MLSHR
Definition sljitLir.h:1251
#define SLJIT_LSHR
Definition sljitLir.h:1246
#define SLJIT_MOV_S32
Definition sljitLir.h:1143
#define SLJIT_COPY_TO_F64
Definition sljitLir.h:1496
#define SLJIT_COPY32_TO_F32
Definition sljitLir.h:1499
#define SLJIT_SHL
Definition sljitLir.h:1234
#define SLJIT_MASHR
Definition sljitLir.h:1263
#define SLJIT_MOV_P
Definition sljitLir.h:1149
#define SLJIT_MOV
Definition sljitLir.h:1125
#define B
#define TMP_REG2
#define TMP_FREG2
#define CMP
#define TMP_REG1
#define ADD
#define LOAD_DATA
#define AND
sljit_u32 sljit_ins
#define TMP_FREG1
#define ADDI
#define ADDE
#define FSUB
#define ANDI
#define TMP_ZERO
#define CMPI
#define NOR
#define XORI
#define FLOAT_DATA(op)
#define REG_DEST
#define OR
#define SIGNED_DATA
#define XOR
#define FD(fd)
#define WORD_DATA
#define REG2_SOURCE
#define ORI
#define SIMM_MIN
#define D(d)
#define FS(s)
#define IMM(imm)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 freg, sljit_s32 reg)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, sljit_s32 freg, sljit_f64 value)
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 STFD
#define FA(fa)
#define TMP_MEM_OFFSET_HI
#define SLW
#define STW
#define XORIS
#define ALT_FORM2
#define ORIS
#define CRD(d)
#define EXTSB
#define LFD
#define SRAWI
#define CMPLI
#define ALT_FORM3
#define RLWINM
#define SRWI(shift)
#define FRSP
#define SUBFIC
#define SRW
#define RLWI_MBE(mb, me)
#define ALT_SET_FLAGS
#define OE(flags)
#define LFS
#define RLWNM
#define SRAW
#define RLWI_SH(sh)
#define SUBFC
#define SUBF
#define MULLI
#define ADDIC
#define NEG
#define ADDC
#define CMPL
#define STFS
#define CNTLZW
#define FB(fb)
#define TMP_MEM_OFFSET
#define LWZ
#define EXTSH
#define SLWI(shift)
#define SUBFE
#define ALT_FORM1
#define TMP_MEM_OFFSET_LO
#define ADDIS
#define ANDIS
#define RC(flags)
#define ALT_FORM4
#define MULLW
#define ALT_FORM5
value