diff options
Diffstat (limited to 'src/lj_crecord.c')
-rw-r--r-- | src/lj_crecord.c | 106 |
1 files changed, 100 insertions, 6 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index b60eb7b3..2bf0bc1d 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -446,7 +446,7 @@ static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp, | |||
446 | /* fallthrough */ | 446 | /* fallthrough */ |
447 | case CCX(I, F): | 447 | case CCX(I, F): |
448 | if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi; | 448 | if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi; |
449 | sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, st, IRCONV_TRUNC|IRCONV_ANY); | 449 | sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, st, IRCONV_ANY); |
450 | goto xstore; | 450 | goto xstore; |
451 | case CCX(I, P): | 451 | case CCX(I, P): |
452 | case CCX(I, A): | 452 | case CCX(I, A): |
@@ -522,7 +522,7 @@ static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp, | |||
522 | if (st == IRT_CDATA) goto err_nyi; | 522 | if (st == IRT_CDATA) goto err_nyi; |
523 | /* The signed conversion is cheaper. x64 really has 47 bit pointers. */ | 523 | /* The signed conversion is cheaper. x64 really has 47 bit pointers. */ |
524 | sp = emitconv(sp, (LJ_64 && dsize == 8) ? IRT_I64 : IRT_U32, | 524 | sp = emitconv(sp, (LJ_64 && dsize == 8) ? IRT_I64 : IRT_U32, |
525 | st, IRCONV_TRUNC|IRCONV_ANY); | 525 | st, IRCONV_ANY); |
526 | goto xstore; | 526 | goto xstore; |
527 | 527 | ||
528 | /* Destination is an array. */ | 528 | /* Destination is an array. */ |
@@ -1229,7 +1229,7 @@ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm) | |||
1229 | for (i = 0; i < 2; i++) { | 1229 | for (i = 0; i < 2; i++) { |
1230 | IRType st = tref_type(sp[i]); | 1230 | IRType st = tref_type(sp[i]); |
1231 | if (st == IRT_NUM || st == IRT_FLOAT) | 1231 | if (st == IRT_NUM || st == IRT_FLOAT) |
1232 | sp[i] = emitconv(sp[i], dt, st, IRCONV_TRUNC|IRCONV_ANY); | 1232 | sp[i] = emitconv(sp[i], dt, st, IRCONV_ANY); |
1233 | else if (!(st == IRT_I64 || st == IRT_U64)) | 1233 | else if (!(st == IRT_I64 || st == IRT_U64)) |
1234 | sp[i] = emitconv(sp[i], dt, IRT_INT, | 1234 | sp[i] = emitconv(sp[i], dt, IRT_INT, |
1235 | (s[i]->info & CTF_UNSIGNED) ? 0 : IRCONV_SEXT); | 1235 | (s[i]->info & CTF_UNSIGNED) ? 0 : IRCONV_SEXT); |
@@ -1297,15 +1297,14 @@ static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm) | |||
1297 | CTypeID id; | 1297 | CTypeID id; |
1298 | #if LJ_64 | 1298 | #if LJ_64 |
1299 | if (t == IRT_NUM || t == IRT_FLOAT) | 1299 | if (t == IRT_NUM || t == IRT_FLOAT) |
1300 | tr = emitconv(tr, IRT_INTP, t, IRCONV_TRUNC|IRCONV_ANY); | 1300 | tr = emitconv(tr, IRT_INTP, t, IRCONV_ANY); |
1301 | else if (!(t == IRT_I64 || t == IRT_U64)) | 1301 | else if (!(t == IRT_I64 || t == IRT_U64)) |
1302 | tr = emitconv(tr, IRT_INTP, IRT_INT, | 1302 | tr = emitconv(tr, IRT_INTP, IRT_INT, |
1303 | ((t - IRT_I8) & 1) ? 0 : IRCONV_SEXT); | 1303 | ((t - IRT_I8) & 1) ? 0 : IRCONV_SEXT); |
1304 | #else | 1304 | #else |
1305 | if (!tref_typerange(sp[1], IRT_I8, IRT_U32)) { | 1305 | if (!tref_typerange(sp[1], IRT_I8, IRT_U32)) { |
1306 | tr = emitconv(tr, IRT_INTP, t, | 1306 | tr = emitconv(tr, IRT_INTP, t, |
1307 | (t == IRT_NUM || t == IRT_FLOAT) ? | 1307 | (t == IRT_NUM || t == IRT_FLOAT) ? IRCONV_ANY : 0); |
1308 | IRCONV_TRUNC|IRCONV_ANY : 0); | ||
1309 | } | 1308 | } |
1310 | #endif | 1309 | #endif |
1311 | tr = emitir(IRT(IR_MUL, IRT_INTP), tr, lj_ir_kintp(J, sz)); | 1310 | tr = emitir(IRT(IR_MUL, IRT_INTP), tr, lj_ir_kintp(J, sz)); |
@@ -1627,6 +1626,101 @@ void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd) | |||
1627 | crec_finalizer(J, J->base[0], &rd->argv[1]); | 1626 | crec_finalizer(J, J->base[0], &rd->argv[1]); |
1628 | } | 1627 | } |
1629 | 1628 | ||
1629 | /* -- 64 bit bit.* library functions -------------------------------------- */ | ||
1630 | |||
1631 | /* Determine bit operation type from argument type. */ | ||
1632 | static CTypeID crec_bit64_type(CTState *cts, cTValue *tv) | ||
1633 | { | ||
1634 | if (tviscdata(tv)) { | ||
1635 | CType *ct = lj_ctype_rawref(cts, cdataV(tv)->ctypeid); | ||
1636 | if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct); | ||
1637 | if ((ct->info & (CTMASK_NUM|CTF_BOOL|CTF_FP|CTF_UNSIGNED)) == | ||
1638 | CTINFO(CT_NUM, CTF_UNSIGNED) && ct->size == 8) | ||
1639 | return CTID_UINT64; /* Use uint64_t, since it has the highest rank. */ | ||
1640 | return CTID_INT64; /* Otherwise use int64_t. */ | ||
1641 | } | ||
1642 | return 0; /* Use regular 32 bit ops. */ | ||
1643 | } | ||
1644 | |||
1645 | void LJ_FASTCALL recff_bit64_tobit(jit_State *J, RecordFFData *rd) | ||
1646 | { | ||
1647 | CTState *cts = ctype_ctsG(J2G(J)); | ||
1648 | TRef tr = crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0, | ||
1649 | J->base[0], &rd->argv[0]); | ||
1650 | if (!tref_isinteger(tr)) | ||
1651 | tr = emitconv(tr, IRT_INT, tref_type(tr), 0); | ||
1652 | J->base[0] = tr; | ||
1653 | } | ||
1654 | |||
1655 | int LJ_FASTCALL recff_bit64_unary(jit_State *J, RecordFFData *rd) | ||
1656 | { | ||
1657 | CTState *cts = ctype_ctsG(J2G(J)); | ||
1658 | CTypeID id = crec_bit64_type(cts, &rd->argv[0]); | ||
1659 | if (id) { | ||
1660 | TRef tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]); | ||
1661 | tr = emitir(IRT(rd->data, id-CTID_INT64+IRT_I64), tr, 0); | ||
1662 | J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr); | ||
1663 | return 1; | ||
1664 | } | ||
1665 | return 0; | ||
1666 | } | ||
1667 | |||
1668 | int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd) | ||
1669 | { | ||
1670 | CTState *cts = ctype_ctsG(J2G(J)); | ||
1671 | CTypeID id = 0; | ||
1672 | MSize i; | ||
1673 | for (i = 0; J->base[i] != 0; i++) { | ||
1674 | CTypeID aid = crec_bit64_type(cts, &rd->argv[i]); | ||
1675 | if (id < aid) id = aid; /* Determine highest type rank of all arguments. */ | ||
1676 | } | ||
1677 | if (id) { | ||
1678 | CType *ct = ctype_get(cts, id); | ||
1679 | uint32_t ot = IRT(rd->data, id-CTID_INT64+IRT_I64); | ||
1680 | TRef tr = crec_ct_tv(J, ct, 0, J->base[0], &rd->argv[0]); | ||
1681 | for (i = 1; J->base[i] != 0; i++) { | ||
1682 | TRef tr2 = crec_ct_tv(J, ct, 0, J->base[i], &rd->argv[i]); | ||
1683 | tr = emitir(ot, tr, tr2); | ||
1684 | } | ||
1685 | J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr); | ||
1686 | return 1; | ||
1687 | } | ||
1688 | return 0; | ||
1689 | } | ||
1690 | |||
1691 | int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd) | ||
1692 | { | ||
1693 | CTState *cts = ctype_ctsG(J2G(J)); | ||
1694 | CTypeID id; | ||
1695 | TRef tsh = 0; | ||
1696 | if (J->base[0] && tref_iscdata(J->base[1])) { | ||
1697 | tsh = crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0, | ||
1698 | J->base[1], &rd->argv[1]); | ||
1699 | if (!tref_isinteger(tsh)) | ||
1700 | tsh = emitconv(tsh, IRT_INT, tref_type(tsh), 0); | ||
1701 | J->base[1] = tsh; | ||
1702 | } | ||
1703 | id = crec_bit64_type(cts, &rd->argv[0]); | ||
1704 | if (id) { | ||
1705 | TRef tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]); | ||
1706 | uint32_t op = rd->data; | ||
1707 | if (!tsh) tsh = lj_opt_narrow_tobit(J, J->base[1]); | ||
1708 | if (!(op < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) && | ||
1709 | !tref_isk(tsh)) | ||
1710 | tsh = emitir(IRTI(IR_BAND), tsh, lj_ir_kint(J, 63)); | ||
1711 | #ifdef LJ_TARGET_UNIFYROT | ||
1712 | if (op == (LJ_TARGET_UNIFYROT == 1 ? IR_BROR : IR_BROL)) { | ||
1713 | op = LJ_TARGET_UNIFYROT == 1 ? IR_BROL : IR_BROR; | ||
1714 | tsh = emitir(IRTI(IR_NEG), tsh, tsh); | ||
1715 | } | ||
1716 | #endif | ||
1717 | tr = emitir(IRT(op, id-CTID_INT64+IRT_I64), tr, tsh); | ||
1718 | J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr); | ||
1719 | return 1; | ||
1720 | } | ||
1721 | return 0; | ||
1722 | } | ||
1723 | |||
1630 | /* -- Miscellaneous library functions ------------------------------------- */ | 1724 | /* -- Miscellaneous library functions ------------------------------------- */ |
1631 | 1725 | ||
1632 | void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd) | 1726 | void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd) |