aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-12-05 19:49:29 +0100
committerMike Pall <mike>2010-12-05 21:01:08 +0100
commitb1fb71fb981c464868e6bc669363658a98ecbd9e (patch)
tree88fe921691d957a40c10181c8f13de201a924d31 /src
parent6a7605ec85a6e5f91fc539a9e5c18659d73f3530 (diff)
downloadluajit-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.c44
-rw-r--r--src/lj_def.h1
-rw-r--r--src/lj_ir.h21
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. */
669static void ra_movrr(ASMState *as, IRIns *ir, Reg r1, Reg r2) 669static 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
378static LJ_AINLINE IRType itype2irt(const TValue *tv) 387static 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