diff options
author | Mike Pall <mike> | 2010-12-05 19:49:29 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2010-12-05 21:01:08 +0100 |
commit | b1fb71fb981c464868e6bc669363658a98ecbd9e (patch) | |
tree | 88fe921691d957a40c10181c8f13de201a924d31 /src | |
parent | 6a7605ec85a6e5f91fc539a9e5c18659d73f3530 (diff) | |
download | luajit-b1fb71fb981c464868e6bc669363658a98ecbd9e.tar.gz luajit-b1fb71fb981c464868e6bc669363658a98ecbd9e.tar.bz2 luajit-b1fb71fb981c464868e6bc669363658a98ecbd9e.zip |
Cleanup 64 bit IR type handling.
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_asm.c | 44 | ||||
-rw-r--r-- | src/lj_def.h | 1 | ||||
-rw-r--r-- | src/lj_ir.h | 21 |
3 files changed, 39 insertions, 27 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index 0dfc7f04..6bb2b8c6 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -631,7 +631,7 @@ static int32_t ra_spill(ASMState *as, IRIns *ir) | |||
631 | { | 631 | { |
632 | int32_t slot = ir->s; | 632 | int32_t slot = ir->s; |
633 | if (!ra_hasspill(slot)) { | 633 | if (!ra_hasspill(slot)) { |
634 | if (irt_isnum(ir->t) || (LJ_64 && irt_islightud(ir->t))) { | 634 | if (irt_is64(ir->t)) { |
635 | slot = as->evenspill; | 635 | slot = as->evenspill; |
636 | as->evenspill += 2; | 636 | as->evenspill += 2; |
637 | } else if (as->oddspill) { | 637 | } else if (as->oddspill) { |
@@ -661,14 +661,14 @@ static Reg ra_releasetmp(ASMState *as, IRRef ref) | |||
661 | return r; | 661 | return r; |
662 | } | 662 | } |
663 | 663 | ||
664 | /* Use 64 bit operations to handle 64 bit lightuserdata. */ | 664 | /* Use 64 bit operations to handle 64 bit IR types. */ |
665 | #define REX_64LU(ir, r) \ | 665 | #define REX_64IR(ir, r) \ |
666 | ((r) | ((LJ_64 && irt_islightud((ir)->t)) ? REX_64 : 0)) | 666 | ((r) | ((LJ_64 && irt_is64((ir)->t)) ? REX_64 : 0)) |
667 | 667 | ||
668 | /* Generic move between two regs. */ | 668 | /* Generic move between two regs. */ |
669 | static void ra_movrr(ASMState *as, IRIns *ir, Reg r1, Reg r2) | 669 | static void ra_movrr(ASMState *as, IRIns *ir, Reg r1, Reg r2) |
670 | { | 670 | { |
671 | emit_rr(as, r1 < RID_MAX_GPR ? XO_MOV : XMM_MOVRR(as), REX_64LU(ir, r1), r2); | 671 | emit_rr(as, r1 < RID_MAX_GPR ? XO_MOV : XMM_MOVRR(as), REX_64IR(ir, r1), r2); |
672 | } | 672 | } |
673 | 673 | ||
674 | /* Restore a register (marked as free). Rematerialize or force a spill. */ | 674 | /* Restore a register (marked as free). Rematerialize or force a spill. */ |
@@ -687,7 +687,7 @@ static Reg ra_restore(ASMState *as, IRRef ref) | |||
687 | ra_modified(as, r); | 687 | ra_modified(as, r); |
688 | RA_DBGX((as, "restore $i $r", ir, r)); | 688 | RA_DBGX((as, "restore $i $r", ir, r)); |
689 | emit_rmro(as, r < RID_MAX_GPR ? XO_MOV : XMM_MOVRM(as), | 689 | emit_rmro(as, r < RID_MAX_GPR ? XO_MOV : XMM_MOVRM(as), |
690 | REX_64LU(ir, r), RID_ESP, ofs); | 690 | REX_64IR(ir, r), RID_ESP, ofs); |
691 | } | 691 | } |
692 | return r; | 692 | return r; |
693 | } | 693 | } |
@@ -698,7 +698,7 @@ static void ra_save(ASMState *as, IRIns *ir, Reg r) | |||
698 | { | 698 | { |
699 | RA_DBGX((as, "save $i $r", ir, r)); | 699 | RA_DBGX((as, "save $i $r", ir, r)); |
700 | emit_rmro(as, r < RID_MAX_GPR ? XO_MOVto : XO_MOVSDto, | 700 | emit_rmro(as, r < RID_MAX_GPR ? XO_MOVto : XO_MOVSDto, |
701 | REX_64LU(ir, r), RID_ESP, sps_scale(ir->s)); | 701 | REX_64IR(ir, r), RID_ESP, sps_scale(ir->s)); |
702 | } | 702 | } |
703 | 703 | ||
704 | #define MINCOST(r) \ | 704 | #define MINCOST(r) \ |
@@ -1397,7 +1397,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) | |||
1397 | lj_trace_err(as->J, LJ_TRERR_NYICOAL); | 1397 | lj_trace_err(as->J, LJ_TRERR_NYICOAL); |
1398 | r = ra_alloc1(as, args[n], allow & RSET_GPR); | 1398 | r = ra_alloc1(as, args[n], allow & RSET_GPR); |
1399 | allow &= ~RID2RSET(r); | 1399 | allow &= ~RID2RSET(r); |
1400 | emit_movtomro(as, REX_64LU(ir, r), RID_ESP, ofs); | 1400 | emit_movtomro(as, REX_64IR(ir, r), RID_ESP, ofs); |
1401 | } | 1401 | } |
1402 | ofs += sizeof(intptr_t); | 1402 | ofs += sizeof(intptr_t); |
1403 | } | 1403 | } |
@@ -1849,7 +1849,7 @@ static void asm_newref(ASMState *as, IRIns *ir) | |||
1849 | /* Otherwise use g->tmptv to hold the TValue. */ | 1849 | /* Otherwise use g->tmptv to hold the TValue. */ |
1850 | if (!irref_isk(ir->op2)) { | 1850 | if (!irref_isk(ir->op2)) { |
1851 | Reg src = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, tmp)); | 1851 | Reg src = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, tmp)); |
1852 | emit_movtomro(as, REX_64LU(irkey, src), tmp, 0); | 1852 | emit_movtomro(as, REX_64IR(irkey, src), tmp, 0); |
1853 | } else if (!irt_ispri(irkey->t)) { | 1853 | } else if (!irt_ispri(irkey->t)) { |
1854 | emit_movmroi(as, tmp, 0, irkey->i); | 1854 | emit_movmroi(as, tmp, 0, irkey->i); |
1855 | } | 1855 | } |
@@ -1918,13 +1918,11 @@ static void asm_fxload(ASMState *as, IRIns *ir) | |||
1918 | case IRT_U8: xo = XO_MOVZXb; break; | 1918 | case IRT_U8: xo = XO_MOVZXb; break; |
1919 | case IRT_I16: xo = XO_MOVSXw; break; | 1919 | case IRT_I16: xo = XO_MOVSXw; break; |
1920 | case IRT_U16: xo = XO_MOVZXw; break; | 1920 | case IRT_U16: xo = XO_MOVZXw; break; |
1921 | #if LJ_64 | ||
1922 | case IRT_LIGHTUD: | ||
1923 | dest |= REX_64; | ||
1924 | /* fallthrough */ | ||
1925 | #endif | ||
1926 | default: | 1921 | default: |
1927 | lua_assert(irt_isint(ir->t) || irt_isaddr(ir->t)); | 1922 | if (LJ_64 && irt_is64(ir->t)) |
1923 | dest |= REX_64; | ||
1924 | else | ||
1925 | lua_assert(irt_isint(ir->t) || irt_isu32(ir->t) || irt_isaddr(ir->t)); | ||
1928 | xo = XO_MOV; | 1926 | xo = XO_MOV; |
1929 | break; | 1927 | break; |
1930 | } | 1928 | } |
@@ -1938,6 +1936,7 @@ static void asm_fstore(ASMState *as, IRIns *ir) | |||
1938 | /* The IRT_I16/IRT_U16 stores should never be simplified for constant | 1936 | /* The IRT_I16/IRT_U16 stores should never be simplified for constant |
1939 | ** values since mov word [mem], imm16 has a length-changing prefix. | 1937 | ** values since mov word [mem], imm16 has a length-changing prefix. |
1940 | */ | 1938 | */ |
1939 | lua_assert(!(irref_isk(ir->op2) && irt_is64(ir->t))); /* NYI: KINT64. */ | ||
1941 | 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)) { |
1942 | RegSet allow8 = (irt_isi8(ir->t) || irt_isu8(ir->t)) ? RSET_GPR8 : RSET_GPR; | 1941 | RegSet allow8 = (irt_isi8(ir->t) || irt_isu8(ir->t)) ? RSET_GPR8 : RSET_GPR; |
1943 | src = ra_alloc1(as, ir->op2, allow8); | 1942 | src = ra_alloc1(as, ir->op2, allow8); |
@@ -1953,7 +1952,10 @@ static void asm_fstore(ASMState *as, IRIns *ir) | |||
1953 | case IRT_LIGHTUD: lua_assert(0); /* NYI: mask 64 bit lightuserdata. */ | 1952 | case IRT_LIGHTUD: lua_assert(0); /* NYI: mask 64 bit lightuserdata. */ |
1954 | #endif | 1953 | #endif |
1955 | default: | 1954 | default: |
1956 | lua_assert(irt_isint(ir->t) || irt_isaddr(ir->t)); | 1955 | if (LJ_64 && irt_is64(ir->t)) |
1956 | src |= REX_64; | ||
1957 | else | ||
1958 | lua_assert(irt_isint(ir->t) || irt_isu32(ir->t) || irt_isaddr(ir->t)); | ||
1957 | xo = XO_MOVto; | 1959 | xo = XO_MOVto; |
1958 | break; | 1960 | break; |
1959 | } | 1961 | } |
@@ -1963,7 +1965,7 @@ static void asm_fstore(ASMState *as, IRIns *ir) | |||
1963 | emit_i8(as, IR(ir->op2)->i); | 1965 | emit_i8(as, IR(ir->op2)->i); |
1964 | emit_mrm(as, XO_MOVmib, 0, RID_MRM); | 1966 | emit_mrm(as, XO_MOVmib, 0, RID_MRM); |
1965 | } else { | 1967 | } else { |
1966 | lua_assert(irt_isint(ir->t) || irt_isaddr(ir->t)); | 1968 | lua_assert(irt_isint(ir->t) || irt_isu32(ir->t) || irt_isaddr(ir->t)); |
1967 | emit_i32(as, IR(ir->op2)->i); | 1969 | emit_i32(as, IR(ir->op2)->i); |
1968 | emit_mrm(as, XO_MOVmi, 0, RID_MRM); | 1970 | emit_mrm(as, XO_MOVmi, 0, RID_MRM); |
1969 | } | 1971 | } |
@@ -2664,7 +2666,7 @@ static void asm_comp_(ASMState *as, IRIns *ir, int cc) | |||
2664 | asm_guardcc(as, cc); | 2666 | asm_guardcc(as, cc); |
2665 | if (usetest && left != RID_MRM) { | 2667 | if (usetest && left != RID_MRM) { |
2666 | /* Use test r,r instead of cmp r,0. */ | 2668 | /* Use test r,r instead of cmp r,0. */ |
2667 | emit_rr(as, XO_TEST, REX_64LU(ir, left), left); | 2669 | emit_rr(as, XO_TEST, REX_64IR(ir, left), left); |
2668 | if (irl+1 == ir) /* Referencing previous ins? */ | 2670 | if (irl+1 == ir) /* Referencing previous ins? */ |
2669 | as->testmcp = as->mcp; /* Set flag to drop test r,r if possible. */ | 2671 | as->testmcp = as->mcp; /* Set flag to drop test r,r if possible. */ |
2670 | } else { | 2672 | } else { |
@@ -2683,7 +2685,7 @@ static void asm_comp_(ASMState *as, IRIns *ir, int cc) | |||
2683 | Reg left = ra_alloc1(as, lref, RSET_GPR); | 2685 | Reg left = ra_alloc1(as, lref, RSET_GPR); |
2684 | Reg right = asm_fuseload(as, rref, rset_exclude(RSET_GPR, left)); | 2686 | Reg right = asm_fuseload(as, rref, rset_exclude(RSET_GPR, left)); |
2685 | asm_guardcc(as, cc); | 2687 | asm_guardcc(as, cc); |
2686 | emit_mrm(as, XO_CMP, REX_64LU(ir, left), right); | 2688 | emit_mrm(as, XO_CMP, REX_64IR(ir, left), right); |
2687 | } | 2689 | } |
2688 | } | 2690 | } |
2689 | } | 2691 | } |
@@ -2762,7 +2764,7 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap) | |||
2762 | lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t)); | 2764 | lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t)); |
2763 | if (!irref_isk(ref)) { | 2765 | if (!irref_isk(ref)) { |
2764 | Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, RID_BASE)); | 2766 | Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, RID_BASE)); |
2765 | emit_movtomro(as, REX_64LU(ir, src), RID_BASE, ofs); | 2767 | emit_movtomro(as, REX_64IR(ir, src), RID_BASE, ofs); |
2766 | } else if (!irt_ispri(ir->t)) { | 2768 | } else if (!irt_ispri(ir->t)) { |
2767 | emit_movmroi(as, RID_BASE, ofs, ir->i); | 2769 | emit_movmroi(as, RID_BASE, ofs, ir->i); |
2768 | } | 2770 | } |
@@ -3189,7 +3191,7 @@ static void asm_head_side(ASMState *as) | |||
3189 | int32_t ofs = sps_scale(regsp_spill(rs)); | 3191 | int32_t ofs = sps_scale(regsp_spill(rs)); |
3190 | ra_free(as, r); | 3192 | ra_free(as, r); |
3191 | emit_rmro(as, r < RID_MAX_GPR ? XO_MOV : XMM_MOVRM(as), | 3193 | emit_rmro(as, r < RID_MAX_GPR ? XO_MOV : XMM_MOVRM(as), |
3192 | REX_64LU(ir, r), RID_ESP, ofs); | 3194 | REX_64IR(ir, r), RID_ESP, ofs); |
3193 | checkmclim(as); | 3195 | checkmclim(as); |
3194 | } | 3196 | } |
3195 | } | 3197 | } |
diff --git a/src/lj_def.h b/src/lj_def.h index bc3ae937..074090af 100644 --- a/src/lj_def.h +++ b/src/lj_def.h | |||
@@ -89,6 +89,7 @@ typedef unsigned __int32 uintptr_t; | |||
89 | #define checku8(x) ((x) == (int32_t)(uint8_t)(x)) | 89 | #define checku8(x) ((x) == (int32_t)(uint8_t)(x)) |
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 checkptr32(x) ((uintptr_t)(x) == (uint32_t)(uintptr_t)(x)) | 93 | #define checkptr32(x) ((uintptr_t)(x) == (uint32_t)(uintptr_t)(x)) |
93 | 94 | ||
94 | /* Every half-decent C compiler transforms this into a rotate instruction. */ | 95 | /* Every half-decent C compiler transforms this into a rotate instruction. */ |
diff --git a/src/lj_ir.h b/src/lj_ir.h index 123d87c8..9d90d69f 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h | |||
@@ -315,7 +315,7 @@ typedef enum { | |||
315 | IRT_THREAD, | 315 | IRT_THREAD, |
316 | IRT_PROTO, | 316 | IRT_PROTO, |
317 | IRT_FUNC, | 317 | IRT_FUNC, |
318 | IRT_9, /* Unused (map of LJ_TTRACE). */ | 318 | IRT_P64, /* IRT_P64 never escapes the IR (map of LJ_TTRACE). */ |
319 | IRT_CDATA, | 319 | IRT_CDATA, |
320 | IRT_TAB, | 320 | IRT_TAB, |
321 | IRT_UDATA, | 321 | IRT_UDATA, |
@@ -325,12 +325,15 @@ typedef enum { | |||
325 | ** a TValue after implicit or explicit conversion (TONUM). Their types | 325 | ** a TValue after implicit or explicit conversion (TONUM). Their types |
326 | ** must be contiguous and next to IRT_NUM (see the typerange macros below). | 326 | ** must be contiguous and next to IRT_NUM (see the typerange macros below). |
327 | */ | 327 | */ |
328 | IRT_INT, | ||
329 | IRT_I8, | 328 | IRT_I8, |
330 | IRT_U8, | 329 | IRT_U8, |
331 | IRT_I16, | 330 | IRT_I16, |
332 | IRT_U16, | 331 | IRT_U16, |
333 | /* There is room for 13 more types. */ | 332 | IRT_INT, |
333 | IRT_U32, | ||
334 | IRT_I64, | ||
335 | IRT_U64, | ||
336 | /* There is room for 10 more types. */ | ||
334 | 337 | ||
335 | /* Additional flags. */ | 338 | /* Additional flags. */ |
336 | IRT_MARK = 0x20, /* Marker for misc. purposes. */ | 339 | IRT_MARK = 0x20, /* Marker for misc. purposes. */ |
@@ -370,11 +373,17 @@ typedef struct IRType1 { uint8_t irt; } IRType1; | |||
370 | #define irt_isu8(t) (irt_type(t) == IRT_U8) | 373 | #define irt_isu8(t) (irt_type(t) == IRT_U8) |
371 | #define irt_isi16(t) (irt_type(t) == IRT_I16) | 374 | #define irt_isi16(t) (irt_type(t) == IRT_I16) |
372 | #define irt_isu16(t) (irt_type(t) == IRT_U16) | 375 | #define irt_isu16(t) (irt_type(t) == IRT_U16) |
376 | #define irt_isu32(t) (irt_type(t) == IRT_U32) | ||
373 | 377 | ||
374 | #define irt_isinteger(t) (irt_typerange((t), IRT_INT, IRT_U16)) | 378 | #define irt_isinteger(t) (irt_typerange((t), IRT_I8, IRT_INT)) |
375 | #define irt_isgcv(t) (irt_typerange((t), IRT_STR, IRT_UDATA)) | 379 | #define irt_isgcv(t) (irt_typerange((t), IRT_STR, IRT_UDATA)) |
376 | #define irt_isaddr(t) (irt_typerange((t), IRT_LIGHTUD, IRT_UDATA)) | 380 | #define irt_isaddr(t) (irt_typerange((t), IRT_LIGHTUD, IRT_UDATA)) |
377 | 381 | ||
382 | #define IRT_IS64 \ | ||
383 | ((1u<<IRT_NUM) | (1u<<IRT_I64) | (1u<<IRT_U64) | (1u<<IRT_P64) | \ | ||
384 | (LJ_64 ? (1u<<IRT_LIGHTUD) : 0)) | ||
385 | #define irt_is64(t) ((IRT_IS64 >> irt_type(t)) & 1) | ||
386 | |||
378 | static LJ_AINLINE IRType itype2irt(const TValue *tv) | 387 | static LJ_AINLINE IRType itype2irt(const TValue *tv) |
379 | { | 388 | { |
380 | if (tvisnum(tv)) | 389 | if (tvisnum(tv)) |
@@ -469,8 +478,8 @@ typedef uint32_t TRef; | |||
469 | #define tref_isbool(tr) (tref_typerange((tr), IRT_FALSE, IRT_TRUE)) | 478 | #define tref_isbool(tr) (tref_typerange((tr), IRT_FALSE, IRT_TRUE)) |
470 | #define tref_ispri(tr) (tref_typerange((tr), IRT_NIL, IRT_TRUE)) | 479 | #define tref_ispri(tr) (tref_typerange((tr), IRT_NIL, IRT_TRUE)) |
471 | #define tref_istruecond(tr) (!tref_typerange((tr), IRT_NIL, IRT_FALSE)) | 480 | #define tref_istruecond(tr) (!tref_typerange((tr), IRT_NIL, IRT_FALSE)) |
472 | #define tref_isinteger(tr) (tref_typerange((tr), IRT_INT, IRT_U16)) | 481 | #define tref_isinteger(tr) (tref_typerange((tr), IRT_I8, IRT_INT)) |
473 | #define tref_isnumber(tr) (tref_typerange((tr), IRT_NUM, IRT_U16)) | 482 | #define tref_isnumber(tr) (tref_typerange((tr), IRT_NUM, IRT_INT)) |
474 | #define tref_isnumber_str(tr) (tref_isnumber((tr)) || tref_isstr((tr))) | 483 | #define tref_isnumber_str(tr) (tref_isnumber((tr)) || tref_isstr((tr))) |
475 | #define tref_isgcv(tr) (tref_typerange((tr), IRT_STR, IRT_UDATA)) | 484 | #define tref_isgcv(tr) (tref_typerange((tr), IRT_STR, IRT_UDATA)) |
476 | 485 | ||