summaryrefslogtreecommitdiff
path: root/src/lj_crecord.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_crecord.c')
-rw-r--r--src/lj_crecord.c35
1 files changed, 33 insertions, 2 deletions
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)
564 564
565static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm) 565static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm)
566{ 566{
567 UNUSED(J); UNUSED(sp); UNUSED(s); UNUSED(mm); 567 if (ctype_isnum(s[0]->info) && ctype_isnum(s[1]->info)) {
568 return 0; /* NYI: 64 bit integer arithmetic. */ 568 IRType dt;
569 CTypeID id;
570 TRef tr, dp, ptr;
571 MSize i;
572 if (((s[0]->info & CTF_UNSIGNED) && s[0]->size == 8) ||
573 ((s[1]->info & CTF_UNSIGNED) && s[1]->size == 8)) {
574 dt = IRT_U64; id = CTID_UINT64;
575 } else {
576 dt = IRT_I64; id = CTID_INT64;
577 }
578 for (i = 0; i < 2; i++) {
579 IRType st = tref_type(sp[i]);
580 if (st == IRT_NUM || st == IRT_FLOAT)
581 sp[i] = emitconv(sp[i], dt, st, IRCONV_TRUNC|IRCONV_ANY);
582 else if (!(st == IRT_I64 || st == IRT_U64))
583 sp[i] = emitconv(sp[i], dt, IRT_INT,
584 ((st - IRT_I8) & 1) ? 0 : IRCONV_SEXT);
585 }
586 if (mm == MM_pow) {
587 tr = lj_ir_call(J, IRCALL_lj_cdata_powi64, sp[0], sp[1],
588 lj_ir_kint(J, (int)dt-(int)IRT_I64));
589 } else {
590 if (mm == MM_div || mm == MM_mod)
591 return 0; /* NYI: integer div, mod. */
592 tr = emitir(IRT(mm+(int)IR_ADD-(int)MM_add, dt), sp[0], sp[1]);
593 }
594 dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, id), TREF_NIL);
595 ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, sizeof(GCcdata)));
596 emitir(IRT(IR_XSTORE, dt), ptr, tr);
597 return dp;
598 }
599 return 0;
569} 600}
570 601
571static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm) 602static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm)