diff options
| author | Mike Pall <mike> | 2011-01-17 01:23:04 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2011-01-17 01:23:04 +0100 |
| commit | f385af7084f300380167bf2261e8109927bd1e18 (patch) | |
| tree | 13c2220d376ad767f73f18d23f06d1b4ae71a870 | |
| parent | 83d8c86bbb7b6123c88e1cc43f48a077e04b4b1a (diff) | |
| download | luajit-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.c | 17 | ||||
| -rw-r--r-- | src/lj_asm.c | 2 | ||||
| -rw-r--r-- | src/lj_crecord.c | 57 | ||||
| -rw-r--r-- | src/lj_record.c | 1 |
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. */ |
| 322 | LJLIB_CF(ffi_meta___eq) | 323 | LJLIB_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 | ||
| 332 | LJLIB_CF(ffi_meta___lt) | 333 | LJLIB_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 | ||
| 337 | LJLIB_CF(ffi_meta___le) | 338 | LJLIB_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. */ |
| 820 | static void rec_mm_comp_cdata(jit_State *J, RecordIndex *ix, int op, MMS mm) | 820 | static 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); |
