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 | |
| parent | f6c4e8d3d70aa891de5a923a88ff670caef0a59d (diff) | |
| download | luajit-159f51d8113555853a3325462f802010d4aac024.tar.gz luajit-159f51d8113555853a3325462f802010d4aac024.tar.bz2 luajit-159f51d8113555853a3325462f802010d4aac024.zip | |
Add IR_TOI64.
| -rw-r--r-- | lib/dump.lua | 6 | ||||
| -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 |
5 files changed, 56 insertions, 4 deletions
diff --git a/lib/dump.lua b/lib/dump.lua index 3c726484..687d79db 100644 --- a/lib/dump.lua +++ b/lib/dump.lua | |||
| @@ -219,7 +219,8 @@ span.irt_int, span.irt_i8, span.irt_u8, span.irt_i16, span.irt_u16 { color: #b04 | |||
| 219 | 219 | ||
| 220 | local colorize, irtype | 220 | local colorize, irtype |
| 221 | 221 | ||
| 222 | -- Lookup table to convert some literals into names. | 222 | -- Lookup tables to convert some literals into names. |
| 223 | local tointname = { [0] = "check", "index", "", "Z", "S", "T", } | ||
| 223 | local litname = { | 224 | local litname = { |
| 224 | ["SLOAD "] = setmetatable({}, { __index = function(t, mode) | 225 | ["SLOAD "] = setmetatable({}, { __index = function(t, mode) |
| 225 | local s = "" | 226 | local s = "" |
| @@ -233,7 +234,8 @@ local litname = { | |||
| 233 | return s | 234 | return s |
| 234 | end}), | 235 | end}), |
| 235 | ["XLOAD "] = { [0] = "", "R", "U", "RU", }, | 236 | ["XLOAD "] = { [0] = "", "R", "U", "RU", }, |
| 236 | ["TOINT "] = { [0] = "check", "index", "", }, | 237 | ["TOINT "] = tointname, |
| 238 | ["TOI64 "] = tointname, | ||
| 237 | ["FLOAD "] = vmdef.irfield, | 239 | ["FLOAD "] = vmdef.irfield, |
| 238 | ["FREF "] = vmdef.irfield, | 240 | ["FREF "] = vmdef.irfield, |
| 239 | ["FPMATH"] = vmdef.irfpm, | 241 | ["FPMATH"] = vmdef.irfpm, |
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), |
