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.c70
1 files changed, 43 insertions, 27 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index cd5c7d49..1ba98ae8 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -137,7 +137,7 @@ static int crec_isnonzero(CType *s, void *p)
137 } 137 }
138} 138}
139 139
140static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp, 140static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp,
141 void *svisnz) 141 void *svisnz)
142{ 142{
143 CTSize dsize = d->size, ssize = s->size; 143 CTSize dsize = d->size, ssize = s->size;
@@ -190,6 +190,7 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp,
190#endif 190#endif
191 xstore: 191 xstore:
192 if (dt == IRT_I64 || dt == IRT_U64) lj_needsplit(J); 192 if (dt == IRT_I64 || dt == IRT_U64) lj_needsplit(J);
193 if (dp == 0) return sp;
193 emitir(IRT(IR_XSTORE, dt), dp, sp); 194 emitir(IRT(IR_XSTORE, dt), dp, sp);
194 break; 195 break;
195 case CCX(I, C): 196 case CCX(I, C):
@@ -290,6 +291,7 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp,
290 lj_trace_err(J, LJ_TRERR_NYICONV); 291 lj_trace_err(J, LJ_TRERR_NYICONV);
291 break; 292 break;
292 } 293 }
294 return 0;
293} 295}
294 296
295/* -- Convert C type to TValue (load) ------------------------------------- */ 297/* -- Convert C type to TValue (load) ------------------------------------- */
@@ -306,21 +308,18 @@ static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp)
306 goto err_nyi; /* NYI: copyval of >64 bit integers. */ 308 goto err_nyi; /* NYI: copyval of >64 bit integers. */
307 tr = emitir(IRT(IR_XLOAD, t), sp, 0); 309 tr = emitir(IRT(IR_XLOAD, t), sp, 0);
308 if (t == IRT_FLOAT || t == IRT_U32) { /* Keep uint32_t/float as numbers. */ 310 if (t == IRT_FLOAT || t == IRT_U32) { /* Keep uint32_t/float as numbers. */
309 tr = emitconv(tr, IRT_NUM, t, 0); 311 return emitconv(tr, IRT_NUM, t, 0);
310 } else if (t == IRT_I64 || t == IRT_U64) { /* Box 64 bit integer. */ 312 } else if (t == IRT_I64 || t == IRT_U64) { /* Box 64 bit integer. */
311 TRef dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, sid), TREF_NIL); 313 sp = tr;
312 TRef ptr = emitir(IRT(IR_ADD, IRT_PTR), dp,
313 lj_ir_kintp(J, sizeof(GCcdata)));
314 emitir(IRT(IR_XSTORE, t), ptr, tr);
315 lj_needsplit(J); 314 lj_needsplit(J);
316 return dp;
317 } else if ((sinfo & CTF_BOOL)) { 315 } else if ((sinfo & CTF_BOOL)) {
318 /* Assume not equal to zero. Fixup and emit pending guard later. */ 316 /* Assume not equal to zero. Fixup and emit pending guard later. */
319 lj_ir_set(J, IRTGI(IR_NE), tr, lj_ir_kint(J, 0)); 317 lj_ir_set(J, IRTGI(IR_NE), tr, lj_ir_kint(J, 0));
320 J->postproc = LJ_POST_FIXGUARD; 318 J->postproc = LJ_POST_FIXGUARD;
321 tr = TREF_TRUE; 319 return TREF_TRUE;
320 } else {
321 return tr;
322 } 322 }
323 return tr;
324 } else if (ctype_isptr(sinfo)) { 323 } else if (ctype_isptr(sinfo)) {
325 IRType t = (LJ_64 && s->size == 8) ? IRT_P64 : IRT_P32; 324 IRType t = (LJ_64 && s->size == 8) ? IRT_P64 : IRT_P32;
326 sp = emitir(IRT(IR_XLOAD, t), sp, 0); 325 sp = emitir(IRT(IR_XLOAD, t), sp, 0);
@@ -345,13 +344,13 @@ static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp)
345 err_nyi: 344 err_nyi:
346 lj_trace_err(J, LJ_TRERR_NYICONV); 345 lj_trace_err(J, LJ_TRERR_NYICONV);
347 } 346 }
348 /* Box pointer or ref. */ 347 /* Box pointer, ref or 64 bit integer. */
349 return emitir(IRTG(IR_CNEWP, IRT_CDATA), lj_ir_kint(J, sid), sp); 348 return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, sid), sp);
350} 349}
351 350
352/* -- Convert TValue to C type (store) ------------------------------------ */ 351/* -- Convert TValue to C type (store) ------------------------------------ */
353 352
354static void crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, TValue *sval) 353static TRef crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, TValue *sval)
355{ 354{
356 CTState *cts = ctype_ctsG(J2G(J)); 355 CTState *cts = ctype_ctsG(J2G(J));
357 CTypeID sid = CTID_P_VOID; 356 CTypeID sid = CTID_P_VOID;
@@ -402,6 +401,12 @@ static void crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, TValue *sval)
402 } else { 401 } else {
403 goto doconv; /* The pointer value was loaded, don't load number. */ 402 goto doconv; /* The pointer value was loaded, don't load number. */
404 } 403 }
404
405 } else if (ctype_isnum(s->info) && s->size == 8) {
406 IRType t = (s->info & CTF_UNSIGNED) ? IRT_U64 : IRT_I64;
407 sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_INT64);
408 lj_needsplit(J);
409 goto doconv;
405 } else { 410 } else {
406 sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCcdata))); 411 sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCcdata)));
407 } 412 }
@@ -418,7 +423,7 @@ static void crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, TValue *sval)
418 s = ctype_get(cts, sid); 423 s = ctype_get(cts, sid);
419doconv: 424doconv:
420 if (ctype_isenum(d->info)) d = ctype_child(cts, d); 425 if (ctype_isenum(d->info)) d = ctype_child(cts, d);
421 crec_ct_ct(J, d, s, dp, sp, svisnz); 426 return crec_ct_ct(J, d, s, dp, sp, svisnz);
422} 427}
423 428
424/* -- C data metamethods -------------------------------------------------- */ 429/* -- C data metamethods -------------------------------------------------- */
@@ -578,15 +583,18 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
578 CTState *cts = ctype_ctsG(J2G(J)); 583 CTState *cts = ctype_ctsG(J2G(J));
579 CTSize sz; 584 CTSize sz;
580 CTInfo info = lj_ctype_info(cts, id, &sz); 585 CTInfo info = lj_ctype_info(cts, id, &sz);
586 CType *d = ctype_raw(cts, id);
581 TRef trid; 587 TRef trid;
582 if (sz == 0 || sz > 64 || (info & CTF_VLA) || ctype_align(info) > CT_MEMALIGN) 588 if (sz == 0 || sz > 64 || (info & CTF_VLA) || ctype_align(info) > CT_MEMALIGN)
583 lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: large/special allocations. */ 589 lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: large/special allocations. */
584 trid = lj_ir_kint(J, id); 590 trid = lj_ir_kint(J, id);
585 if (ctype_isptr(info)) { 591 /* Use special instruction to box pointer or 64 bit integer. */
586 TRef sp = J->base[1] ? J->base[1] : lj_ir_kptr(J, NULL); 592 if (ctype_isptr(info) || (ctype_isnum(info) && sz == 8)) {
587 J->base[0] = emitir(IRTG(IR_CNEWP, IRT_CDATA), trid, sp); 593 TRef sp = J->base[1] ? crec_ct_tv(J, d, 0, J->base[1], &rd->argv[1]) :
594 ctype_isptr(info) ? lj_ir_kptr(J, NULL) :
595 (lj_needsplit(J), lj_ir_kint64(J, 0));
596 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, sp);
588 } else { 597 } else {
589 CType *d = ctype_raw(cts, id);
590 TRef trcd = emitir(IRTG(IR_CNEW, IRT_CDATA), trid, TREF_NIL); 598 TRef trcd = emitir(IRTG(IR_CNEW, IRT_CDATA), trid, TREF_NIL);
591 J->base[0] = trcd; 599 J->base[0] = trcd;
592 if (J->base[1] && !J->base[2] && !lj_cconv_multi_init(d, &rd->argv[1])) { 600 if (J->base[1] && !J->base[2] && !lj_cconv_multi_init(d, &rd->argv[1])) {
@@ -598,7 +606,7 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
598 TValue tv; 606 TValue tv;
599 TValue *sval = &tv; 607 TValue *sval = &tv;
600 MSize i; 608 MSize i;
601 setnumV(&tv, 0); 609 tv.u64 = 0;
602 if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info))) 610 if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info)))
603 lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init array of aggregates. */ 611 lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init array of aggregates. */
604 for (i = 1, ofs = 0; ofs < sz; ofs += esize) { 612 for (i = 1, ofs = 0; ofs < sz; ofs += esize) {
@@ -645,11 +653,16 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
645 } 653 }
646 } 654 }
647 } else { 655 } else {
648 TRef sp, dp; 656 TRef dp;
649 single_init: 657 single_init:
650 sp = J->base[1] ? J->base[1] : lj_ir_kint(J, 0);
651 dp = emitir(IRT(IR_ADD, IRT_PTR), trcd, lj_ir_kintp(J, sizeof(GCcdata))); 658 dp = emitir(IRT(IR_ADD, IRT_PTR), trcd, lj_ir_kintp(J, sizeof(GCcdata)));
652 crec_ct_tv(J, d, dp, sp, &rd->argv[1]); 659 if (J->base[1]) {
660 crec_ct_tv(J, d, dp, J->base[1], &rd->argv[1]);
661 } else {
662 TValue tv;
663 tv.u64 = 0;
664 crec_ct_tv(J, d, dp, lj_ir_kint(J, 0), &tv);
665 }
653 } 666 }
654 } 667 }
655} 668}
@@ -669,7 +682,7 @@ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm)
669 if (ctype_isnum(s[0]->info) && ctype_isnum(s[1]->info)) { 682 if (ctype_isnum(s[0]->info) && ctype_isnum(s[1]->info)) {
670 IRType dt; 683 IRType dt;
671 CTypeID id; 684 CTypeID id;
672 TRef tr, dp, ptr; 685 TRef tr;
673 MSize i; 686 MSize i;
674 lj_needsplit(J); 687 lj_needsplit(J);
675 if (((s[0]->info & CTF_UNSIGNED) && s[0]->size == 8) || 688 if (((s[0]->info & CTF_UNSIGNED) && s[0]->size == 8) ||
@@ -702,10 +715,7 @@ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm)
702 } else { 715 } else {
703 tr = emitir(IRT(mm+(int)IR_ADD-(int)MM_add, dt), sp[0], sp[1]); 716 tr = emitir(IRT(mm+(int)IR_ADD-(int)MM_add, dt), sp[0], sp[1]);
704 } 717 }
705 dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, id), TREF_NIL); 718 return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
706 ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, sizeof(GCcdata)));
707 emitir(IRT(IR_XSTORE, dt), ptr, tr);
708 return dp;
709 } 719 }
710 return 0; 720 return 0;
711} 721}
@@ -767,7 +777,7 @@ static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm)
767 tr = emitir(IRT(IR_ADD, IRT_PTR), sp[0], tr); 777 tr = emitir(IRT(IR_ADD, IRT_PTR), sp[0], tr);
768 id = lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|ctype_cid(ctp->info)), 778 id = lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|ctype_cid(ctp->info)),
769 CTSIZE_PTR); 779 CTSIZE_PTR);
770 return emitir(IRTG(IR_CNEWP, IRT_CDATA), lj_ir_kint(J, id), tr); 780 return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
771 } 781 }
772} 782}
773 783
@@ -787,6 +797,11 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
787 IRType t = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32; 797 IRType t = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32;
788 if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct); 798 if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct);
789 tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_PTR); 799 tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_PTR);
800 } else if (ctype_isnum(ct->info) && ct->size == 8) {
801 IRType t = (ct->info & CTF_UNSIGNED) ? IRT_U64 : IRT_I64;
802 tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_INT64);
803 lj_needsplit(J);
804 goto ok;
790 } else { 805 } else {
791 tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata))); 806 tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata)));
792 } 807 }
@@ -807,6 +822,7 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
807 } else if (!tref_isnum(tr)) { 822 } else if (!tref_isnum(tr)) {
808 goto err_type; 823 goto err_type;
809 } 824 }
825 ok:
810 s[i] = ct; 826 s[i] = ct;
811 sp[i] = tr; 827 sp[i] = tr;
812 } 828 }