aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2011-01-17 01:23:04 +0100
committerMike Pall <mike>2011-01-17 01:23:04 +0100
commitf385af7084f300380167bf2261e8109927bd1e18 (patch)
tree13c2220d376ad767f73f18d23f06d1b4ae71a870
parent83d8c86bbb7b6123c88e1cc43f48a077e04b4b1a (diff)
downloadluajit-f385af7084f300380167bf2261e8109927bd1e18.tar.gz
luajit-f385af7084f300380167bf2261e8109927bd1e18.tar.bz2
luajit-f385af7084f300380167bf2261e8109927bd1e18.zip
FFI: Record 64 bit integer comparisons and pointer comparisons.
-rw-r--r--src/lib_ffi.c17
-rw-r--r--src/lj_asm.c2
-rw-r--r--src/lj_crecord.c57
-rw-r--r--src/lj_record.c1
4 files changed, 49 insertions, 28 deletions
diff --git a/src/lib_ffi.c b/src/lib_ffi.c
index 89baa356..42d71153 100644
--- a/src/lib_ffi.c
+++ b/src/lib_ffi.c
@@ -157,14 +157,13 @@ static int ffi_arith_ptr(lua_State *L, CTState *cts, FFIArith *fa, MMS mm)
157 return 1; 157 return 1;
158 } 158 }
159 } 159 }
160 if (!((mm == MM_add || mm == MM_sub) && 160 if (!((mm == MM_add || mm == MM_sub) && ctype_isnum(fa->ct[1]->info)))
161 ctype_isnum(fa->ct[1]->info))) return 0; 161 return 0;
162 lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT_PSZ), fa->ct[1], 162 lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT_PSZ), fa->ct[1],
163 (uint8_t *)&idx, fa->p[1], 0); 163 (uint8_t *)&idx, fa->p[1], 0);
164 if (mm == MM_sub) idx = -idx; 164 if (mm == MM_sub) idx = -idx;
165 } else if (mm == MM_add && 165 } else if (mm == MM_add && ctype_isnum(ctp->info) &&
166 (ctype_isptr(fa->ct[1]->info) || ctype_isrefarray(fa->ct[1]->info))) { 166 (ctype_isptr(fa->ct[1]->info) || ctype_isrefarray(fa->ct[1]->info))) {
167 if (!ctype_isnum(ctp->info)) return 0;
168 /* Swap pointer and index. */ 167 /* Swap pointer and index. */
169 ctp = fa->ct[1]; pp = fa->p[1]; 168 ctp = fa->ct[1]; pp = fa->p[1];
170 lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT_PSZ), fa->ct[0], 169 lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT_PSZ), fa->ct[0],
@@ -264,8 +263,10 @@ static int ffi_arith(lua_State *L)
264 FFIArith fa; 263 FFIArith fa;
265 MMS mm = (MMS)(curr_func(L)->c.ffid - (int)FF_ffi_meta___eq + (int)MM_eq); 264 MMS mm = (MMS)(curr_func(L)->c.ffid - (int)FF_ffi_meta___eq + (int)MM_eq);
266 if (ffi_checkarith(L, cts, &fa)) { 265 if (ffi_checkarith(L, cts, &fa)) {
267 if (ffi_arith_int64(L, cts, &fa, mm) || ffi_arith_ptr(L, cts, &fa, mm)) 266 if (ffi_arith_int64(L, cts, &fa, mm) || ffi_arith_ptr(L, cts, &fa, mm)) {
267 copyTV(L, &G(L)->tmptv2, L->top-1); /* Remember for trace recorder. */
268 return 1; 268 return 1;
269 }
269 } 270 }
270 /* NYI: per-cdata metamethods. */ 271 /* NYI: per-cdata metamethods. */
271 { 272 {
@@ -319,7 +320,7 @@ LJLIB_CF(ffi_meta___newindex) LJLIB_REC(cdata_index 1)
319} 320}
320 321
321/* The following functions must be in contiguous ORDER MM. */ 322/* The following functions must be in contiguous ORDER MM. */
322LJLIB_CF(ffi_meta___eq) 323LJLIB_CF(ffi_meta___eq) LJLIB_REC(cdata_arith MM_eq)
323{ 324{
324 return ffi_arith(L); 325 return ffi_arith(L);
325} 326}
@@ -329,12 +330,12 @@ LJLIB_CF(ffi_meta___len)
329 return ffi_arith(L); 330 return ffi_arith(L);
330} 331}
331 332
332LJLIB_CF(ffi_meta___lt) 333LJLIB_CF(ffi_meta___lt) LJLIB_REC(cdata_arith MM_lt)
333{ 334{
334 return ffi_arith(L); 335 return ffi_arith(L);
335} 336}
336 337
337LJLIB_CF(ffi_meta___le) 338LJLIB_CF(ffi_meta___le) LJLIB_REC(cdata_arith MM_le)
338{ 339{
339 return ffi_arith(L); 340 return ffi_arith(L);
340} 341}
diff --git a/src/lj_asm.c b/src/lj_asm.c
index af8ac51b..db126d74 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -2927,7 +2927,7 @@ static void asm_comp_(ASMState *as, IRIns *ir, int cc)
2927 IROp leftop = (IROp)(IR(lref)->o); 2927 IROp leftop = (IROp)(IR(lref)->o);
2928 Reg r64 = REX_64IR(ir, 0); 2928 Reg r64 = REX_64IR(ir, 0);
2929 int32_t imm = 0; 2929 int32_t imm = 0;
2930 lua_assert(irt_isint(ir->t) || irt_isaddr(ir->t)); 2930 lua_assert(irt_is64(ir->t) || irt_isint(ir->t) || irt_isaddr(ir->t));
2931 /* Swap constants (only for ABC) and fusable loads to the right. */ 2931 /* Swap constants (only for ABC) and fusable loads to the right. */
2932 if (irref_isk(lref) || (!irref_isk(rref) && opisfusableload(leftop))) { 2932 if (irref_isk(lref) || (!irref_isk(rref) && opisfusableload(leftop))) {
2933 if ((cc & 0xc) == 0xc) cc ^= 3; /* L <-> G, LE <-> GE */ 2933 if ((cc & 0xc) == 0xc) cc ^= 3; /* L <-> G, LE <-> GE */
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index e2b3e8af..c6577975 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -663,7 +663,20 @@ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm)
663 sp[i] = emitconv(sp[i], dt, IRT_INT, 663 sp[i] = emitconv(sp[i], dt, IRT_INT,
664 ((st - IRT_I8) & 1) ? 0 : IRCONV_SEXT); 664 ((st - IRT_I8) & 1) ? 0 : IRCONV_SEXT);
665 } 665 }
666 if (mm == MM_pow) { 666 if (mm < MM_add) {
667 /* Assume true comparison. Fixup and emit pending guard later. */
668 IROp op;
669 if (mm == MM_eq) {
670 op = IR_EQ;
671 } else {
672 op = mm == MM_lt ? IR_LT : IR_LE;
673 if (dt == IRT_U64)
674 op += (IR_ULT-IR_LT);
675 }
676 lj_ir_set(J, IRTG(op, dt), sp[0], sp[1]);
677 J->postproc = LJ_POST_FIXGUARD;
678 return TREF_TRUE;
679 } else if (mm == MM_pow) {
667 tr = lj_ir_call(J, IRCALL_lj_cdata_powi64, sp[0], sp[1], 680 tr = lj_ir_call(J, IRCALL_lj_cdata_powi64, sp[0], sp[1],
668 lj_ir_kint(J, (int)dt-(int)IRT_I64)); 681 lj_ir_kint(J, (int)dt-(int)IRT_I64));
669 } else { 682 } else {
@@ -683,35 +696,41 @@ static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm)
683{ 696{
684 CTState *cts = ctype_ctsG(J2G(J)); 697 CTState *cts = ctype_ctsG(J2G(J));
685 CType *ctp = s[0]; 698 CType *ctp = s[0];
686 CTSize sz; 699 if (ctype_isptr(ctp->info) || ctype_isrefarray(ctp->info)) {
687 if (!(mm == MM_add || mm == MM_sub)) 700 if ((mm == MM_sub || mm == MM_eq || mm == MM_lt || mm == MM_le) &&
688 return 0; 701 (ctype_isptr(s[1]->info) || ctype_isrefarray(s[1]->info))) {
689 if (ctype_ispointer(ctp->info)) { 702 if (mm == MM_sub) { /* Pointer difference. */
690 sz = lj_ctype_size(cts, ctype_cid(ctp->info)); 703 TRef tr;
691 if (mm == MM_sub && ctype_ispointer(s[1]->info)) { 704 CTSize sz = lj_ctype_size(cts, ctype_cid(ctp->info));
692 /* Pointer difference. */ 705 if (sz == 0 || (sz & (sz-1)) != 0)
693 TRef tr; 706 return 0; /* NYI: integer division. */
694 if (sz == 0 || (sz & (sz-1)) != 0) 707 tr = emitir(IRT(IR_SUB, IRT_PTR), sp[0], sp[1]);
695 return 0; /* NYI: integer division. */ 708 tr = emitir(IRT(IR_BSAR, IRT_INTP), tr, lj_ir_kint(J, lj_fls(sz)));
696 tr = emitir(IRT(IR_SUB, IRT_PTR), sp[0], sp[1]);
697 tr = emitir(IRT(IR_BSAR, IRT_INTP), tr, lj_ir_kint(J, lj_fls(sz)));
698#if LJ_64 709#if LJ_64
699 tr = emitconv(tr, IRT_NUM, IRT_INTP, 0); 710 tr = emitconv(tr, IRT_NUM, IRT_INTP, 0);
700#endif 711#endif
701 return tr; 712 return tr;
713 } else { /* Pointer comparison (unsigned). */
714 /* Assume true comparison. Fixup and emit pending guard later. */
715 IROp op = mm == MM_eq ? IR_EQ : mm == MM_lt ? IR_ULT : IR_ULE;
716 lj_ir_set(J, IRTG(op, IRT_PTR), sp[0], sp[1]);
717 J->postproc = LJ_POST_FIXGUARD;
718 return TREF_TRUE;
719 }
702 } 720 }
703 if (!ctype_isnum(s[1]->info)) return 0; 721 if (!((mm == MM_add || mm == MM_sub) && ctype_isnum(s[1]->info)))
704 } else if (mm == MM_add && 722 return 0;
705 ctype_isnum(ctp->info) && ctype_ispointer(s[1]->info)) { 723 } else if (mm == MM_add && ctype_isnum(ctp->info) &&
724 (ctype_isptr(s[1]->info) || ctype_isrefarray(s[1]->info))) {
706 TRef tr = sp[0]; sp[0] = sp[1]; sp[1] = tr; /* Swap pointer and index. */ 725 TRef tr = sp[0]; sp[0] = sp[1]; sp[1] = tr; /* Swap pointer and index. */
707 ctp = s[1]; 726 ctp = s[1];
708 sz = lj_ctype_size(cts, ctype_cid(ctp->info));
709 } else { 727 } else {
710 return 0; 728 return 0;
711 } 729 }
712 { 730 {
713 TRef tr = sp[1]; 731 TRef tr = sp[1];
714 IRType t = tref_type(tr); 732 IRType t = tref_type(tr);
733 CTSize sz = lj_ctype_size(cts, ctype_cid(ctp->info));
715 CTypeID id; 734 CTypeID id;
716#if LJ_64 735#if LJ_64
717 if (t == IRT_NUM || t == IRT_FLOAT) 736 if (t == IRT_NUM || t == IRT_FLOAT)
diff --git a/src/lj_record.c b/src/lj_record.c
index 1669fde1..c150e2e4 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -819,6 +819,7 @@ static void rec_mm_comp(jit_State *J, RecordIndex *ix, int op)
819/* Setup call to cdata comparison metamethod. */ 819/* Setup call to cdata comparison metamethod. */
820static void rec_mm_comp_cdata(jit_State *J, RecordIndex *ix, int op, MMS mm) 820static void rec_mm_comp_cdata(jit_State *J, RecordIndex *ix, int op, MMS mm)
821{ 821{
822 lj_snap_add(J);
822 if (tref_iscdata(ix->val)) { 823 if (tref_iscdata(ix->val)) {
823 ix->tab = ix->val; 824 ix->tab = ix->val;
824 copyTV(J->L, &ix->tabv, &ix->valv); 825 copyTV(J->L, &ix->tabv, &ix->valv);