diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_asm.c | 122 |
1 files changed, 80 insertions, 42 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index 90373f27..2659c8a2 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -96,6 +96,12 @@ typedef struct ASMState { | |||
96 | uint16_t parentmap[LJ_MAX_JSLOTS]; /* Parent instruction to RegSP map. */ | 96 | uint16_t parentmap[LJ_MAX_JSLOTS]; /* Parent instruction to RegSP map. */ |
97 | } ASMState; | 97 | } ASMState; |
98 | 98 | ||
99 | #ifdef LUA_USE_ASSERT | ||
100 | #define lj_assertA(c, ...) lj_assertG_(J2G(as->J), (c), __VA_ARGS__) | ||
101 | #else | ||
102 | #define lj_assertA(c, ...) ((void)as) | ||
103 | #endif | ||
104 | |||
99 | #define IR(ref) (&as->ir[(ref)]) | 105 | #define IR(ref) (&as->ir[(ref)]) |
100 | 106 | ||
101 | #define ASMREF_TMP1 REF_TRUE /* Temp. register. */ | 107 | #define ASMREF_TMP1 REF_TRUE /* Temp. register. */ |
@@ -127,9 +133,8 @@ static LJ_AINLINE void checkmclim(ASMState *as) | |||
127 | #ifdef LUA_USE_ASSERT | 133 | #ifdef LUA_USE_ASSERT |
128 | if (as->mcp + MCLIM_REDZONE < as->mcp_prev) { | 134 | if (as->mcp + MCLIM_REDZONE < as->mcp_prev) { |
129 | IRIns *ir = IR(as->curins+1); | 135 | IRIns *ir = IR(as->curins+1); |
130 | fprintf(stderr, "RED ZONE OVERFLOW: %p IR %04d %02d %04d %04d\n", as->mcp, | 136 | lj_assertA(0, "red zone overflow: %p IR %04d %02d %04d %04d\n", as->mcp, |
131 | as->curins+1-REF_BIAS, ir->o, ir->op1-REF_BIAS, ir->op2-REF_BIAS); | 137 | as->curins+1-REF_BIAS, ir->o, ir->op1-REF_BIAS, ir->op2-REF_BIAS); |
132 | lua_assert(0); | ||
133 | } | 138 | } |
134 | #endif | 139 | #endif |
135 | if (LJ_UNLIKELY(as->mcp < as->mclim)) asm_mclimit(as); | 140 | if (LJ_UNLIKELY(as->mcp < as->mclim)) asm_mclimit(as); |
@@ -243,7 +248,7 @@ static void ra_dprintf(ASMState *as, const char *fmt, ...) | |||
243 | *p++ = *q >= 'A' && *q <= 'Z' ? *q + 0x20 : *q; | 248 | *p++ = *q >= 'A' && *q <= 'Z' ? *q + 0x20 : *q; |
244 | } else { | 249 | } else { |
245 | *p++ = '?'; | 250 | *p++ = '?'; |
246 | lua_assert(0); | 251 | lj_assertA(0, "bad register %d for debug format \"%s\"", r, fmt); |
247 | } | 252 | } |
248 | } else if (e[1] == 'f' || e[1] == 'i') { | 253 | } else if (e[1] == 'f' || e[1] == 'i') { |
249 | IRRef ref; | 254 | IRRef ref; |
@@ -261,7 +266,7 @@ static void ra_dprintf(ASMState *as, const char *fmt, ...) | |||
261 | } else if (e[1] == 'x') { | 266 | } else if (e[1] == 'x') { |
262 | p += sprintf(p, "%08x", va_arg(argp, int32_t)); | 267 | p += sprintf(p, "%08x", va_arg(argp, int32_t)); |
263 | } else { | 268 | } else { |
264 | lua_assert(0); | 269 | lj_assertA(0, "bad debug format code"); |
265 | } | 270 | } |
266 | fmt = e+2; | 271 | fmt = e+2; |
267 | } | 272 | } |
@@ -320,7 +325,7 @@ static Reg ra_rematk(ASMState *as, IRRef ref) | |||
320 | Reg r; | 325 | Reg r; |
321 | if (ra_iskref(ref)) { | 326 | if (ra_iskref(ref)) { |
322 | r = ra_krefreg(ref); | 327 | r = ra_krefreg(ref); |
323 | lua_assert(!rset_test(as->freeset, r)); | 328 | lj_assertA(!rset_test(as->freeset, r), "rematk of free reg %d", r); |
324 | ra_free(as, r); | 329 | ra_free(as, r); |
325 | ra_modified(as, r); | 330 | ra_modified(as, r); |
326 | #if LJ_64 | 331 | #if LJ_64 |
@@ -332,7 +337,9 @@ static Reg ra_rematk(ASMState *as, IRRef ref) | |||
332 | } | 337 | } |
333 | ir = IR(ref); | 338 | ir = IR(ref); |
334 | r = ir->r; | 339 | r = ir->r; |
335 | lua_assert(ra_hasreg(r) && !ra_hasspill(ir->s)); | 340 | lj_assertA(ra_hasreg(r), "rematk of K%03d has no reg", REF_BIAS - ref); |
341 | lj_assertA(!ra_hasspill(ir->s), | ||
342 | "rematk of K%03d has spill slot [%x]", REF_BIAS - ref, ir->s); | ||
336 | ra_free(as, r); | 343 | ra_free(as, r); |
337 | ra_modified(as, r); | 344 | ra_modified(as, r); |
338 | ir->r = RID_INIT; /* Do not keep any hint. */ | 345 | ir->r = RID_INIT; /* Do not keep any hint. */ |
@@ -346,7 +353,8 @@ static Reg ra_rematk(ASMState *as, IRRef ref) | |||
346 | ra_sethint(ir->r, RID_BASE); /* Restore BASE register hint. */ | 353 | ra_sethint(ir->r, RID_BASE); /* Restore BASE register hint. */ |
347 | emit_getgl(as, r, jit_base); | 354 | emit_getgl(as, r, jit_base); |
348 | } else if (emit_canremat(ASMREF_L) && ir->o == IR_KPRI) { | 355 | } else if (emit_canremat(ASMREF_L) && ir->o == IR_KPRI) { |
349 | lua_assert(irt_isnil(ir->t)); /* REF_NIL stores ASMREF_L register. */ | 356 | /* REF_NIL stores ASMREF_L register. */ |
357 | lj_assertA(irt_isnil(ir->t), "rematk of bad ASMREF_L"); | ||
350 | emit_getgl(as, r, cur_L); | 358 | emit_getgl(as, r, cur_L); |
351 | #if LJ_64 | 359 | #if LJ_64 |
352 | } else if (ir->o == IR_KINT64) { | 360 | } else if (ir->o == IR_KINT64) { |
@@ -359,8 +367,9 @@ static Reg ra_rematk(ASMState *as, IRRef ref) | |||
359 | #endif | 367 | #endif |
360 | #endif | 368 | #endif |
361 | } else { | 369 | } else { |
362 | lua_assert(ir->o == IR_KINT || ir->o == IR_KGC || | 370 | lj_assertA(ir->o == IR_KINT || ir->o == IR_KGC || |
363 | ir->o == IR_KPTR || ir->o == IR_KKPTR || ir->o == IR_KNULL); | 371 | ir->o == IR_KPTR || ir->o == IR_KKPTR || ir->o == IR_KNULL, |
372 | "rematk of bad IR op %d", ir->o); | ||
364 | emit_loadi(as, r, ir->i); | 373 | emit_loadi(as, r, ir->i); |
365 | } | 374 | } |
366 | return r; | 375 | return r; |
@@ -370,7 +379,8 @@ static Reg ra_rematk(ASMState *as, IRRef ref) | |||
370 | static int32_t ra_spill(ASMState *as, IRIns *ir) | 379 | static int32_t ra_spill(ASMState *as, IRIns *ir) |
371 | { | 380 | { |
372 | int32_t slot = ir->s; | 381 | int32_t slot = ir->s; |
373 | lua_assert(ir >= as->ir + REF_TRUE); | 382 | lj_assertA(ir >= as->ir + REF_TRUE, |
383 | "spill of K%03d", REF_BIAS - (int)(ir - as->ir)); | ||
374 | if (!ra_hasspill(slot)) { | 384 | if (!ra_hasspill(slot)) { |
375 | if (irt_is64(ir->t)) { | 385 | if (irt_is64(ir->t)) { |
376 | slot = as->evenspill; | 386 | slot = as->evenspill; |
@@ -395,7 +405,9 @@ static Reg ra_releasetmp(ASMState *as, IRRef ref) | |||
395 | { | 405 | { |
396 | IRIns *ir = IR(ref); | 406 | IRIns *ir = IR(ref); |
397 | Reg r = ir->r; | 407 | Reg r = ir->r; |
398 | lua_assert(ra_hasreg(r) && !ra_hasspill(ir->s)); | 408 | lj_assertA(ra_hasreg(r), "release of TMP%d has no reg", ref-ASMREF_TMP1+1); |
409 | lj_assertA(!ra_hasspill(ir->s), | ||
410 | "release of TMP%d has spill slot [%x]", ref-ASMREF_TMP1+1, ir->s); | ||
399 | ra_free(as, r); | 411 | ra_free(as, r); |
400 | ra_modified(as, r); | 412 | ra_modified(as, r); |
401 | ir->r = RID_INIT; | 413 | ir->r = RID_INIT; |
@@ -411,7 +423,7 @@ static Reg ra_restore(ASMState *as, IRRef ref) | |||
411 | IRIns *ir = IR(ref); | 423 | IRIns *ir = IR(ref); |
412 | int32_t ofs = ra_spill(as, ir); /* Force a spill slot. */ | 424 | int32_t ofs = ra_spill(as, ir); /* Force a spill slot. */ |
413 | Reg r = ir->r; | 425 | Reg r = ir->r; |
414 | lua_assert(ra_hasreg(r)); | 426 | lj_assertA(ra_hasreg(r), "restore of IR %04d has no reg", ref - REF_BIAS); |
415 | ra_sethint(ir->r, r); /* Keep hint. */ | 427 | ra_sethint(ir->r, r); /* Keep hint. */ |
416 | ra_free(as, r); | 428 | ra_free(as, r); |
417 | if (!rset_test(as->weakset, r)) { /* Only restore non-weak references. */ | 429 | if (!rset_test(as->weakset, r)) { /* Only restore non-weak references. */ |
@@ -440,14 +452,15 @@ static Reg ra_evict(ASMState *as, RegSet allow) | |||
440 | { | 452 | { |
441 | IRRef ref; | 453 | IRRef ref; |
442 | RegCost cost = ~(RegCost)0; | 454 | RegCost cost = ~(RegCost)0; |
443 | lua_assert(allow != RSET_EMPTY); | 455 | lj_assertA(allow != RSET_EMPTY, "evict from empty set"); |
444 | if (RID_NUM_FPR == 0 || allow < RID2RSET(RID_MAX_GPR)) { | 456 | if (RID_NUM_FPR == 0 || allow < RID2RSET(RID_MAX_GPR)) { |
445 | GPRDEF(MINCOST) | 457 | GPRDEF(MINCOST) |
446 | } else { | 458 | } else { |
447 | FPRDEF(MINCOST) | 459 | FPRDEF(MINCOST) |
448 | } | 460 | } |
449 | ref = regcost_ref(cost); | 461 | ref = regcost_ref(cost); |
450 | lua_assert(ra_iskref(ref) || (ref >= as->T->nk && ref < as->T->nins)); | 462 | lj_assertA(ra_iskref(ref) || (ref >= as->T->nk && ref < as->T->nins), |
463 | "evict of out-of-range IR %04d", ref - REF_BIAS); | ||
451 | /* Preferably pick any weak ref instead of a non-weak, non-const ref. */ | 464 | /* Preferably pick any weak ref instead of a non-weak, non-const ref. */ |
452 | if (!irref_isk(ref) && (as->weakset & allow)) { | 465 | if (!irref_isk(ref) && (as->weakset & allow)) { |
453 | IRIns *ir = IR(ref); | 466 | IRIns *ir = IR(ref); |
@@ -605,7 +618,8 @@ static Reg ra_allocref(ASMState *as, IRRef ref, RegSet allow) | |||
605 | IRIns *ir = IR(ref); | 618 | IRIns *ir = IR(ref); |
606 | RegSet pick = as->freeset & allow; | 619 | RegSet pick = as->freeset & allow; |
607 | Reg r; | 620 | Reg r; |
608 | lua_assert(ra_noreg(ir->r)); | 621 | lj_assertA(ra_noreg(ir->r), |
622 | "IR %04d already has reg %d", ref - REF_BIAS, ir->r); | ||
609 | if (pick) { | 623 | if (pick) { |
610 | /* First check register hint from propagation or PHI. */ | 624 | /* First check register hint from propagation or PHI. */ |
611 | if (ra_hashint(ir->r)) { | 625 | if (ra_hashint(ir->r)) { |
@@ -669,8 +683,10 @@ static void ra_rename(ASMState *as, Reg down, Reg up) | |||
669 | IRIns *ir = IR(ref); | 683 | IRIns *ir = IR(ref); |
670 | ir->r = (uint8_t)up; | 684 | ir->r = (uint8_t)up; |
671 | as->cost[down] = 0; | 685 | as->cost[down] = 0; |
672 | lua_assert((down < RID_MAX_GPR) == (up < RID_MAX_GPR)); | 686 | lj_assertA((down < RID_MAX_GPR) == (up < RID_MAX_GPR), |
673 | lua_assert(!rset_test(as->freeset, down) && rset_test(as->freeset, up)); | 687 | "rename between GPR/FPR %d and %d", down, up); |
688 | lj_assertA(!rset_test(as->freeset, down), "rename from free reg %d", down); | ||
689 | lj_assertA(rset_test(as->freeset, up), "rename to non-free reg %d", up); | ||
674 | ra_free(as, down); /* 'down' is free ... */ | 690 | ra_free(as, down); /* 'down' is free ... */ |
675 | ra_modified(as, down); | 691 | ra_modified(as, down); |
676 | rset_clear(as->freeset, up); /* ... and 'up' is now allocated. */ | 692 | rset_clear(as->freeset, up); /* ... and 'up' is now allocated. */ |
@@ -711,7 +727,7 @@ static void ra_destreg(ASMState *as, IRIns *ir, Reg r) | |||
711 | { | 727 | { |
712 | Reg dest = ra_dest(as, ir, RID2RSET(r)); | 728 | Reg dest = ra_dest(as, ir, RID2RSET(r)); |
713 | if (dest != r) { | 729 | if (dest != r) { |
714 | lua_assert(rset_test(as->freeset, r)); | 730 | lj_assertA(rset_test(as->freeset, r), "dest reg %d is not free", r); |
715 | ra_modified(as, r); | 731 | ra_modified(as, r); |
716 | emit_movrr(as, ir, dest, r); | 732 | emit_movrr(as, ir, dest, r); |
717 | } | 733 | } |
@@ -744,8 +760,9 @@ static void ra_left(ASMState *as, Reg dest, IRRef lref) | |||
744 | #endif | 760 | #endif |
745 | #endif | 761 | #endif |
746 | } else if (ir->o != IR_KPRI) { | 762 | } else if (ir->o != IR_KPRI) { |
747 | lua_assert(ir->o == IR_KINT || ir->o == IR_KGC || | 763 | lj_assertA(ir->o == IR_KINT || ir->o == IR_KGC || |
748 | ir->o == IR_KPTR || ir->o == IR_KKPTR || ir->o == IR_KNULL); | 764 | ir->o == IR_KPTR || ir->o == IR_KKPTR || ir->o == IR_KNULL, |
765 | "K%03d has bad IR op %d", REF_BIAS - lref, ir->o); | ||
749 | emit_loadi(as, dest, ir->i); | 766 | emit_loadi(as, dest, ir->i); |
750 | return; | 767 | return; |
751 | } | 768 | } |
@@ -887,11 +904,14 @@ static void asm_snap_alloc1(ASMState *as, IRRef ref) | |||
887 | #endif | 904 | #endif |
888 | { /* Allocate stored values for TNEW, TDUP and CNEW. */ | 905 | { /* Allocate stored values for TNEW, TDUP and CNEW. */ |
889 | IRIns *irs; | 906 | IRIns *irs; |
890 | lua_assert(ir->o == IR_TNEW || ir->o == IR_TDUP || ir->o == IR_CNEW); | 907 | lj_assertA(ir->o == IR_TNEW || ir->o == IR_TDUP || ir->o == IR_CNEW, |
908 | "sink of IR %04d has bad op %d", ref - REF_BIAS, ir->o); | ||
891 | for (irs = IR(as->snapref-1); irs > ir; irs--) | 909 | for (irs = IR(as->snapref-1); irs > ir; irs--) |
892 | if (irs->r == RID_SINK && asm_sunk_store(as, ir, irs)) { | 910 | if (irs->r == RID_SINK && asm_sunk_store(as, ir, irs)) { |
893 | lua_assert(irs->o == IR_ASTORE || irs->o == IR_HSTORE || | 911 | lj_assertA(irs->o == IR_ASTORE || irs->o == IR_HSTORE || |
894 | irs->o == IR_FSTORE || irs->o == IR_XSTORE); | 912 | irs->o == IR_FSTORE || irs->o == IR_XSTORE, |
913 | "sunk store IR %04d has bad op %d", | ||
914 | (int)(irs - as->ir) - REF_BIAS, irs->o); | ||
895 | asm_snap_alloc1(as, irs->op2); | 915 | asm_snap_alloc1(as, irs->op2); |
896 | if (LJ_32 && (irs+1)->o == IR_HIOP) | 916 | if (LJ_32 && (irs+1)->o == IR_HIOP) |
897 | asm_snap_alloc1(as, (irs+1)->op2); | 917 | asm_snap_alloc1(as, (irs+1)->op2); |
@@ -938,7 +958,9 @@ static void asm_snap_alloc(ASMState *as) | |||
938 | if (!irref_isk(ref)) { | 958 | if (!irref_isk(ref)) { |
939 | asm_snap_alloc1(as, ref); | 959 | asm_snap_alloc1(as, ref); |
940 | if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) { | 960 | if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM)) { |
941 | lua_assert(irt_type(IR(ref+1)->t) == IRT_SOFTFP); | 961 | lj_assertA(irt_type(IR(ref+1)->t) == IRT_SOFTFP, |
962 | "snap %d[%d] points to bad SOFTFP IR %04d", | ||
963 | as->snapno, n, ref - REF_BIAS); | ||
942 | asm_snap_alloc1(as, ref+1); | 964 | asm_snap_alloc1(as, ref+1); |
943 | } | 965 | } |
944 | } | 966 | } |
@@ -1002,19 +1024,20 @@ static int32_t asm_stack_adjust(ASMState *as) | |||
1002 | } | 1024 | } |
1003 | 1025 | ||
1004 | /* Must match with hash*() in lj_tab.c. */ | 1026 | /* Must match with hash*() in lj_tab.c. */ |
1005 | static uint32_t ir_khash(IRIns *ir) | 1027 | static uint32_t ir_khash(ASMState *as, IRIns *ir) |
1006 | { | 1028 | { |
1007 | uint32_t lo, hi; | 1029 | uint32_t lo, hi; |
1030 | UNUSED(as); | ||
1008 | if (irt_isstr(ir->t)) { | 1031 | if (irt_isstr(ir->t)) { |
1009 | return ir_kstr(ir)->hash; | 1032 | return ir_kstr(ir)->hash; |
1010 | } else if (irt_isnum(ir->t)) { | 1033 | } else if (irt_isnum(ir->t)) { |
1011 | lo = ir_knum(ir)->u32.lo; | 1034 | lo = ir_knum(ir)->u32.lo; |
1012 | hi = ir_knum(ir)->u32.hi << 1; | 1035 | hi = ir_knum(ir)->u32.hi << 1; |
1013 | } else if (irt_ispri(ir->t)) { | 1036 | } else if (irt_ispri(ir->t)) { |
1014 | lua_assert(!irt_isnil(ir->t)); | 1037 | lj_assertA(!irt_isnil(ir->t), "hash of nil key"); |
1015 | return irt_type(ir->t)-IRT_FALSE; | 1038 | return irt_type(ir->t)-IRT_FALSE; |
1016 | } else { | 1039 | } else { |
1017 | lua_assert(irt_isgcv(ir->t)); | 1040 | lj_assertA(irt_isgcv(ir->t), "hash of bad IR type %d", irt_type(ir->t)); |
1018 | lo = u32ptr(ir_kgc(ir)); | 1041 | lo = u32ptr(ir_kgc(ir)); |
1019 | #if LJ_GC64 | 1042 | #if LJ_GC64 |
1020 | hi = (uint32_t)(u64ptr(ir_kgc(ir)) >> 32) | (irt_toitype(ir->t) << 15); | 1043 | hi = (uint32_t)(u64ptr(ir_kgc(ir)) >> 32) | (irt_toitype(ir->t) << 15); |
@@ -1122,7 +1145,8 @@ static void asm_bufput(ASMState *as, IRIns *ir) | |||
1122 | args[0] = ir->op1; /* SBuf * */ | 1145 | args[0] = ir->op1; /* SBuf * */ |
1123 | args[1] = ir->op2; /* GCstr * */ | 1146 | args[1] = ir->op2; /* GCstr * */ |
1124 | irs = IR(ir->op2); | 1147 | irs = IR(ir->op2); |
1125 | lua_assert(irt_isstr(irs->t)); | 1148 | lj_assertA(irt_isstr(irs->t), |
1149 | "BUFPUT of non-string IR %04d", ir->op2 - REF_BIAS); | ||
1126 | if (irs->o == IR_KGC) { | 1150 | if (irs->o == IR_KGC) { |
1127 | GCstr *s = ir_kstr(irs); | 1151 | GCstr *s = ir_kstr(irs); |
1128 | if (s->len == 1) { /* Optimize put of single-char string constant. */ | 1152 | if (s->len == 1) { /* Optimize put of single-char string constant. */ |
@@ -1136,7 +1160,8 @@ static void asm_bufput(ASMState *as, IRIns *ir) | |||
1136 | args[1] = ASMREF_TMP1; /* TValue * */ | 1160 | args[1] = ASMREF_TMP1; /* TValue * */ |
1137 | ci = &lj_ir_callinfo[IRCALL_lj_strfmt_putnum]; | 1161 | ci = &lj_ir_callinfo[IRCALL_lj_strfmt_putnum]; |
1138 | } else { | 1162 | } else { |
1139 | lua_assert(irt_isinteger(IR(irs->op1)->t)); | 1163 | lj_assertA(irt_isinteger(IR(irs->op1)->t), |
1164 | "TOSTR of non-numeric IR %04d", irs->op1); | ||
1140 | args[1] = irs->op1; /* int */ | 1165 | args[1] = irs->op1; /* int */ |
1141 | if (irs->op2 == IRTOSTR_INT) | 1166 | if (irs->op2 == IRTOSTR_INT) |
1142 | ci = &lj_ir_callinfo[IRCALL_lj_strfmt_putint]; | 1167 | ci = &lj_ir_callinfo[IRCALL_lj_strfmt_putint]; |
@@ -1201,7 +1226,8 @@ static void asm_conv64(ASMState *as, IRIns *ir) | |||
1201 | IRType dt = (((ir-1)->op2 & IRCONV_DSTMASK) >> IRCONV_DSH); | 1226 | IRType dt = (((ir-1)->op2 & IRCONV_DSTMASK) >> IRCONV_DSH); |
1202 | IRCallID id; | 1227 | IRCallID id; |
1203 | IRRef args[2]; | 1228 | IRRef args[2]; |
1204 | lua_assert((ir-1)->o == IR_CONV && ir->o == IR_HIOP); | 1229 | lj_assertA((ir-1)->o == IR_CONV && ir->o == IR_HIOP, |
1230 | "not a CONV/HIOP pair at IR %04d", (int)(ir - as->ir) - REF_BIAS); | ||
1205 | args[LJ_BE] = (ir-1)->op1; | 1231 | args[LJ_BE] = (ir-1)->op1; |
1206 | args[LJ_LE] = ir->op1; | 1232 | args[LJ_LE] = ir->op1; |
1207 | if (st == IRT_NUM || st == IRT_FLOAT) { | 1233 | if (st == IRT_NUM || st == IRT_FLOAT) { |
@@ -1256,15 +1282,16 @@ static void asm_collectargs(ASMState *as, IRIns *ir, | |||
1256 | const CCallInfo *ci, IRRef *args) | 1282 | const CCallInfo *ci, IRRef *args) |
1257 | { | 1283 | { |
1258 | uint32_t n = CCI_XNARGS(ci); | 1284 | uint32_t n = CCI_XNARGS(ci); |
1259 | lua_assert(n <= CCI_NARGS_MAX*2); /* Account for split args. */ | 1285 | /* Account for split args. */ |
1286 | lj_assertA(n <= CCI_NARGS_MAX*2, "too many args %d to collect", n); | ||
1260 | if ((ci->flags & CCI_L)) { *args++ = ASMREF_L; n--; } | 1287 | if ((ci->flags & CCI_L)) { *args++ = ASMREF_L; n--; } |
1261 | while (n-- > 1) { | 1288 | while (n-- > 1) { |
1262 | ir = IR(ir->op1); | 1289 | ir = IR(ir->op1); |
1263 | lua_assert(ir->o == IR_CARG); | 1290 | lj_assertA(ir->o == IR_CARG, "malformed CALL arg tree"); |
1264 | args[n] = ir->op2 == REF_NIL ? 0 : ir->op2; | 1291 | args[n] = ir->op2 == REF_NIL ? 0 : ir->op2; |
1265 | } | 1292 | } |
1266 | args[0] = ir->op1 == REF_NIL ? 0 : ir->op1; | 1293 | args[0] = ir->op1 == REF_NIL ? 0 : ir->op1; |
1267 | lua_assert(IR(ir->op1)->o != IR_CARG); | 1294 | lj_assertA(IR(ir->op1)->o != IR_CARG, "malformed CALL arg tree"); |
1268 | } | 1295 | } |
1269 | 1296 | ||
1270 | /* Reconstruct CCallInfo flags for CALLX*. */ | 1297 | /* Reconstruct CCallInfo flags for CALLX*. */ |
@@ -1648,7 +1675,10 @@ static void asm_ir(ASMState *as, IRIns *ir) | |||
1648 | switch ((IROp)ir->o) { | 1675 | switch ((IROp)ir->o) { |
1649 | /* Miscellaneous ops. */ | 1676 | /* Miscellaneous ops. */ |
1650 | case IR_LOOP: asm_loop(as); break; | 1677 | case IR_LOOP: asm_loop(as); break; |
1651 | case IR_NOP: case IR_XBAR: lua_assert(!ra_used(ir)); break; | 1678 | case IR_NOP: case IR_XBAR: |
1679 | lj_assertA(!ra_used(ir), | ||
1680 | "IR %04d not unused", (int)(ir - as->ir) - REF_BIAS); | ||
1681 | break; | ||
1652 | case IR_USE: | 1682 | case IR_USE: |
1653 | ra_alloc1(as, ir->op1, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); break; | 1683 | ra_alloc1(as, ir->op1, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); break; |
1654 | case IR_PHI: asm_phi(as, ir); break; | 1684 | case IR_PHI: asm_phi(as, ir); break; |
@@ -1687,7 +1717,9 @@ static void asm_ir(ASMState *as, IRIns *ir) | |||
1687 | #if LJ_SOFTFP32 | 1717 | #if LJ_SOFTFP32 |
1688 | case IR_DIV: case IR_POW: case IR_ABS: | 1718 | case IR_DIV: case IR_POW: case IR_ABS: |
1689 | case IR_LDEXP: case IR_FPMATH: case IR_TOBIT: | 1719 | case IR_LDEXP: case IR_FPMATH: case IR_TOBIT: |
1690 | lua_assert(0); /* Unused for LJ_SOFTFP32. */ | 1720 | /* Unused for LJ_SOFTFP32. */ |
1721 | lj_assertA(0, "IR %04d with unused op %d", | ||
1722 | (int)(ir - as->ir) - REF_BIAS, ir->o); | ||
1691 | break; | 1723 | break; |
1692 | #else | 1724 | #else |
1693 | case IR_DIV: asm_div(as, ir); break; | 1725 | case IR_DIV: asm_div(as, ir); break; |
@@ -1736,7 +1768,8 @@ static void asm_ir(ASMState *as, IRIns *ir) | |||
1736 | #if LJ_HASFFI | 1768 | #if LJ_HASFFI |
1737 | asm_cnew(as, ir); | 1769 | asm_cnew(as, ir); |
1738 | #else | 1770 | #else |
1739 | lua_assert(0); | 1771 | lj_assertA(0, "IR %04d with unused op %d", |
1772 | (int)(ir - as->ir) - REF_BIAS, ir->o); | ||
1740 | #endif | 1773 | #endif |
1741 | break; | 1774 | break; |
1742 | 1775 | ||
@@ -1814,8 +1847,10 @@ static void asm_head_side(ASMState *as) | |||
1814 | for (i = as->stopins; i > REF_BASE; i--) { | 1847 | for (i = as->stopins; i > REF_BASE; i--) { |
1815 | IRIns *ir = IR(i); | 1848 | IRIns *ir = IR(i); |
1816 | RegSP rs; | 1849 | RegSP rs; |
1817 | lua_assert((ir->o == IR_SLOAD && (ir->op2 & IRSLOAD_PARENT)) || | 1850 | lj_assertA((ir->o == IR_SLOAD && (ir->op2 & IRSLOAD_PARENT)) || |
1818 | (LJ_SOFTFP && ir->o == IR_HIOP) || ir->o == IR_PVAL); | 1851 | (LJ_SOFTFP && ir->o == IR_HIOP) || ir->o == IR_PVAL, |
1852 | "IR %04d has bad parent op %d", | ||
1853 | (int)(ir - as->ir) - REF_BIAS, ir->o); | ||
1819 | rs = as->parentmap[i - REF_FIRST]; | 1854 | rs = as->parentmap[i - REF_FIRST]; |
1820 | if (ra_hasreg(ir->r)) { | 1855 | if (ra_hasreg(ir->r)) { |
1821 | rset_clear(allow, ir->r); | 1856 | rset_clear(allow, ir->r); |
@@ -2074,7 +2109,7 @@ static void asm_setup_regsp(ASMState *as) | |||
2074 | ir = IR(REF_FIRST); | 2109 | ir = IR(REF_FIRST); |
2075 | if (as->parent) { | 2110 | if (as->parent) { |
2076 | uint16_t *p; | 2111 | uint16_t *p; |
2077 | lastir = lj_snap_regspmap(as->parent, as->J->exitno, ir); | 2112 | lastir = lj_snap_regspmap(as->J, as->parent, as->J->exitno, ir); |
2078 | if (lastir - ir > LJ_MAX_JSLOTS) | 2113 | if (lastir - ir > LJ_MAX_JSLOTS) |
2079 | lj_trace_err(as->J, LJ_TRERR_NYICOAL); | 2114 | lj_trace_err(as->J, LJ_TRERR_NYICOAL); |
2080 | as->stopins = (IRRef)((lastir-1) - as->ir); | 2115 | as->stopins = (IRRef)((lastir-1) - as->ir); |
@@ -2378,7 +2413,10 @@ void lj_asm_trace(jit_State *J, GCtrace *T) | |||
2378 | /* Assemble a trace in linear backwards order. */ | 2413 | /* Assemble a trace in linear backwards order. */ |
2379 | for (as->curins--; as->curins > as->stopins; as->curins--) { | 2414 | for (as->curins--; as->curins > as->stopins; as->curins--) { |
2380 | IRIns *ir = IR(as->curins); | 2415 | IRIns *ir = IR(as->curins); |
2381 | lua_assert(!(LJ_32 && irt_isint64(ir->t))); /* Handled by SPLIT. */ | 2416 | /* 64 bit types handled by SPLIT for 32 bit archs. */ |
2417 | lj_assertA(!(LJ_32 && irt_isint64(ir->t)), | ||
2418 | "IR %04d has unsplit 64 bit type", | ||
2419 | (int)(ir - as->ir) - REF_BIAS); | ||
2382 | if (!ra_used(ir) && !ir_sideeff(ir) && (as->flags & JIT_F_OPT_DCE)) | 2420 | if (!ra_used(ir) && !ir_sideeff(ir) && (as->flags & JIT_F_OPT_DCE)) |
2383 | continue; /* Dead-code elimination can be soooo easy. */ | 2421 | continue; /* Dead-code elimination can be soooo easy. */ |
2384 | if (irt_isguard(ir->t)) | 2422 | if (irt_isguard(ir->t)) |
@@ -2408,7 +2446,7 @@ void lj_asm_trace(jit_State *J, GCtrace *T) | |||
2408 | asm_phi_fixup(as); | 2446 | asm_phi_fixup(as); |
2409 | 2447 | ||
2410 | if (J->curfinal->nins >= T->nins) { /* IR didn't grow? */ | 2448 | if (J->curfinal->nins >= T->nins) { /* IR didn't grow? */ |
2411 | lua_assert(J->curfinal->nk == T->nk); | 2449 | lj_assertA(J->curfinal->nk == T->nk, "unexpected IR constant growth"); |
2412 | memcpy(J->curfinal->ir + as->orignins, T->ir + as->orignins, | 2450 | memcpy(J->curfinal->ir + as->orignins, T->ir + as->orignins, |
2413 | (T->nins - as->orignins) * sizeof(IRIns)); /* Copy RENAMEs. */ | 2451 | (T->nins - as->orignins) * sizeof(IRIns)); /* Copy RENAMEs. */ |
2414 | T->nins = J->curfinal->nins; | 2452 | T->nins = J->curfinal->nins; |