aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-12-06 16:18:18 +0100
committerMike Pall <mike>2010-12-06 18:21:51 +0100
commit159f51d8113555853a3325462f802010d4aac024 (patch)
tree270b24defe097629df0cf6afa021747babf31c75 /src
parentf6c4e8d3d70aa891de5a923a88ff670caef0a59d (diff)
downloadluajit-159f51d8113555853a3325462f802010d4aac024.tar.gz
luajit-159f51d8113555853a3325462f802010d4aac024.tar.bz2
luajit-159f51d8113555853a3325462f802010d4aac024.zip
Add IR_TOI64.
Diffstat (limited to 'src')
-rw-r--r--src/lj_asm.c19
-rw-r--r--src/lj_ir.h8
-rw-r--r--src/lj_opt_fold.c26
-rw-r--r--src/lj_target_x86.h1
4 files changed, 52 insertions, 2 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c
index 81529a56..e05de41e 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -1595,6 +1595,24 @@ static void asm_tobit(ASMState *as, IRIns *ir)
1595 ra_left(as, tmp, ir->op1); 1595 ra_left(as, tmp, ir->op1);
1596} 1596}
1597 1597
1598static void asm_toi64(ASMState *as, IRIns *ir)
1599{
1600 Reg dest = ra_dest(as, ir, RSET_GPR);
1601 IRRef lref = ir->op1;
1602 lua_assert(LJ_64); /* NYI: 32 bit register pairs. */
1603 if (ir->op2 == IRTOINT_TRUNCI64) {
1604 Reg left = asm_fuseload(as, lref, RSET_FPR);
1605 emit_mrm(as, XO_CVTTSD2SI, dest|REX_64, left);
1606 } else if (ir->op2 == IRTOINT_ZEXT64) {
1607 /* Nothing to do. This assumes 32 bit regs are already zero-extended. */
1608 ra_left(as, dest, lref); /* But may need to move regs. */
1609 } else {
1610 Reg left = asm_fuseload(as, lref, RSET_GPR);
1611 emit_mrm(as, XO_MOVSXd, dest|REX_64, left);
1612 lua_assert(ir->op2 == IRTOINT_SEXT64);
1613 }
1614}
1615
1598static void asm_strto(ASMState *as, IRIns *ir) 1616static void asm_strto(ASMState *as, IRIns *ir)
1599{ 1617{
1600 /* Force a spill slot for the destination register (if any). */ 1618 /* Force a spill slot for the destination register (if any). */
@@ -3531,6 +3549,7 @@ static void asm_ir(ASMState *as, IRIns *ir)
3531 asm_toint(as, ir); break; 3549 asm_toint(as, ir); break;
3532 break; 3550 break;
3533 case IR_TOBIT: asm_tobit(as, ir); break; 3551 case IR_TOBIT: asm_tobit(as, ir); break;
3552 case IR_TOI64: asm_toi64(as, ir); break;
3534 case IR_TOSTR: asm_tostr(as, ir); break; 3553 case IR_TOSTR: asm_tostr(as, ir); break;
3535 case IR_STRTO: asm_strto(as, ir); break; 3554 case IR_STRTO: asm_strto(as, ir); break;
3536 3555
diff --git a/src/lj_ir.h b/src/lj_ir.h
index 72a4d6b4..72c37343 100644
--- a/src/lj_ir.h
+++ b/src/lj_ir.h
@@ -119,6 +119,7 @@
119 _(TONUM, N , ref, ___) \ 119 _(TONUM, N , ref, ___) \
120 _(TOINT, N , ref, lit) \ 120 _(TOINT, N , ref, lit) \
121 _(TOBIT, N , ref, ref) \ 121 _(TOBIT, N , ref, ref) \
122 _(TOI64, N , ref, lit) \
122 _(TOSTR, N , ref, ___) \ 123 _(TOSTR, N , ref, ___) \
123 _(STRTO, N , ref, ___) \ 124 _(STRTO, N , ref, ___) \
124 \ 125 \
@@ -204,11 +205,14 @@ IRFLDEF(FLENUM)
204#define IRXLOAD_READONLY 1 /* Load from read-only data. */ 205#define IRXLOAD_READONLY 1 /* Load from read-only data. */
205#define IRXLOAD_UNALIGNED 2 /* Unaligned load. */ 206#define IRXLOAD_UNALIGNED 2 /* Unaligned load. */
206 207
207/* TOINT mode, stored in op2. Ordered by strength of the checks. */ 208/* TOINT/TOI64 mode, stored in op2. Ordered by strength of the checks. */
208#define IRTOINT_CHECK 0 /* Number checked for integerness. */ 209#define IRTOINT_CHECK 0 /* Number checked for integerness. */
209#define IRTOINT_INDEX 1 /* Checked + special backprop rules. */ 210#define IRTOINT_INDEX 1 /* Checked + special backprop rules. */
210#define IRTOINT_ANY 2 /* Any FP number is ok. */ 211#define IRTOINT_ANY 2 /* Any FP number is ok. */
211#define IRTOINT_TOBIT 3 /* Cache only: TOBIT conversion. */ 212#define IRTOINT_ZEXT64 3 /* Convert uint32_t to int64_t. */
213#define IRTOINT_SEXT64 4 /* Convert int32_t to int64_t. */
214#define IRTOINT_TRUNCI64 5 /* Truncate number to int64_t. */
215#define IRTOINT_TOBIT 6 /* Cache only: TOBIT conversion. */
212 216
213/* C call info for CALL* instructions. */ 217/* C call info for CALL* instructions. */
214typedef struct CCallInfo { 218typedef struct CCallInfo {
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index feddba87..cf5de82f 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -270,6 +270,23 @@ LJFOLDF(kfold_toint)
270 return INTFOLD(k); 270 return INTFOLD(k);
271} 271}
272 272
273LJFOLD(TOI64 KINT any)
274LJFOLDF(kfold_toi64_kint)
275{
276 lua_assert(fins->op2 == IRTOINT_ZEXT64 || fins->op2 == IRTOINT_SEXT64);
277 if (fins->op2 == IRTOINT_ZEXT64)
278 return lj_ir_kint64(J, (int64_t)(uint32_t)fleft->i);
279 else
280 return lj_ir_kint64(J, (int64_t)(int32_t)fleft->i);
281}
282
283LJFOLD(TOI64 KNUM any)
284LJFOLDF(kfold_toi64_knum)
285{
286 lua_assert(fins->op2 == IRTOINT_TRUNCI64);
287 return lj_ir_kint64(J, (int64_t)knumleft);
288}
289
273LJFOLD(TOSTR KNUM) 290LJFOLD(TOSTR KNUM)
274LJFOLDF(kfold_tostr_knum) 291LJFOLDF(kfold_tostr_knum)
275{ 292{
@@ -471,6 +488,15 @@ LJFOLDF(shortcut_leftleft_across_phi)
471 return fleft->op1; /* f(g(x)) ==> x */ 488 return fleft->op1; /* f(g(x)) ==> x */
472} 489}
473 490
491LJFOLD(TOI64 TONUM any)
492LJFOLDF(shortcut_leftleft_toint64)
493{
494 /* Fold even across PHI to avoid expensive int->num->int64 conversions. */
495 fins->op1 = fleft->op1; /* (int64_t)(double)(int)x ==> (int64_t)x */
496 fins->op2 = IRTOINT_SEXT64;
497 return RETRYFOLD;
498}
499
474/* -- FP algebraic simplifications ---------------------------------------- */ 500/* -- FP algebraic simplifications ---------------------------------------- */
475 501
476/* FP arithmetic is tricky -- there's not much to simplify. 502/* FP arithmetic is tricky -- there's not much to simplify.
diff --git a/src/lj_target_x86.h b/src/lj_target_x86.h
index d3956a09..bf58d67c 100644
--- a/src/lj_target_x86.h
+++ b/src/lj_target_x86.h
@@ -230,6 +230,7 @@ typedef enum {
230 XO_MOVZXw = XO_0f(b7), 230 XO_MOVZXw = XO_0f(b7),
231 XO_MOVSXb = XO_0f(be), 231 XO_MOVSXb = XO_0f(be),
232 XO_MOVSXw = XO_0f(bf), 232 XO_MOVSXw = XO_0f(bf),
233 XO_MOVSXd = XO_(63),
233 XO_BSWAP = XO_0f(c8), 234 XO_BSWAP = XO_0f(c8),
234 235
235 XO_MOVSD = XO_f20f(10), 236 XO_MOVSD = XO_f20f(10),