diff options
author | Mike Pall <mike> | 2013-03-13 22:44:01 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2013-03-14 06:03:18 +0100 |
commit | a98aede37772797b4471e1a094452051edff5862 (patch) | |
tree | 6e8c86838e359b899ffa0021bf3149087caa71da /src/lj_crecord.c | |
parent | 3e8f5ac7186ecac63e17688b9ba6e72697143dbb (diff) | |
download | luajit-a98aede37772797b4471e1a094452051edff5862.tar.gz luajit-a98aede37772797b4471e1a094452051edff5862.tar.bz2 luajit-a98aede37772797b4471e1a094452051edff5862.zip |
FFI: Add 64 bit bitwise operations.
Diffstat (limited to 'src/lj_crecord.c')
-rw-r--r-- | src/lj_crecord.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index a5d896eb..2bf0bc1d 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -1626,6 +1626,101 @@ void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd) | |||
1626 | crec_finalizer(J, J->base[0], &rd->argv[1]); | 1626 | crec_finalizer(J, J->base[0], &rd->argv[1]); |
1627 | } | 1627 | } |
1628 | 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 | |||
1629 | /* -- Miscellaneous library functions ------------------------------------- */ | 1724 | /* -- Miscellaneous library functions ------------------------------------- */ |
1630 | 1725 | ||
1631 | void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd) | 1726 | void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd) |