diff options
author | Mike Pall <mike> | 2011-05-22 17:41:59 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2011-05-22 17:44:58 +0200 |
commit | 138f54352ad604ef50f77cbcc15abec6dbd883c0 (patch) | |
tree | f8ac2d3599cec2af1007da1c894847d3d0e2ff95 /src/lj_opt_split.c | |
parent | d0115c65f5ad80af2a113332906a0c5a010f9812 (diff) | |
download | luajit-138f54352ad604ef50f77cbcc15abec6dbd883c0.tar.gz luajit-138f54352ad604ef50f77cbcc15abec6dbd883c0.tar.bz2 luajit-138f54352ad604ef50f77cbcc15abec6dbd883c0.zip |
Split up FP IR instructions with SPLIT pass for soft-float targets.
Diffstat (limited to 'src/lj_opt_split.c')
-rw-r--r-- | src/lj_opt_split.c | 271 |
1 files changed, 243 insertions, 28 deletions
diff --git a/src/lj_opt_split.c b/src/lj_opt_split.c index 2f8b1e9c..67436a65 100644 --- a/src/lj_opt_split.c +++ b/src/lj_opt_split.c | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | #include "lj_obj.h" | 9 | #include "lj_obj.h" |
10 | 10 | ||
11 | #if LJ_HASJIT && LJ_HASFFI && LJ_32 | 11 | #if LJ_HASJIT && (LJ_SOFTFP || (LJ_32 && LJ_HASFFI)) |
12 | 12 | ||
13 | #include "lj_err.h" | 13 | #include "lj_err.h" |
14 | #include "lj_str.h" | 14 | #include "lj_str.h" |
@@ -21,9 +21,9 @@ | |||
21 | /* SPLIT pass: | 21 | /* SPLIT pass: |
22 | ** | 22 | ** |
23 | ** This pass splits up 64 bit IR instructions into multiple 32 bit IR | 23 | ** This pass splits up 64 bit IR instructions into multiple 32 bit IR |
24 | ** instructions. It's only active for 32 bit CPUs which lack native 64 bit | 24 | ** instructions. It's only active for soft-float targets or for 32 bit CPUs |
25 | ** operations. The FFI is currently the only emitter for 64 bit | 25 | ** which lack native 64 bit integer operations (the FFI is currently the |
26 | ** instructions, so this pass is disabled if the FFI is disabled. | 26 | ** only emitter for 64 bit integer instructions). |
27 | ** | 27 | ** |
28 | ** Splitting the IR in a separate pass keeps each 32 bit IR assembler | 28 | ** Splitting the IR in a separate pass keeps each 32 bit IR assembler |
29 | ** backend simple. Only a small amount of extra functionality needs to be | 29 | ** backend simple. Only a small amount of extra functionality needs to be |
@@ -41,14 +41,19 @@ | |||
41 | ** The operands of HIOP hold the hiword input references. The output of HIOP | 41 | ** The operands of HIOP hold the hiword input references. The output of HIOP |
42 | ** is the hiword output reference, which is also used to hold the hiword | 42 | ** is the hiword output reference, which is also used to hold the hiword |
43 | ** register or spill slot information. The register allocator treats this | 43 | ** register or spill slot information. The register allocator treats this |
44 | ** instruction independent of any other instruction, which improves code | 44 | ** instruction independently of any other instruction, which improves code |
45 | ** quality compared to using fixed register pairs. | 45 | ** quality compared to using fixed register pairs. |
46 | ** | 46 | ** |
47 | ** It's easier to split up some instructions into two regular 32 bit | 47 | ** It's easier to split up some instructions into two regular 32 bit |
48 | ** instructions. E.g. XLOAD is split up into two XLOADs with two different | 48 | ** instructions. E.g. XLOAD is split up into two XLOADs with two different |
49 | ** addresses. Obviously 64 bit constants need to be split up into two 32 bit | 49 | ** addresses. Obviously 64 bit constants need to be split up into two 32 bit |
50 | ** constants, too. Some hiword instructions can be entirely omitted, e.g. | 50 | ** constants, too. Some hiword instructions can be entirely omitted, e.g. |
51 | ** when zero-extending a 32 bit value to 64 bits. | 51 | ** when zero-extending a 32 bit value to 64 bits. 64 bit arguments for calls |
52 | ** are split up into two 32 bit arguments each. | ||
53 | ** | ||
54 | ** On soft-float targets, floating-point instructions are directly converted | ||
55 | ** to soft-float calls by the SPLIT pass (except for comparisons and MIN/MAX). | ||
56 | ** HIOP for number results has the type IRT_SOFTFP ("sfp" in -jdump). | ||
52 | ** | 57 | ** |
53 | ** Here's the IR and x64 machine code for 'x.b = x.a + 1' for a struct with | 58 | ** Here's the IR and x64 machine code for 'x.b = x.a + 1' for a struct with |
54 | ** two int64_t fields: | 59 | ** two int64_t fields: |
@@ -101,10 +106,43 @@ static IRRef split_emit(jit_State *J, uint16_t ot, IRRef1 op1, IRRef1 op2) | |||
101 | return nref; | 106 | return nref; |
102 | } | 107 | } |
103 | 108 | ||
104 | /* Emit a CALLN with two split 64 bit arguments. */ | 109 | #if LJ_SOFTFP |
105 | static IRRef split_call64(jit_State *J, IRRef1 *hisubst, IRIns *oir, | 110 | /* Emit a CALLN with one split 64 bit argument. */ |
111 | static IRRef split_call_l(jit_State *J, IRRef1 *hisubst, IRIns *oir, | ||
106 | IRIns *ir, IRCallID id) | 112 | IRIns *ir, IRCallID id) |
107 | { | 113 | { |
114 | IRRef tmp, op1 = ir->op1; | ||
115 | J->cur.nins--; | ||
116 | #if LJ_LE | ||
117 | tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), oir[op1].prev, hisubst[op1]); | ||
118 | #else | ||
119 | tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), hisubst[op1], oir[op1].prev); | ||
120 | #endif | ||
121 | ir->prev = tmp = split_emit(J, IRTI(IR_CALLN), tmp, id); | ||
122 | return split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), tmp, tmp); | ||
123 | } | ||
124 | |||
125 | /* Emit a CALLN with one split 64 bit argument and a 32 bit argument. */ | ||
126 | static IRRef split_call_li(jit_State *J, IRRef1 *hisubst, IRIns *oir, | ||
127 | IRIns *ir, IRCallID id) | ||
128 | { | ||
129 | IRRef tmp, op1 = ir->op1, op2 = ir->op2; | ||
130 | J->cur.nins--; | ||
131 | #if LJ_LE | ||
132 | tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), oir[op1].prev, hisubst[op1]); | ||
133 | #else | ||
134 | tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), hisubst[op1], oir[op1].prev); | ||
135 | #endif | ||
136 | tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, oir[op2].prev); | ||
137 | ir->prev = tmp = split_emit(J, IRTI(IR_CALLN), tmp, id); | ||
138 | return split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), tmp, tmp); | ||
139 | } | ||
140 | #endif | ||
141 | |||
142 | /* Emit a CALLN with two split 64 bit arguments. */ | ||
143 | static IRRef split_call_ll(jit_State *J, IRRef1 *hisubst, IRIns *oir, | ||
144 | IRIns *ir, IRCallID id) | ||
145 | { | ||
108 | IRRef tmp, op1 = ir->op1, op2 = ir->op2; | 146 | IRRef tmp, op1 = ir->op1, op2 = ir->op2; |
109 | J->cur.nins--; | 147 | J->cur.nins--; |
110 | #if LJ_LE | 148 | #if LJ_LE |
@@ -117,7 +155,9 @@ static IRRef split_call64(jit_State *J, IRRef1 *hisubst, IRIns *oir, | |||
117 | tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, oir[op2].prev); | 155 | tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), tmp, oir[op2].prev); |
118 | #endif | 156 | #endif |
119 | ir->prev = tmp = split_emit(J, IRTI(IR_CALLN), tmp, id); | 157 | ir->prev = tmp = split_emit(J, IRTI(IR_CALLN), tmp, id); |
120 | return split_emit(J, IRTI(IR_HIOP), tmp, tmp); | 158 | return split_emit(J, |
159 | IRT(IR_HIOP, (LJ_SOFTFP && irt_isnum(ir->t)) ? IRT_SOFTFP : IRT_INT), | ||
160 | tmp, tmp); | ||
121 | } | 161 | } |
122 | 162 | ||
123 | /* Get a pointer to the other 32 bit word (LE: hiword, BE: loword). */ | 163 | /* Get a pointer to the other 32 bit word (LE: hiword, BE: loword). */ |
@@ -155,7 +195,8 @@ static void split_ir(jit_State *J) | |||
155 | /* Process constants and fixed references. */ | 195 | /* Process constants and fixed references. */ |
156 | for (ref = nk; ref <= REF_BASE; ref++) { | 196 | for (ref = nk; ref <= REF_BASE; ref++) { |
157 | IRIns *ir = &oir[ref]; | 197 | IRIns *ir = &oir[ref]; |
158 | if (ir->o == IR_KINT64) { /* Split up 64 bit constant. */ | 198 | if ((LJ_SOFTFP && ir->o == IR_KNUM) || ir->o == IR_KINT64) { |
199 | /* Split up 64 bit constant. */ | ||
159 | TValue tv = *ir_k64(ir); | 200 | TValue tv = *ir_k64(ir); |
160 | ir->prev = lj_ir_kint(J, (int32_t)tv.u32.lo); | 201 | ir->prev = lj_ir_kint(J, (int32_t)tv.u32.lo); |
161 | hisubst[ref] = lj_ir_kint(J, (int32_t)tv.u32.hi); | 202 | hisubst[ref] = lj_ir_kint(J, (int32_t)tv.u32.hi); |
@@ -181,6 +222,106 @@ static void split_ir(jit_State *J) | |||
181 | hisubst[ref] = 0; | 222 | hisubst[ref] = 0; |
182 | 223 | ||
183 | /* Split 64 bit instructions. */ | 224 | /* Split 64 bit instructions. */ |
225 | #if LJ_SOFTFP | ||
226 | if (irt_isnum(ir->t)) { | ||
227 | nir->t.irt = IRT_INT | (nir->t.irt & IRT_GUARD); /* Turn into INT op. */ | ||
228 | /* Note: hi ref = lo ref + 1! Required for SNAP_SOFTFPNUM logic. */ | ||
229 | switch (ir->o) { | ||
230 | case IR_ADD: | ||
231 | hi = split_call_ll(J, hisubst, oir, ir, IRCALL_softfp_add); | ||
232 | break; | ||
233 | case IR_SUB: | ||
234 | hi = split_call_ll(J, hisubst, oir, ir, IRCALL_softfp_sub); | ||
235 | break; | ||
236 | case IR_MUL: | ||
237 | hi = split_call_ll(J, hisubst, oir, ir, IRCALL_softfp_mul); | ||
238 | break; | ||
239 | case IR_DIV: | ||
240 | hi = split_call_ll(J, hisubst, oir, ir, IRCALL_softfp_div); | ||
241 | break; | ||
242 | case IR_POW: | ||
243 | hi = split_call_li(J, hisubst, oir, ir, IRCALL_lj_vm_powi); | ||
244 | break; | ||
245 | case IR_FPMATH: | ||
246 | hi = split_call_l(J, hisubst, oir, ir, IRCALL_lj_vm_floor + ir->op2); | ||
247 | break; | ||
248 | case IR_ATAN2: | ||
249 | hi = split_call_ll(J, hisubst, oir, ir, IRCALL_atan2); | ||
250 | break; | ||
251 | case IR_LDEXP: | ||
252 | hi = split_call_li(J, hisubst, oir, ir, IRCALL_ldexp); | ||
253 | break; | ||
254 | case IR_NEG: case IR_ABS: | ||
255 | nir->o = IR_CONV; /* Pass through loword. */ | ||
256 | nir->op2 = (IRT_INT << 5) | IRT_INT; | ||
257 | hi = split_emit(J, IRT(ir->o == IR_NEG ? IR_BXOR : IR_BAND, IRT_SOFTFP), | ||
258 | hisubst[ir->op1], hisubst[ir->op2]); | ||
259 | break; | ||
260 | case IR_SLOAD: case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD: | ||
261 | case IR_MIN: case IR_MAX: | ||
262 | hi = split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nref, nref); | ||
263 | break; | ||
264 | case IR_XLOAD: | ||
265 | hi = split_emit(J, IRT(IR_XLOAD, IRT_SOFTFP), | ||
266 | split_ptr(J, nir->op1), ir->op2); | ||
267 | #if LJ_BE | ||
268 | ir->prev = hi; hi = nref; | ||
269 | #endif | ||
270 | break; | ||
271 | case IR_ASTORE: case IR_HSTORE: case IR_USTORE: | ||
272 | split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nir->op1, hisubst[ir->op2]); | ||
273 | break; | ||
274 | case IR_XSTORE: { | ||
275 | #if LJ_LE | ||
276 | IRRef hiref = hisubst[ir->op2]; | ||
277 | #else | ||
278 | IRRef hiref = nir->op2; nir->op2 = hisubst[ir->op2]; | ||
279 | #endif | ||
280 | split_emit(J, IRT(IR_XSTORE, IRT_SOFTFP), | ||
281 | split_ptr(J, nir->op1), hiref); | ||
282 | break; | ||
283 | } | ||
284 | case IR_CONV: { /* Conversion to number. Others handled below. */ | ||
285 | IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); | ||
286 | #if LJ_32 && LJ_HASFFI | ||
287 | if (st == IRT_I64 || st == IRT_U64) { | ||
288 | hi = split_call_l(J, hisubst, oir, ir, | ||
289 | st == IRT_I64 ? IRCALL_softfp_l2d : IRCALL_softfp_ul2d); | ||
290 | break; | ||
291 | } | ||
292 | #endif | ||
293 | lua_assert(st == IRT_INT || | ||
294 | (LJ_32 && LJ_HASFFI && (st == IRT_U32 || st == IRT_FLOAT))); | ||
295 | nir->o = IR_CALLN; | ||
296 | #if LJ_32 && LJ_HASFFI | ||
297 | nir->op2 = st == IRT_INT ? IRCALL_softfp_i2d : | ||
298 | st == IRT_FLOAT ? IRCALL_softfp_f2d : | ||
299 | IRCALL_softfp_ui2d; | ||
300 | #else | ||
301 | nir->op2 = IRCALL_softfp_i2d; | ||
302 | #endif | ||
303 | hi = split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nref, nref); | ||
304 | break; | ||
305 | } | ||
306 | case IR_CALLS: | ||
307 | case IR_CALLXS: | ||
308 | goto split_call; | ||
309 | case IR_PHI: | ||
310 | if (nir->op1 == nir->op2) | ||
311 | J->cur.nins--; /* Drop useless PHIs. */ | ||
312 | if (hisubst[ir->op1] != hisubst[ir->op2]) | ||
313 | split_emit(J, IRT(IR_PHI, IRT_SOFTFP), | ||
314 | hisubst[ir->op1], hisubst[ir->op2]); | ||
315 | break; | ||
316 | default: | ||
317 | lua_assert(ir->o <= IR_NE); | ||
318 | split_emit(J, IRTG(IR_HIOP, IRT_SOFTFP), | ||
319 | hisubst[ir->op1], hisubst[ir->op2]); | ||
320 | break; | ||
321 | } | ||
322 | } else | ||
323 | #endif | ||
324 | #if LJ_32 && LJ_HASFFI | ||
184 | if (irt_isint64(ir->t)) { | 325 | if (irt_isint64(ir->t)) { |
185 | IRRef hiref = hisubst[ir->op1]; | 326 | IRRef hiref = hisubst[ir->op1]; |
186 | nir->t.irt = IRT_INT | (nir->t.irt & IRT_GUARD); /* Turn into INT op. */ | 327 | nir->t.irt = IRT_INT | (nir->t.irt & IRT_GUARD); /* Turn into INT op. */ |
@@ -199,22 +340,22 @@ static void split_ir(jit_State *J) | |||
199 | hi = split_emit(J, IRTI(IR_HIOP), hiref, hisubst[ir->op2]); | 340 | hi = split_emit(J, IRTI(IR_HIOP), hiref, hisubst[ir->op2]); |
200 | break; | 341 | break; |
201 | case IR_MUL: | 342 | case IR_MUL: |
202 | hi = split_call64(J, hisubst, oir, ir, IRCALL_lj_carith_mul64); | 343 | hi = split_call_ll(J, hisubst, oir, ir, IRCALL_lj_carith_mul64); |
203 | break; | 344 | break; |
204 | case IR_DIV: | 345 | case IR_DIV: |
205 | hi = split_call64(J, hisubst, oir, ir, | 346 | hi = split_call_ll(J, hisubst, oir, ir, |
206 | irt_isi64(ir->t) ? IRCALL_lj_carith_divi64 : | 347 | irt_isi64(ir->t) ? IRCALL_lj_carith_divi64 : |
207 | IRCALL_lj_carith_divu64); | 348 | IRCALL_lj_carith_divu64); |
208 | break; | 349 | break; |
209 | case IR_MOD: | 350 | case IR_MOD: |
210 | hi = split_call64(J, hisubst, oir, ir, | 351 | hi = split_call_ll(J, hisubst, oir, ir, |
211 | irt_isi64(ir->t) ? IRCALL_lj_carith_modi64 : | 352 | irt_isi64(ir->t) ? IRCALL_lj_carith_modi64 : |
212 | IRCALL_lj_carith_modu64); | 353 | IRCALL_lj_carith_modu64); |
213 | break; | 354 | break; |
214 | case IR_POW: | 355 | case IR_POW: |
215 | hi = split_call64(J, hisubst, oir, ir, | 356 | hi = split_call_ll(J, hisubst, oir, ir, |
216 | irt_isi64(ir->t) ? IRCALL_lj_carith_powi64 : | 357 | irt_isi64(ir->t) ? IRCALL_lj_carith_powi64 : |
217 | IRCALL_lj_carith_powu64); | 358 | IRCALL_lj_carith_powu64); |
218 | break; | 359 | break; |
219 | case IR_FLOAD: | 360 | case IR_FLOAD: |
220 | lua_assert(ir->op2 == IRFL_CDATA_INT64); | 361 | lua_assert(ir->op2 == IRFL_CDATA_INT64); |
@@ -239,9 +380,21 @@ static void split_ir(jit_State *J) | |||
239 | break; | 380 | break; |
240 | case IR_CONV: { /* Conversion to 64 bit integer. Others handled below. */ | 381 | case IR_CONV: { /* Conversion to 64 bit integer. Others handled below. */ |
241 | IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); | 382 | IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); |
383 | #if LJ_SOFTFP | ||
384 | if (st == IRT_NUM) { /* NUM to 64 bit int conv. */ | ||
385 | split_call_l(J, hisubst, oir, ir, | ||
386 | irt_isi64(ir->t) ? IRCALL_softfp_d2l : IRCALL_softfp_d2ul); | ||
387 | } else if (st == IRT_FLOAT) { /* FLOAT to 64 bit int conv. */ | ||
388 | nir->o = IR_CALLN; | ||
389 | nir->op2 = irt_isi64(ir->t) ? IRCALL_softfp_f2l : IRCALL_softfp_f2ul; | ||
390 | hi = split_emit(J, IRTI(IR_HIOP), nref, nref); | ||
391 | } | ||
392 | #else | ||
242 | if (st == IRT_NUM || st == IRT_FLOAT) { /* FP to 64 bit int conv. */ | 393 | if (st == IRT_NUM || st == IRT_FLOAT) { /* FP to 64 bit int conv. */ |
243 | hi = split_emit(J, IRTI(IR_HIOP), nir->op1, nref); | 394 | hi = split_emit(J, IRTI(IR_HIOP), nir->op1, nref); |
244 | } else if (st == IRT_I64 || st == IRT_U64) { /* 64/64 bit cast. */ | 395 | } |
396 | #endif | ||
397 | else if (st == IRT_I64 || st == IRT_U64) { /* 64/64 bit cast. */ | ||
245 | /* Drop cast, since assembler doesn't care. */ | 398 | /* Drop cast, since assembler doesn't care. */ |
246 | goto fwdlo; | 399 | goto fwdlo; |
247 | } else if ((ir->op2 & IRCONV_SEXT)) { /* Sign-extend to 64 bit. */ | 400 | } else if ((ir->op2 & IRCONV_SEXT)) { /* Sign-extend to 64 bit. */ |
@@ -274,13 +427,37 @@ static void split_ir(jit_State *J) | |||
274 | split_emit(J, IRTGI(IR_HIOP), hiref, hisubst[ir->op2]); | 427 | split_emit(J, IRTGI(IR_HIOP), hiref, hisubst[ir->op2]); |
275 | break; | 428 | break; |
276 | } | 429 | } |
277 | } else if (ir->o == IR_CONV) { /* See above, too. */ | 430 | } else |
431 | #endif | ||
432 | #if LJ_SOFTFP | ||
433 | if (ir->o == IR_TOBIT) { | ||
434 | IRRef tmp, op1 = ir->op1; | ||
435 | J->cur.nins--; | ||
436 | #if LJ_LE | ||
437 | tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), oir[op1].prev, hisubst[op1]); | ||
438 | #else | ||
439 | tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), hisubst[op1], oir[op1].prev); | ||
440 | #endif | ||
441 | ir->prev = split_emit(J, IRTI(IR_CALLN), tmp, IRCALL_lj_vm_tobit); | ||
442 | } else | ||
443 | #endif | ||
444 | if (ir->o == IR_CONV) { /* See above, too. */ | ||
278 | IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); | 445 | IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); |
446 | #if LJ_32 && LJ_HASFFI | ||
279 | if (st == IRT_I64 || st == IRT_U64) { /* Conversion from 64 bit int. */ | 447 | if (st == IRT_I64 || st == IRT_U64) { /* Conversion from 64 bit int. */ |
448 | #if LJ_SOFTFP | ||
449 | if (irt_isfloat(ir->t)) { | ||
450 | split_call_l(J, hisubst, oir, ir, | ||
451 | st == IRT_I64 ? IRCALL_softfp_l2f : IRCALL_softfp_ul2f); | ||
452 | J->cur.nins--; /* Drop unused HIOP. */ | ||
453 | } | ||
454 | #else | ||
280 | if (irt_isfp(ir->t)) { /* 64 bit integer to FP conversion. */ | 455 | if (irt_isfp(ir->t)) { /* 64 bit integer to FP conversion. */ |
281 | ir->prev = split_emit(J, IRT(IR_HIOP, irt_type(ir->t)), | 456 | ir->prev = split_emit(J, IRT(IR_HIOP, irt_type(ir->t)), |
282 | hisubst[ir->op1], nref); | 457 | hisubst[ir->op1], nref); |
283 | } else { /* Truncate to lower 32 bits. */ | 458 | } |
459 | #endif | ||
460 | else { /* Truncate to lower 32 bits. */ | ||
284 | fwdlo: | 461 | fwdlo: |
285 | ir->prev = nir->op1; /* Forward loword. */ | 462 | ir->prev = nir->op1; /* Forward loword. */ |
286 | /* Replace with NOP to avoid messing up the snapshot logic. */ | 463 | /* Replace with NOP to avoid messing up the snapshot logic. */ |
@@ -288,6 +465,36 @@ static void split_ir(jit_State *J) | |||
288 | nir->op1 = nir->op2 = 0; | 465 | nir->op1 = nir->op2 = 0; |
289 | } | 466 | } |
290 | } | 467 | } |
468 | #endif | ||
469 | #if LJ_SOFTFP && LJ_32 && LJ_HASFFI | ||
470 | else if (irt_isfloat(ir->t)) { | ||
471 | if (st == IRT_NUM) { | ||
472 | split_call_l(J, hisubst, oir, ir, IRCALL_softfp_d2f); | ||
473 | J->cur.nins--; /* Drop unused HIOP. */ | ||
474 | } else { | ||
475 | nir->o = IR_CALLN; | ||
476 | nir->op2 = st == IRT_INT ? IRCALL_softfp_i2f : IRCALL_softfp_ui2f; | ||
477 | } | ||
478 | } else if (st == IRT_FLOAT) { | ||
479 | nir->o = IR_CALLN; | ||
480 | nir->op2 = irt_isint(ir->t) ? IRCALL_softfp_f2i : IRCALL_softfp_f2ui; | ||
481 | } else | ||
482 | #endif | ||
483 | #if LJ_SOFTFP | ||
484 | if (st == IRT_NUM || (LJ_32 && LJ_HASFFI && st == IRT_FLOAT)) { | ||
485 | if (irt_isguard(ir->t)) { | ||
486 | lua_assert(0); /* NYI: missing check. */ | ||
487 | } | ||
488 | split_call_l(J, hisubst, oir, ir, | ||
489 | #if LJ_32 && LJ_HASFFI | ||
490 | st == IRT_NUM ? IRCALL_softfp_d2i : IRCALL_softfp_f2i | ||
491 | #else | ||
492 | IRCALL_softfp_d2i | ||
493 | #endif | ||
494 | ); | ||
495 | J->cur.nins--; /* Drop unused HIOP. */ | ||
496 | } | ||
497 | #endif | ||
291 | } else if (ir->o == IR_CALLXS) { | 498 | } else if (ir->o == IR_CALLXS) { |
292 | IRRef hiref; | 499 | IRRef hiref; |
293 | split_call: | 500 | split_call: |
@@ -303,8 +510,10 @@ static void split_ir(jit_State *J) | |||
303 | #endif | 510 | #endif |
304 | ir->prev = nref = split_emit(J, ot, nref, op2); | 511 | ir->prev = nref = split_emit(J, ot, nref, op2); |
305 | } | 512 | } |
306 | if (irt_isint64(ir->t)) | 513 | if (LJ_SOFTFP ? irt_is64(ir->t) : irt_isint64(ir->t)) |
307 | hi = split_emit(J, IRTI(IR_HIOP), nref, nref); | 514 | hi = split_emit(J, |
515 | IRT(IR_HIOP, (LJ_SOFTFP && irt_isnum(ir->t)) ? IRT_SOFTFP : IRT_INT), | ||
516 | nref, nref); | ||
308 | } else if (ir->o == IR_CARG) { | 517 | } else if (ir->o == IR_CARG) { |
309 | IRRef hiref = hisubst[ir->op1]; | 518 | IRRef hiref = hisubst[ir->op1]; |
310 | if (hiref) { | 519 | if (hiref) { |
@@ -367,17 +576,18 @@ static TValue *cpsplit(lua_State *L, lua_CFunction dummy, void *ud) | |||
367 | return NULL; | 576 | return NULL; |
368 | } | 577 | } |
369 | 578 | ||
370 | #ifdef LUA_USE_ASSERT | 579 | #if defined(LUA_USE_ASSERT) || LJ_SOFTFP |
371 | /* Slow, but sure way to check whether a SPLIT pass is needed. */ | 580 | /* Slow, but sure way to check whether a SPLIT pass is needed. */ |
372 | static int split_needsplit(jit_State *J) | 581 | static int split_needsplit(jit_State *J) |
373 | { | 582 | { |
374 | IRIns *ir, *irend; | 583 | IRIns *ir, *irend; |
375 | IRRef ref; | 584 | IRRef ref; |
376 | for (ir = IR(REF_FIRST), irend = IR(J->cur.nins); ir < irend; ir++) | 585 | for (ir = IR(REF_FIRST), irend = IR(J->cur.nins); ir < irend; ir++) |
377 | if (irt_isint64(ir->t)) | 586 | if (LJ_SOFTFP ? irt_is64(ir->t) : irt_isint64(ir->t)) |
378 | return 1; | 587 | return 1; |
379 | for (ref = J->chain[IR_CONV]; ref; ref = IR(ref)->prev) | 588 | for (ref = J->chain[IR_CONV]; ref; ref = IR(ref)->prev) |
380 | if ((IR(ref)->op2 & IRCONV_SRCMASK) == IRT_I64 || | 589 | if ((LJ_SOFTFP && (IR(ref)->op2 & IRCONV_SRCMASK) == IRT_NUM) || |
590 | (IR(ref)->op2 & IRCONV_SRCMASK) == IRT_I64 || | ||
381 | (IR(ref)->op2 & IRCONV_SRCMASK) == IRT_U64) | 591 | (IR(ref)->op2 & IRCONV_SRCMASK) == IRT_U64) |
382 | return 1; | 592 | return 1; |
383 | return 0; /* Nope. */ | 593 | return 0; /* Nope. */ |
@@ -387,7 +597,12 @@ static int split_needsplit(jit_State *J) | |||
387 | /* SPLIT pass. */ | 597 | /* SPLIT pass. */ |
388 | void lj_opt_split(jit_State *J) | 598 | void lj_opt_split(jit_State *J) |
389 | { | 599 | { |
600 | #if LJ_SOFTFP | ||
601 | if (!J->needsplit) | ||
602 | J->needsplit = split_needsplit(J); | ||
603 | #else | ||
390 | lua_assert(J->needsplit >= split_needsplit(J)); /* Verify flag. */ | 604 | lua_assert(J->needsplit >= split_needsplit(J)); /* Verify flag. */ |
605 | #endif | ||
391 | if (J->needsplit) { | 606 | if (J->needsplit) { |
392 | int errcode = lj_vm_cpcall(J->L, NULL, J, cpsplit); | 607 | int errcode = lj_vm_cpcall(J->L, NULL, J, cpsplit); |
393 | if (errcode) { | 608 | if (errcode) { |