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); |