diff options
Diffstat (limited to 'src/lj_crecord.c')
-rw-r--r-- | src/lj_crecord.c | 70 |
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 | ||
140 | static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp, | 140 | static 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 | ||
354 | static void crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, TValue *sval) | 353 | static 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); |
419 | doconv: | 424 | doconv: |
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 | } |