diff options
| author | Mike Pall <mike> | 2010-12-05 21:50:52 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2010-12-05 22:12:31 +0100 |
| commit | 5a13fa69d95993fa68b12be4091f48b80844bdcf (patch) | |
| tree | 73ec2ee4d64eec20245f198fde91eff9b3eadf35 /src | |
| parent | b1fb71fb981c464868e6bc669363658a98ecbd9e (diff) | |
| download | luajit-5a13fa69d95993fa68b12be4091f48b80844bdcf.tar.gz luajit-5a13fa69d95993fa68b12be4091f48b80844bdcf.tar.bz2 luajit-5a13fa69d95993fa68b12be4091f48b80844bdcf.zip | |
Add IR_KINT64.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_asm.c | 65 | ||||
| -rw-r--r-- | src/lj_def.h | 3 | ||||
| -rw-r--r-- | src/lj_ir.c | 94 | ||||
| -rw-r--r-- | src/lj_ir.h | 40 | ||||
| -rw-r--r-- | src/lj_iropt.h | 19 | ||||
| -rw-r--r-- | src/lj_jit.h | 2 | ||||
| -rw-r--r-- | src/lj_opt_mem.c | 2 | ||||
| -rw-r--r-- | src/lj_record.c | 3 | ||||
| -rw-r--r-- | src/lj_trace.c | 2 |
9 files changed, 135 insertions, 95 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index 6bb2b8c6..4c31a3e9 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
| @@ -384,15 +384,23 @@ static void emit_loadi(ASMState *as, Reg r, int32_t i) | |||
| 384 | emit_loadi(as, (r), ptr2addr((addr))) | 384 | emit_loadi(as, (r), ptr2addr((addr))) |
| 385 | 385 | ||
| 386 | #if LJ_64 | 386 | #if LJ_64 |
| 387 | /* mov r, imm64 */ | 387 | /* mov r, imm64 or shorter 32 bit extended load. */ |
| 388 | static void emit_loadu64(ASMState *as, Reg r, uint64_t i) | 388 | static void emit_loadu64(ASMState *as, Reg r, uint64_t u64) |
| 389 | { | 389 | { |
| 390 | MCode *p = as->mcp; | 390 | if (checku32(u64)) { /* 32 bit load clears upper 32 bits. */ |
| 391 | *(uint64_t *)(p-8) = i; | 391 | emit_loadi(as, r, (int32_t)u64); |
| 392 | p[-9] = (MCode)(XI_MOVri+(r&7)); | 392 | } else if (checki32((int64_t)u64)) { /* Sign-extended 32 bit load. */ |
| 393 | p[-10] = 0x48 + ((r>>3)&1); | 393 | MCode *p = as->mcp; |
| 394 | p -= 10; | 394 | *(int32_t *)(p-4) = (int32_t)u64; |
| 395 | as->mcp = p; | 395 | as->mcp = emit_opm(XO_MOVmi, XM_REG, REX_64, r, p, -4); |
| 396 | } else { /* Full-size 64 bit load. */ | ||
| 397 | MCode *p = as->mcp; | ||
| 398 | *(uint64_t *)(p-8) = u64; | ||
| 399 | p[-9] = (MCode)(XI_MOVri+(r&7)); | ||
| 400 | p[-10] = 0x48 + ((r>>3)&1); | ||
| 401 | p -= 10; | ||
| 402 | as->mcp = p; | ||
| 403 | } | ||
| 396 | } | 404 | } |
| 397 | #endif | 405 | #endif |
| 398 | 406 | ||
| @@ -618,6 +626,10 @@ static Reg ra_rematk(ASMState *as, IRIns *ir) | |||
| 618 | } else if (ir->o == IR_KPRI) { /* REF_NIL stores ASMREF_L register. */ | 626 | } else if (ir->o == IR_KPRI) { /* REF_NIL stores ASMREF_L register. */ |
| 619 | lua_assert(irt_isnil(ir->t)); | 627 | lua_assert(irt_isnil(ir->t)); |
| 620 | emit_getgl(as, r, jit_L); | 628 | emit_getgl(as, r, jit_L); |
| 629 | #if LJ_64 /* NYI: 32 bit register pairs. */ | ||
| 630 | } else if (ir->o == IR_KINT64) { | ||
| 631 | emit_loadu64(as, r, ir_kint64(ir)->u64); | ||
| 632 | #endif | ||
| 621 | } else { | 633 | } else { |
| 622 | lua_assert(ir->o == IR_KINT || ir->o == IR_KGC || | 634 | lua_assert(ir->o == IR_KINT || ir->o == IR_KGC || |
| 623 | ir->o == IR_KPTR || ir->o == IR_KNULL); | 635 | ir->o == IR_KPTR || ir->o == IR_KNULL); |
| @@ -909,6 +921,11 @@ static void ra_left(ASMState *as, Reg dest, IRRef lref) | |||
| 909 | emit_loadn(as, dest, tv); | 921 | emit_loadn(as, dest, tv); |
| 910 | return; | 922 | return; |
| 911 | } | 923 | } |
| 924 | #if LJ_64 /* NYI: 32 bit register pairs. */ | ||
| 925 | } else if (ir->o == IR_KINT64) { | ||
| 926 | emit_loadu64(as, dest, ir_kint64(ir)->u64); | ||
| 927 | return; | ||
| 928 | #endif | ||
| 912 | } else { | 929 | } else { |
| 913 | lua_assert(ir->o == IR_KINT || ir->o == IR_KGC || | 930 | lua_assert(ir->o == IR_KINT || ir->o == IR_KGC || |
| 914 | ir->o == IR_KPTR || ir->o == IR_KNULL); | 931 | ir->o == IR_KPTR || ir->o == IR_KNULL); |
| @@ -1343,7 +1360,8 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) | |||
| 1343 | lua_assert(!(nargs > 2 && (ci->flags&CCI_FASTCALL))); /* Avoid stack adj. */ | 1360 | lua_assert(!(nargs > 2 && (ci->flags&CCI_FASTCALL))); /* Avoid stack adj. */ |
| 1344 | emit_call(as, ci->func); | 1361 | emit_call(as, ci->func); |
| 1345 | for (n = 0; n < nargs; n++) { /* Setup args. */ | 1362 | for (n = 0; n < nargs; n++) { /* Setup args. */ |
| 1346 | IRIns *ir = IR(args[n]); | 1363 | IRRef ref = args[n]; |
| 1364 | IRIns *ir = IR(ref); | ||
| 1347 | Reg r; | 1365 | Reg r; |
| 1348 | #if LJ_64 && LJ_ABI_WIN | 1366 | #if LJ_64 && LJ_ABI_WIN |
| 1349 | /* Windows/x64 argument registers are strictly positional. */ | 1367 | /* Windows/x64 argument registers are strictly positional. */ |
| @@ -1364,38 +1382,42 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) | |||
| 1364 | } | 1382 | } |
| 1365 | #endif | 1383 | #endif |
| 1366 | if (r) { /* Argument is in a register. */ | 1384 | if (r) { /* Argument is in a register. */ |
| 1367 | if (r < RID_MAX_GPR && args[n] < ASMREF_TMP1) { | 1385 | if (r < RID_MAX_GPR && ref < ASMREF_TMP1) { |
| 1368 | emit_loadi(as, r, ir->i); | 1386 | #if LJ_64 /* NYI: 32 bit register pairs. */ |
| 1387 | if (ir->o == IR_KINT64) | ||
| 1388 | emit_loadu64(as, r, ir_kint64(ir)->u64); | ||
| 1389 | else | ||
| 1390 | #endif | ||
| 1391 | emit_loadi(as, r, ir->i); | ||
| 1369 | } else { | 1392 | } else { |
| 1370 | lua_assert(rset_test(as->freeset, r)); /* Must have been evicted. */ | 1393 | lua_assert(rset_test(as->freeset, r)); /* Must have been evicted. */ |
| 1371 | if (ra_hasreg(ir->r)) { | 1394 | if (ra_hasreg(ir->r)) { |
| 1372 | ra_noweak(as, ir->r); | 1395 | ra_noweak(as, ir->r); |
| 1373 | ra_movrr(as, ir, r, ir->r); | 1396 | ra_movrr(as, ir, r, ir->r); |
| 1374 | } else { | 1397 | } else { |
| 1375 | ra_allocref(as, args[n], RID2RSET(r)); | 1398 | ra_allocref(as, ref, RID2RSET(r)); |
| 1376 | } | 1399 | } |
| 1377 | } | 1400 | } |
| 1378 | } else if (irt_isnum(ir->t)) { /* FP argument is on stack. */ | 1401 | } else if (irt_isnum(ir->t)) { /* FP argument is on stack. */ |
| 1379 | if (!LJ_64 && (ofs & 4) && irref_isk(args[n])) { | 1402 | if (LJ_32 && (ofs & 4) && irref_isk(ref)) { |
| 1380 | /* Split stores for unaligned FP consts. */ | 1403 | /* Split stores for unaligned FP consts. */ |
| 1381 | emit_movmroi(as, RID_ESP, ofs, (int32_t)ir_knum(ir)->u32.lo); | 1404 | emit_movmroi(as, RID_ESP, ofs, (int32_t)ir_knum(ir)->u32.lo); |
| 1382 | emit_movmroi(as, RID_ESP, ofs+4, (int32_t)ir_knum(ir)->u32.hi); | 1405 | emit_movmroi(as, RID_ESP, ofs+4, (int32_t)ir_knum(ir)->u32.hi); |
| 1383 | } else { | 1406 | } else { |
| 1384 | if ((allow & RSET_FPR) == RSET_EMPTY) | 1407 | if ((allow & RSET_FPR) == RSET_EMPTY) |
| 1385 | lj_trace_err(as->J, LJ_TRERR_NYICOAL); | 1408 | lj_trace_err(as->J, LJ_TRERR_NYICOAL); |
| 1386 | r = ra_alloc1(as, args[n], allow & RSET_FPR); | 1409 | r = ra_alloc1(as, ref, allow & RSET_FPR); |
| 1387 | allow &= ~RID2RSET(r); | 1410 | allow &= ~RID2RSET(r); |
| 1388 | emit_rmro(as, XO_MOVSDto, r, RID_ESP, ofs); | 1411 | emit_rmro(as, XO_MOVSDto, r, RID_ESP, ofs); |
| 1389 | } | 1412 | } |
| 1390 | ofs += 8; | 1413 | ofs += 8; |
| 1391 | } else { /* Non-FP argument is on stack. */ | 1414 | } else { /* Non-FP argument is on stack. */ |
| 1392 | /* NYI: no widening for 64 bit parameters on x64. */ | 1415 | if (LJ_32 && ref < ASMREF_TMP1) { |
| 1393 | if (args[n] < ASMREF_TMP1) { | ||
| 1394 | emit_movmroi(as, RID_ESP, ofs, ir->i); | 1416 | emit_movmroi(as, RID_ESP, ofs, ir->i); |
| 1395 | } else { | 1417 | } else { |
| 1396 | if ((allow & RSET_GPR) == RSET_EMPTY) | 1418 | if ((allow & RSET_GPR) == RSET_EMPTY) |
| 1397 | lj_trace_err(as->J, LJ_TRERR_NYICOAL); | 1419 | lj_trace_err(as->J, LJ_TRERR_NYICOAL); |
| 1398 | r = ra_alloc1(as, args[n], allow & RSET_GPR); | 1420 | r = ra_alloc1(as, ref, allow & RSET_GPR); |
| 1399 | allow &= ~RID2RSET(r); | 1421 | allow &= ~RID2RSET(r); |
| 1400 | emit_movtomro(as, REX_64IR(ir, r), RID_ESP, ofs); | 1422 | emit_movtomro(as, REX_64IR(ir, r), RID_ESP, ofs); |
| 1401 | } | 1423 | } |
| @@ -1936,8 +1958,9 @@ static void asm_fstore(ASMState *as, IRIns *ir) | |||
| 1936 | /* The IRT_I16/IRT_U16 stores should never be simplified for constant | 1958 | /* The IRT_I16/IRT_U16 stores should never be simplified for constant |
| 1937 | ** values since mov word [mem], imm16 has a length-changing prefix. | 1959 | ** values since mov word [mem], imm16 has a length-changing prefix. |
| 1938 | */ | 1960 | */ |
| 1939 | lua_assert(!(irref_isk(ir->op2) && irt_is64(ir->t))); /* NYI: KINT64. */ | 1961 | if (!irref_isk(ir->op2) || irt_isi16(ir->t) || irt_isu16(ir->t) || |
| 1940 | if (!irref_isk(ir->op2) || irt_isi16(ir->t) || irt_isu16(ir->t)) { | 1962 | (LJ_64 && irt_is64(ir->t) && |
| 1963 | !checki32((int64_t)ir_k64(IR(ir->op2))->u64))) { | ||
| 1941 | RegSet allow8 = (irt_isi8(ir->t) || irt_isu8(ir->t)) ? RSET_GPR8 : RSET_GPR; | 1964 | RegSet allow8 = (irt_isi8(ir->t) || irt_isu8(ir->t)) ? RSET_GPR8 : RSET_GPR; |
| 1942 | src = ra_alloc1(as, ir->op2, allow8); | 1965 | src = ra_alloc1(as, ir->op2, allow8); |
| 1943 | rset_clear(allow, src); | 1966 | rset_clear(allow, src); |
| @@ -2496,7 +2519,7 @@ static void asm_add(ASMState *as, IRIns *ir) | |||
| 2496 | if (irt_isnum(ir->t)) | 2519 | if (irt_isnum(ir->t)) |
| 2497 | asm_fparith(as, ir, XO_ADDSD); | 2520 | asm_fparith(as, ir, XO_ADDSD); |
| 2498 | else if ((as->flags & JIT_F_LEA_AGU) || as->testmcp == as->mcp || | 2521 | else if ((as->flags & JIT_F_LEA_AGU) || as->testmcp == as->mcp || |
| 2499 | !asm_lea(as, ir)) | 2522 | irt_is64(ir->t) || !asm_lea(as, ir)) |
| 2500 | asm_intarith(as, ir, XOg_ADD); | 2523 | asm_intarith(as, ir, XOg_ADD); |
| 2501 | } | 2524 | } |
| 2502 | 2525 | ||
| @@ -2615,7 +2638,7 @@ static void asm_comp_(ASMState *as, IRIns *ir, int cc) | |||
| 2615 | else if ((cc & 0xa) == 0x2) cc ^= 5; /* A <-> B, AE <-> BE */ | 2638 | else if ((cc & 0xa) == 0x2) cc ^= 5; /* A <-> B, AE <-> BE */ |
| 2616 | lref = ir->op2; rref = ir->op1; | 2639 | lref = ir->op2; rref = ir->op1; |
| 2617 | } | 2640 | } |
| 2618 | if (irref_isk(rref)) { | 2641 | if (irref_isk(rref) && IR(rref)->o != IR_KINT64) { |
| 2619 | IRIns *irl = IR(lref); | 2642 | IRIns *irl = IR(lref); |
| 2620 | int32_t imm = IR(rref)->i; | 2643 | int32_t imm = IR(rref)->i; |
| 2621 | /* Check wether we can use test ins. Not for unsigned, since CF=0. */ | 2644 | /* Check wether we can use test ins. Not for unsigned, since CF=0. */ |
diff --git a/src/lj_def.h b/src/lj_def.h index 074090af..e72a8ef9 100644 --- a/src/lj_def.h +++ b/src/lj_def.h | |||
| @@ -62,7 +62,7 @@ typedef unsigned __int32 uintptr_t; | |||
| 62 | #define LJ_MIN_SBUF 32 /* Min. string buffer length. */ | 62 | #define LJ_MIN_SBUF 32 /* Min. string buffer length. */ |
| 63 | #define LJ_MIN_VECSZ 8 /* Min. size for growable vectors. */ | 63 | #define LJ_MIN_VECSZ 8 /* Min. size for growable vectors. */ |
| 64 | #define LJ_MIN_IRSZ 32 /* Min. size for growable IR. */ | 64 | #define LJ_MIN_IRSZ 32 /* Min. size for growable IR. */ |
| 65 | #define LJ_MIN_KNUMSZ 16 /* Min. size for chained KNUM array. */ | 65 | #define LJ_MIN_K64SZ 16 /* Min. size for chained K64Array. */ |
| 66 | 66 | ||
| 67 | /* JIT compiler limits. */ | 67 | /* JIT compiler limits. */ |
| 68 | #define LJ_MAX_JSLOTS 250 /* Max. # of stack slots for a trace. */ | 68 | #define LJ_MAX_JSLOTS 250 /* Max. # of stack slots for a trace. */ |
| @@ -90,6 +90,7 @@ typedef unsigned __int32 uintptr_t; | |||
| 90 | #define checki16(x) ((x) == (int32_t)(int16_t)(x)) | 90 | #define checki16(x) ((x) == (int32_t)(int16_t)(x)) |
| 91 | #define checku16(x) ((x) == (int32_t)(uint16_t)(x)) | 91 | #define checku16(x) ((x) == (int32_t)(uint16_t)(x)) |
| 92 | #define checki32(x) ((x) == (int32_t)(x)) | 92 | #define checki32(x) ((x) == (int32_t)(x)) |
| 93 | #define checku32(x) ((x) == (uint32_t)(x)) | ||
| 93 | #define checkptr32(x) ((uintptr_t)(x) == (uint32_t)(uintptr_t)(x)) | 94 | #define checkptr32(x) ((uintptr_t)(x) == (uint32_t)(uintptr_t)(x)) |
| 94 | 95 | ||
| 95 | /* Every half-decent C compiler transforms this into a rotate instruction. */ | 96 | /* Every half-decent C compiler transforms this into a rotate instruction. */ |
diff --git a/src/lj_ir.c b/src/lj_ir.c index 529c333b..d39a345f 100644 --- a/src/lj_ir.c +++ b/src/lj_ir.c | |||
| @@ -167,88 +167,95 @@ found: | |||
| 167 | return TREF(ref, IRT_INT); | 167 | return TREF(ref, IRT_INT); |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | /* The MRef inside the KNUM IR instruction holds the address of the constant | 170 | /* The MRef inside the KNUM/KINT64 IR instructions holds the address of the |
| 171 | ** (an aligned double or a special 64 bit pattern). The KNUM constants | 171 | ** 64 bit constant. The constants themselves are stored in a chained array |
| 172 | ** themselves are stored in a chained array and shared across traces. | 172 | ** and shared across traces. |
| 173 | ** | 173 | ** |
| 174 | ** Rationale for choosing this data structure: | 174 | ** Rationale for choosing this data structure: |
| 175 | ** - The address of the constants is embedded in the generated machine code | 175 | ** - The address of the constants is embedded in the generated machine code |
| 176 | ** and must never move. A resizable array or hash table wouldn't work. | 176 | ** and must never move. A resizable array or hash table wouldn't work. |
| 177 | ** - Most apps need very few non-integer constants (less than a dozen). | 177 | ** - Most apps need very few non-32 bit integer constants (less than a dozen). |
| 178 | ** - Linear search is hard to beat in terms of speed and low complexity. | 178 | ** - Linear search is hard to beat in terms of speed and low complexity. |
| 179 | */ | 179 | */ |
| 180 | typedef struct KNumArray { | 180 | typedef struct K64Array { |
| 181 | MRef next; /* Pointer to next list. */ | 181 | MRef next; /* Pointer to next list. */ |
| 182 | MSize numk; /* Number of used elements in this array. */ | 182 | MSize numk; /* Number of used elements in this array. */ |
| 183 | TValue k[LJ_MIN_KNUMSZ]; /* Array of constants. */ | 183 | TValue k[LJ_MIN_K64SZ]; /* Array of constants. */ |
| 184 | } KNumArray; | 184 | } K64Array; |
| 185 | 185 | ||
| 186 | /* Free all chained arrays. */ | 186 | /* Free all chained arrays. */ |
| 187 | void lj_ir_knum_freeall(jit_State *J) | 187 | void lj_ir_k64_freeall(jit_State *J) |
| 188 | { | 188 | { |
| 189 | KNumArray *kn; | 189 | K64Array *k; |
| 190 | for (kn = mref(J->knum, KNumArray); kn; ) { | 190 | for (k = mref(J->k64, K64Array); k; ) { |
| 191 | KNumArray *next = mref(kn->next, KNumArray); | 191 | K64Array *next = mref(k->next, K64Array); |
| 192 | lj_mem_free(J2G(J), kn, sizeof(KNumArray)); | 192 | lj_mem_free(J2G(J), k, sizeof(K64Array)); |
| 193 | kn = next; | 193 | k = next; |
| 194 | } | 194 | } |
| 195 | } | 195 | } |
| 196 | 196 | ||
| 197 | /* Find KNUM constant in chained array or add it. */ | 197 | /* Find 64 bit constant in chained array or add it. */ |
| 198 | static cTValue *ir_knum_find(jit_State *J, uint64_t nn) | 198 | static cTValue *ir_k64_find(jit_State *J, uint64_t u64) |
| 199 | { | 199 | { |
| 200 | KNumArray *kn, *knp = NULL; | 200 | K64Array *k, *kp = NULL; |
| 201 | TValue *ntv; | 201 | TValue *ntv; |
| 202 | MSize idx; | 202 | MSize idx; |
| 203 | /* Search for the constant in the whole chain of arrays. */ | 203 | /* Search for the constant in the whole chain of arrays. */ |
| 204 | for (kn = mref(J->knum, KNumArray); kn; kn = mref(kn->next, KNumArray)) { | 204 | for (k = mref(J->k64, K64Array); k; k = mref(k->next, K64Array)) { |
| 205 | knp = kn; /* Remember previous element in list. */ | 205 | kp = k; /* Remember previous element in list. */ |
| 206 | for (idx = 0; idx < kn->numk; idx++) { /* Search one array. */ | 206 | for (idx = 0; idx < k->numk; idx++) { /* Search one array. */ |
| 207 | TValue *tv = &kn->k[idx]; | 207 | TValue *tv = &k->k[idx]; |
| 208 | if (tv->u64 == nn) /* Needed for +-0/NaN/absmask. */ | 208 | if (tv->u64 == u64) /* Needed for +-0/NaN/absmask. */ |
| 209 | return tv; | 209 | return tv; |
| 210 | } | 210 | } |
| 211 | } | 211 | } |
| 212 | /* Constant was not found, need to add it. */ | 212 | /* Constant was not found, need to add it. */ |
| 213 | if (!(knp && knp->numk < LJ_MIN_KNUMSZ)) { /* Allocate a new array. */ | 213 | if (!(kp && kp->numk < LJ_MIN_K64SZ)) { /* Allocate a new array. */ |
| 214 | KNumArray *nkn = lj_mem_newt(J->L, sizeof(KNumArray), KNumArray); | 214 | K64Array *kn = lj_mem_newt(J->L, sizeof(K64Array), K64Array); |
| 215 | setmref(nkn->next, NULL); | 215 | setmref(kn->next, NULL); |
| 216 | nkn->numk = 0; | 216 | kn->numk = 0; |
| 217 | if (knp) | 217 | if (kp) |
| 218 | setmref(knp->next, nkn); /* Chain to the end of the list. */ | 218 | setmref(kp->next, kn); /* Chain to the end of the list. */ |
| 219 | else | 219 | else |
| 220 | setmref(J->knum, nkn); /* Link first array. */ | 220 | setmref(J->k64, kn); /* Link first array. */ |
| 221 | knp = nkn; | 221 | kp = kn; |
| 222 | } | 222 | } |
| 223 | ntv = &knp->k[knp->numk++]; /* Add to current array. */ | 223 | ntv = &kp->k[kp->numk++]; /* Add to current array. */ |
| 224 | ntv->u64 = nn; | 224 | ntv->u64 = u64; |
| 225 | return ntv; | 225 | return ntv; |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | /* Intern FP constant, given by its address. */ | 228 | /* Intern 64 bit constant, given by its address. */ |
| 229 | TRef lj_ir_knum_addr(jit_State *J, cTValue *tv) | 229 | TRef lj_ir_k64(jit_State *J, IROp op, cTValue *tv) |
| 230 | { | 230 | { |
| 231 | IRIns *ir, *cir = J->cur.ir; | 231 | IRIns *ir, *cir = J->cur.ir; |
| 232 | IRRef ref; | 232 | IRRef ref; |
| 233 | for (ref = J->chain[IR_KNUM]; ref; ref = cir[ref].prev) | 233 | IRType t = op == IR_KNUM ? IRT_NUM : IRT_I64; |
| 234 | if (ir_knum(&cir[ref]) == tv) | 234 | for (ref = J->chain[op]; ref; ref = cir[ref].prev) |
| 235 | if (ir_k64(&cir[ref]) == tv) | ||
| 235 | goto found; | 236 | goto found; |
| 236 | ref = ir_nextk(J); | 237 | ref = ir_nextk(J); |
| 237 | ir = IR(ref); | 238 | ir = IR(ref); |
| 238 | lua_assert(checkptr32(tv)); | 239 | lua_assert(checkptr32(tv)); |
| 239 | setmref(ir->ptr, tv); | 240 | setmref(ir->ptr, tv); |
| 240 | ir->t.irt = IRT_NUM; | 241 | ir->t.irt = t; |
| 241 | ir->o = IR_KNUM; | 242 | ir->o = op; |
| 242 | ir->prev = J->chain[IR_KNUM]; | 243 | ir->prev = J->chain[op]; |
| 243 | J->chain[IR_KNUM] = (IRRef1)ref; | 244 | J->chain[op] = (IRRef1)ref; |
| 244 | found: | 245 | found: |
| 245 | return TREF(ref, IRT_NUM); | 246 | return TREF(ref, t); |
| 246 | } | 247 | } |
| 247 | 248 | ||
| 248 | /* Intern FP constant, given by its 64 bit pattern. */ | 249 | /* Intern FP constant, given by its 64 bit pattern. */ |
| 249 | TRef lj_ir_knum_nn(jit_State *J, uint64_t nn) | 250 | TRef lj_ir_knum_u64(jit_State *J, uint64_t u64) |
| 251 | { | ||
| 252 | return lj_ir_k64(J, IR_KNUM, ir_k64_find(J, u64)); | ||
| 253 | } | ||
| 254 | |||
| 255 | /* Intern 64 bit integer constant. */ | ||
| 256 | TRef lj_ir_kint64(jit_State *J, uint64_t u64) | ||
| 250 | { | 257 | { |
| 251 | return lj_ir_knum_addr(J, ir_knum_find(J, nn)); | 258 | return lj_ir_k64(J, IR_KINT64, ir_k64_find(J, u64)); |
| 252 | } | 259 | } |
| 253 | 260 | ||
| 254 | /* Check whether a number is int and return it. -0 is NOT considered an int. */ | 261 | /* Check whether a number is int and return it. -0 is NOT considered an int. */ |
| @@ -373,6 +380,9 @@ void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir) | |||
| 373 | } else if (irt_isnum(ir->t)) { | 380 | } else if (irt_isnum(ir->t)) { |
| 374 | lua_assert(ir->o == IR_KNUM); | 381 | lua_assert(ir->o == IR_KNUM); |
| 375 | setnumV(tv, ir_knum(ir)->n); | 382 | setnumV(tv, ir_knum(ir)->n); |
| 383 | } else if (irt_is64(ir->t)) { | ||
| 384 | lua_assert(ir->o == IR_KINT64); | ||
| 385 | setnumV(tv, (int64_t)ir_kint64(ir)->u64); /* NYI: use FFI int64_t. */ | ||
| 376 | } else if (irt_ispri(ir->t)) { | 386 | } else if (irt_ispri(ir->t)) { |
| 377 | lua_assert(ir->o == IR_KPRI); | 387 | lua_assert(ir->o == IR_KPRI); |
| 378 | setitype(tv, irt_toitype(ir->t)); | 388 | setitype(tv, irt_toitype(ir->t)); |
diff --git a/src/lj_ir.h b/src/lj_ir.h index 9d90d69f..b8ea0fa9 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h | |||
| @@ -12,6 +12,24 @@ | |||
| 12 | 12 | ||
| 13 | /* IR instruction definition. Order matters, see below. */ | 13 | /* IR instruction definition. Order matters, see below. */ |
| 14 | #define IRDEF(_) \ | 14 | #define IRDEF(_) \ |
| 15 | /* Guarded assertions. */ \ | ||
| 16 | /* Must be properly aligned to flip opposites (^1) and (un)ordered (^4). */ \ | ||
| 17 | _(LT, N , ref, ref) \ | ||
| 18 | _(GE, N , ref, ref) \ | ||
| 19 | _(LE, N , ref, ref) \ | ||
| 20 | _(GT, N , ref, ref) \ | ||
| 21 | \ | ||
| 22 | _(ULT, N , ref, ref) \ | ||
| 23 | _(UGE, N , ref, ref) \ | ||
| 24 | _(ULE, N , ref, ref) \ | ||
| 25 | _(UGT, N , ref, ref) \ | ||
| 26 | \ | ||
| 27 | _(EQ, C , ref, ref) \ | ||
| 28 | _(NE, C , ref, ref) \ | ||
| 29 | \ | ||
| 30 | _(ABC, N , ref, ref) \ | ||
| 31 | _(RETF, S , ref, ref) \ | ||
| 32 | \ | ||
| 15 | /* Miscellaneous ops. */ \ | 33 | /* Miscellaneous ops. */ \ |
| 16 | _(NOP, N , ___, ___) \ | 34 | _(NOP, N , ___, ___) \ |
| 17 | _(BASE, N , lit, lit) \ | 35 | _(BASE, N , lit, lit) \ |
| @@ -26,26 +44,9 @@ | |||
| 26 | _(KPTR, N , cst, ___) \ | 44 | _(KPTR, N , cst, ___) \ |
| 27 | _(KNULL, N , cst, ___) \ | 45 | _(KNULL, N , cst, ___) \ |
| 28 | _(KNUM, N , cst, ___) \ | 46 | _(KNUM, N , cst, ___) \ |
| 47 | _(KINT64, N , cst, ___) \ | ||
| 29 | _(KSLOT, N , ref, lit) \ | 48 | _(KSLOT, N , ref, lit) \ |
| 30 | \ | 49 | \ |
| 31 | /* Guarded assertions. */ \ | ||
| 32 | /* Must be properly aligned to flip opposites (^1) and (un)ordered (^4). */ \ | ||
| 33 | _(EQ, C , ref, ref) \ | ||
| 34 | _(NE, C , ref, ref) \ | ||
| 35 | \ | ||
| 36 | _(ABC, N , ref, ref) \ | ||
| 37 | _(RETF, S , ref, ref) \ | ||
| 38 | \ | ||
| 39 | _(LT, N , ref, ref) \ | ||
| 40 | _(GE, N , ref, ref) \ | ||
| 41 | _(LE, N , ref, ref) \ | ||
| 42 | _(GT, N , ref, ref) \ | ||
| 43 | \ | ||
| 44 | _(ULT, N , ref, ref) \ | ||
| 45 | _(UGE, N , ref, ref) \ | ||
| 46 | _(ULE, N , ref, ref) \ | ||
| 47 | _(UGT, N , ref, ref) \ | ||
| 48 | \ | ||
| 49 | /* Bit ops. */ \ | 50 | /* Bit ops. */ \ |
| 50 | _(BNOT, N , ref, ___) \ | 51 | _(BNOT, N , ref, ___) \ |
| 51 | _(BSWAP, N , ref, ___) \ | 52 | _(BSWAP, N , ref, ___) \ |
| @@ -536,6 +537,9 @@ typedef union IRIns { | |||
| 536 | #define ir_ktab(ir) (gco2tab(ir_kgc((ir)))) | 537 | #define ir_ktab(ir) (gco2tab(ir_kgc((ir)))) |
| 537 | #define ir_kfunc(ir) (gco2func(ir_kgc((ir)))) | 538 | #define ir_kfunc(ir) (gco2func(ir_kgc((ir)))) |
| 538 | #define ir_knum(ir) check_exp((ir)->o == IR_KNUM, mref((ir)->ptr, cTValue)) | 539 | #define ir_knum(ir) check_exp((ir)->o == IR_KNUM, mref((ir)->ptr, cTValue)) |
| 540 | #define ir_kint64(ir) check_exp((ir)->o == IR_KINT64, mref((ir)->ptr,cTValue)) | ||
| 541 | #define ir_k64(ir) \ | ||
| 542 | check_exp((ir)->o == IR_KNUM || (ir)->o == IR_KINT64, mref((ir)->ptr,cTValue)) | ||
| 539 | #define ir_kptr(ir) check_exp((ir)->o == IR_KPTR, mref((ir)->ptr, void)) | 543 | #define ir_kptr(ir) check_exp((ir)->o == IR_KPTR, mref((ir)->ptr, void)) |
| 540 | 544 | ||
| 541 | LJ_STATIC_ASSERT((int)IRT_GUARD == (int)IRM_W); | 545 | LJ_STATIC_ASSERT((int)IRT_GUARD == (int)IRM_W); |
diff --git a/src/lj_iropt.h b/src/lj_iropt.h index 00bb2496..c05040d6 100644 --- a/src/lj_iropt.h +++ b/src/lj_iropt.h | |||
| @@ -39,10 +39,11 @@ static LJ_AINLINE IRRef lj_ir_nextins(jit_State *J) | |||
| 39 | 39 | ||
| 40 | /* Interning of constants. */ | 40 | /* Interning of constants. */ |
| 41 | LJ_FUNC TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k); | 41 | LJ_FUNC TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k); |
| 42 | LJ_FUNC void lj_ir_knum_freeall(jit_State *J); | 42 | LJ_FUNC void lj_ir_k64_freeall(jit_State *J); |
| 43 | LJ_FUNC TRef lj_ir_knum_addr(jit_State *J, cTValue *tv); | 43 | LJ_FUNC TRef lj_ir_k64(jit_State *J, IROp op, cTValue *tv); |
| 44 | LJ_FUNC TRef lj_ir_knum_nn(jit_State *J, uint64_t nn); | 44 | LJ_FUNC TRef lj_ir_knum_u64(jit_State *J, uint64_t u64); |
| 45 | LJ_FUNC TRef lj_ir_knumint(jit_State *J, lua_Number n); | 45 | LJ_FUNC TRef lj_ir_knumint(jit_State *J, lua_Number n); |
| 46 | LJ_FUNC TRef lj_ir_kint64(jit_State *J, uint64_t u64); | ||
| 46 | LJ_FUNC TRef lj_ir_kgc(jit_State *J, GCobj *o, IRType t); | 47 | LJ_FUNC TRef lj_ir_kgc(jit_State *J, GCobj *o, IRType t); |
| 47 | LJ_FUNC TRef lj_ir_kptr(jit_State *J, void *ptr); | 48 | LJ_FUNC TRef lj_ir_kptr(jit_State *J, void *ptr); |
| 48 | LJ_FUNC TRef lj_ir_knull(jit_State *J, IRType t); | 49 | LJ_FUNC TRef lj_ir_knull(jit_State *J, IRType t); |
| @@ -52,7 +53,7 @@ static LJ_AINLINE TRef lj_ir_knum(jit_State *J, lua_Number n) | |||
| 52 | { | 53 | { |
| 53 | TValue tv; | 54 | TValue tv; |
| 54 | tv.n = n; | 55 | tv.n = n; |
| 55 | return lj_ir_knum_nn(J, tv.u64); | 56 | return lj_ir_knum_u64(J, tv.u64); |
| 56 | } | 57 | } |
| 57 | 58 | ||
| 58 | #define lj_ir_kstr(J, str) lj_ir_kgc(J, obj2gco((str)), IRT_STR) | 59 | #define lj_ir_kstr(J, str) lj_ir_kgc(J, obj2gco((str)), IRT_STR) |
| @@ -60,13 +61,13 @@ static LJ_AINLINE TRef lj_ir_knum(jit_State *J, lua_Number n) | |||
| 60 | #define lj_ir_kfunc(J, func) lj_ir_kgc(J, obj2gco((func)), IRT_FUNC) | 61 | #define lj_ir_kfunc(J, func) lj_ir_kgc(J, obj2gco((func)), IRT_FUNC) |
| 61 | 62 | ||
| 62 | /* Special FP constants. */ | 63 | /* Special FP constants. */ |
| 63 | #define lj_ir_knum_zero(J) lj_ir_knum_nn(J, U64x(00000000,00000000)) | 64 | #define lj_ir_knum_zero(J) lj_ir_knum_u64(J, U64x(00000000,00000000)) |
| 64 | #define lj_ir_knum_one(J) lj_ir_knum_nn(J, U64x(3ff00000,00000000)) | 65 | #define lj_ir_knum_one(J) lj_ir_knum_u64(J, U64x(3ff00000,00000000)) |
| 65 | #define lj_ir_knum_tobit(J) lj_ir_knum_nn(J, U64x(43380000,00000000)) | 66 | #define lj_ir_knum_tobit(J) lj_ir_knum_u64(J, U64x(43380000,00000000)) |
| 66 | 67 | ||
| 67 | /* Special 128 bit SIMD constants. */ | 68 | /* Special 128 bit SIMD constants. */ |
| 68 | #define lj_ir_knum_abs(J) lj_ir_knum_addr(J, LJ_KSIMD(J, LJ_KSIMD_ABS)) | 69 | #define lj_ir_knum_abs(J) lj_ir_k64(J, IR_KNUM, LJ_KSIMD(J, LJ_KSIMD_ABS)) |
| 69 | #define lj_ir_knum_neg(J) lj_ir_knum_addr(J, LJ_KSIMD(J, LJ_KSIMD_NEG)) | 70 | #define lj_ir_knum_neg(J) lj_ir_k64(J, IR_KNUM, LJ_KSIMD(J, LJ_KSIMD_NEG)) |
| 70 | 71 | ||
| 71 | /* Access to constants. */ | 72 | /* Access to constants. */ |
| 72 | LJ_FUNC void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir); | 73 | LJ_FUNC void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir); |
diff --git a/src/lj_jit.h b/src/lj_jit.h index d309f828..c5902a61 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h | |||
| @@ -271,7 +271,7 @@ typedef struct jit_State { | |||
| 271 | int32_t framedepth; /* Current frame depth. */ | 271 | int32_t framedepth; /* Current frame depth. */ |
| 272 | int32_t retdepth; /* Return frame depth (count of RETF). */ | 272 | int32_t retdepth; /* Return frame depth (count of RETF). */ |
| 273 | 273 | ||
| 274 | MRef knum; /* Pointer to chained array of KNUM constants. */ | 274 | MRef k64; /* Pointer to chained array of 64 bit constants. */ |
| 275 | TValue ksimd[LJ_KSIMD__MAX*2+1]; /* 16 byte aligned SIMD constants. */ | 275 | TValue ksimd[LJ_KSIMD__MAX*2+1]; /* 16 byte aligned SIMD constants. */ |
| 276 | 276 | ||
| 277 | IRIns *irbuf; /* Temp. IR instruction buffer. Biased with REF_BIAS. */ | 277 | IRIns *irbuf; /* Temp. IR instruction buffer. Biased with REF_BIAS. */ |
diff --git a/src/lj_opt_mem.c b/src/lj_opt_mem.c index ee573cad..9b96d66e 100644 --- a/src/lj_opt_mem.c +++ b/src/lj_opt_mem.c | |||
| @@ -188,7 +188,7 @@ static TRef fwd_ahload(jit_State *J, IRRef xref) | |||
| 188 | tv = lj_tab_get(J->L, ir_ktab(IR(ir->op1)), &keyv); | 188 | tv = lj_tab_get(J->L, ir_ktab(IR(ir->op1)), &keyv); |
| 189 | lua_assert(itype2irt(tv) == irt_type(fins->t)); | 189 | lua_assert(itype2irt(tv) == irt_type(fins->t)); |
| 190 | if (irt_isnum(fins->t)) | 190 | if (irt_isnum(fins->t)) |
| 191 | return lj_ir_knum_nn(J, tv->u64); | 191 | return lj_ir_knum_u64(J, tv->u64); |
| 192 | else | 192 | else |
| 193 | return lj_ir_kstr(J, strV(tv)); | 193 | return lj_ir_kstr(J, strV(tv)); |
| 194 | } | 194 | } |
diff --git a/src/lj_record.c b/src/lj_record.c index de3f6a64..967022f5 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
| @@ -1863,7 +1863,8 @@ static void rec_setup_side(jit_State *J, GCtrace *T) | |||
| 1863 | case IR_KPRI: tr = TREF_PRI(irt_type(ir->t)); break; | 1863 | case IR_KPRI: tr = TREF_PRI(irt_type(ir->t)); break; |
| 1864 | case IR_KINT: tr = lj_ir_kint(J, ir->i); break; | 1864 | case IR_KINT: tr = lj_ir_kint(J, ir->i); break; |
| 1865 | case IR_KGC: tr = lj_ir_kgc(J, ir_kgc(ir), irt_t(ir->t)); break; | 1865 | case IR_KGC: tr = lj_ir_kgc(J, ir_kgc(ir), irt_t(ir->t)); break; |
| 1866 | case IR_KNUM: tr = lj_ir_knum_addr(J, ir_knum(ir)); break; | 1866 | case IR_KNUM: tr = lj_ir_k64(J, IR_KNUM, ir_knum(ir)); break; |
| 1867 | case IR_KINT64: tr = lj_ir_k64(J, IR_KINT64, ir_kint64(ir)); break; | ||
| 1867 | case IR_KPTR: tr = lj_ir_kptr(J, ir_kptr(ir)); break; /* Continuation. */ | 1868 | case IR_KPTR: tr = lj_ir_kptr(J, ir_kptr(ir)); break; /* Continuation. */ |
| 1868 | /* Inherited SLOADs don't need a guard or type check. */ | 1869 | /* Inherited SLOADs don't need a guard or type check. */ |
| 1869 | case IR_SLOAD: | 1870 | case IR_SLOAD: |
diff --git a/src/lj_trace.c b/src/lj_trace.c index 8589a9e9..b9439c9f 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c | |||
| @@ -306,7 +306,7 @@ void lj_trace_freestate(global_State *g) | |||
| 306 | } | 306 | } |
| 307 | #endif | 307 | #endif |
| 308 | lj_mcode_free(J); | 308 | lj_mcode_free(J); |
| 309 | lj_ir_knum_freeall(J); | 309 | lj_ir_k64_freeall(J); |
| 310 | lj_mem_freevec(g, J->snapmapbuf, J->sizesnapmap, SnapEntry); | 310 | lj_mem_freevec(g, J->snapmapbuf, J->sizesnapmap, SnapEntry); |
| 311 | lj_mem_freevec(g, J->snapbuf, J->sizesnap, SnapShot); | 311 | lj_mem_freevec(g, J->snapbuf, J->sizesnap, SnapShot); |
| 312 | lj_mem_freevec(g, J->irbuf + J->irbotlim, J->irtoplim - J->irbotlim, IRIns); | 312 | lj_mem_freevec(g, J->irbuf + J->irbotlim, J->irtoplim - J->irbotlim, IRIns); |
