From eaf88dfb3a30c88b262e1705fdc343c7e861a003 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Mon, 3 Jan 2011 03:35:35 +0100 Subject: [PATCH] FFI: Record 64 bit integer arithmetic. Currently NYI in the x86 backend. --- src/lj_cdata.c | 6 ------ src/lj_crecord.c | 35 +++++++++++++++++++++++++++++++++-- src/lj_ir.h | 7 +++++++ 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/lj_cdata.c b/src/lj_cdata.c index 71453e27..7c7eed43 100644 --- a/src/lj_cdata.c +++ b/src/lj_cdata.c @@ -235,7 +235,6 @@ void lj_cdata_set(CTState *cts, CType *d, uint8_t *dp, TValue *o, CTInfo qual) uint64_t lj_cdata_powi64(uint64_t x, uint64_t k, int isunsigned) { uint64_t y = 0; - int sign = 0; if (k == 0) return 1; if (!isunsigned) { @@ -249,10 +248,6 @@ uint64_t lj_cdata_powi64(uint64_t x, uint64_t k, int isunsigned) else return 0; } - if ((int64_t)x < 0) { - x = -x; - sign = (k & 1); - } } for (; (k & 1) == 0; k >>= 1) x *= x; y = x; @@ -265,7 +260,6 @@ uint64_t lj_cdata_powi64(uint64_t x, uint64_t k, int isunsigned) } y *= x; } - if (sign) y = (uint64_t)-(int64_t)y; return y; } diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 81d53dfc..a02f1c4d 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c @@ -564,8 +564,39 @@ void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd) static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm) { - UNUSED(J); UNUSED(sp); UNUSED(s); UNUSED(mm); - return 0; /* NYI: 64 bit integer arithmetic. */ + if (ctype_isnum(s[0]->info) && ctype_isnum(s[1]->info)) { + IRType dt; + CTypeID id; + TRef tr, dp, ptr; + MSize i; + if (((s[0]->info & CTF_UNSIGNED) && s[0]->size == 8) || + ((s[1]->info & CTF_UNSIGNED) && s[1]->size == 8)) { + dt = IRT_U64; id = CTID_UINT64; + } else { + dt = IRT_I64; id = CTID_INT64; + } + for (i = 0; i < 2; i++) { + IRType st = tref_type(sp[i]); + if (st == IRT_NUM || st == IRT_FLOAT) + sp[i] = emitconv(sp[i], dt, st, IRCONV_TRUNC|IRCONV_ANY); + else if (!(st == IRT_I64 || st == IRT_U64)) + sp[i] = emitconv(sp[i], dt, IRT_INT, + ((st - IRT_I8) & 1) ? 0 : IRCONV_SEXT); + } + if (mm == MM_pow) { + tr = lj_ir_call(J, IRCALL_lj_cdata_powi64, sp[0], sp[1], + lj_ir_kint(J, (int)dt-(int)IRT_I64)); + } else { + if (mm == MM_div || mm == MM_mod) + return 0; /* NYI: integer div, mod. */ + tr = emitir(IRT(mm+(int)IR_ADD-(int)MM_add, dt), sp[0], sp[1]); + } + dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, id), TREF_NIL); + ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, sizeof(GCcdata))); + emitir(IRT(IR_XSTORE, dt), ptr, tr); + return dp; + } + return 0; } static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm) diff --git a/src/lj_ir.h b/src/lj_ir.h index 7d1e6daf..a8e890c5 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h @@ -251,6 +251,12 @@ typedef struct CCallInfo { #define CCI_FASTCALL 0x0800 /* Fastcall convention. */ /* Function definitions for CALL* instructions. */ +#if LJ_HASFFI +#define IRCALLDEF_FFI(_) \ + _(lj_cdata_powi64, 3, N, U64, CCI_NOFPRCLOBBER) +#else +#define IRCALLDEF_FFI(_) +#endif #define IRCALLDEF(_) \ _(lj_str_cmp, 2, FN, INT, CCI_NOFPRCLOBBER) \ _(lj_str_new, 3, S, STR, CCI_L) \ @@ -265,6 +271,7 @@ typedef struct CCallInfo { _(lj_gc_barrieruv, 2, FS, NIL, 0) \ _(lj_mem_newgco, 2, FS, P32, CCI_L) \ _(lj_math_random_step, 1, FS, NUM, CCI_CASTU64|CCI_NOFPRCLOBBER) \ + IRCALLDEF_FFI(_) \ _(sinh, 1, N, NUM, 0) \ _(cosh, 1, N, NUM, 0) \ _(tanh, 1, N, NUM, 0) \