diff options
Diffstat (limited to 'src/lj_crecord.c')
-rw-r--r-- | src/lj_crecord.c | 57 |
1 files changed, 38 insertions, 19 deletions
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) |