diff options
author | Mike Pall <mike> | 2010-12-06 16:18:18 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2010-12-06 18:21:51 +0100 |
commit | 159f51d8113555853a3325462f802010d4aac024 (patch) | |
tree | 270b24defe097629df0cf6afa021747babf31c75 /src | |
parent | f6c4e8d3d70aa891de5a923a88ff670caef0a59d (diff) | |
download | luajit-159f51d8113555853a3325462f802010d4aac024.tar.gz luajit-159f51d8113555853a3325462f802010d4aac024.tar.bz2 luajit-159f51d8113555853a3325462f802010d4aac024.zip |
Add IR_TOI64.
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_asm.c | 19 | ||||
-rw-r--r-- | src/lj_ir.h | 8 | ||||
-rw-r--r-- | src/lj_opt_fold.c | 26 | ||||
-rw-r--r-- | src/lj_target_x86.h | 1 |
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 | ||
1598 | static 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 | |||
1598 | static void asm_strto(ASMState *as, IRIns *ir) | 1616 | static 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. */ |
214 | typedef struct CCallInfo { | 218 | typedef 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 | ||
273 | LJFOLD(TOI64 KINT any) | ||
274 | LJFOLDF(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 | |||
283 | LJFOLD(TOI64 KNUM any) | ||
284 | LJFOLDF(kfold_toi64_knum) | ||
285 | { | ||
286 | lua_assert(fins->op2 == IRTOINT_TRUNCI64); | ||
287 | return lj_ir_kint64(J, (int64_t)knumleft); | ||
288 | } | ||
289 | |||
273 | LJFOLD(TOSTR KNUM) | 290 | LJFOLD(TOSTR KNUM) |
274 | LJFOLDF(kfold_tostr_knum) | 291 | LJFOLDF(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 | ||
491 | LJFOLD(TOI64 TONUM any) | ||
492 | LJFOLDF(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), |