diff options
Diffstat (limited to 'src/buildvm_x86.dasc')
-rw-r--r-- | src/buildvm_x86.dasc | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/buildvm_x86.dasc b/src/buildvm_x86.dasc index 6ac2646c..e9ecc2c2 100644 --- a/src/buildvm_x86.dasc +++ b/src/buildvm_x86.dasc | |||
@@ -4576,6 +4576,109 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop, int cmov, int sse) | |||
4576 | | ins_call | 4576 | | ins_call |
4577 | break; | 4577 | break; |
4578 | 4578 | ||
4579 | case BC_ITERN: | ||
4580 | | ins_A // RA = base, (RB = nresults+1 (2+1), RC = nargs+1 (2+1)) | ||
4581 | #if LJ_HASJIT | ||
4582 | | // NYI: add hotloop, record BC_ITERN. | ||
4583 | #endif | ||
4584 | | mov TMP1, KBASE // Need two more free registers. | ||
4585 | | mov TMP2, DISPATCH | ||
4586 | | mov TAB:RB, [BASE+RA*8-16] | ||
4587 | | mov RC, [BASE+RA*8-8] // Get index from control var. | ||
4588 | | mov DISPATCH, TAB:RB->asize | ||
4589 | | add PC, 4 | ||
4590 | | mov KBASE, TAB:RB->array | ||
4591 | |1: // Traverse array part. | ||
4592 | | cmp RC, DISPATCH; jae >5 // Index points after array part? | ||
4593 | | cmp dword [KBASE+RC*8+4], LJ_TNIL; je >4 | ||
4594 | if (sse) { | ||
4595 | | cvtsi2sd xmm0, RC | ||
4596 | } else { | ||
4597 | | fild dword [BASE+RA*8-8] | ||
4598 | } | ||
4599 | | // Copy array slot to returned value. | ||
4600 | |.if X64 | ||
4601 | | mov RBa, [KBASE+RC*8] | ||
4602 | | mov [BASE+RA*8+8], RBa | ||
4603 | |.else | ||
4604 | | mov RB, [KBASE+RC*8+4] | ||
4605 | | mov [BASE+RA*8+12], RB | ||
4606 | | mov RB, [KBASE+RC*8] | ||
4607 | | mov [BASE+RA*8+8], RB | ||
4608 | |.endif | ||
4609 | | add RC, 1 | ||
4610 | | // Return array index as a numeric key. | ||
4611 | if (sse) { | ||
4612 | | movsd qword [BASE+RA*8], xmm0 | ||
4613 | } else { | ||
4614 | | fstp qword [BASE+RA*8] | ||
4615 | } | ||
4616 | | mov [BASE+RA*8-8], RC // Update control var. | ||
4617 | |2: | ||
4618 | | movzx RD, PC_RD // Get target from ITERL. | ||
4619 | | branchPC RD | ||
4620 | |3: | ||
4621 | | mov DISPATCH, TMP2 | ||
4622 | | mov KBASE, TMP1 | ||
4623 | | ins_next | ||
4624 | | | ||
4625 | |4: // Skip holes in array part. | ||
4626 | | add RC, 1 | ||
4627 | if (!sse) { | ||
4628 | | mov [BASE+RA*8-8], RC | ||
4629 | } | ||
4630 | | jmp <1 | ||
4631 | | | ||
4632 | |5: // Traverse hash part. | ||
4633 | | sub RC, DISPATCH | ||
4634 | |6: | ||
4635 | | cmp RC, TAB:RB->hmask; ja <3 // End of iteration? Branch to ITERL+1. | ||
4636 | | imul KBASE, RC, #NODE | ||
4637 | | add NODE:KBASE, TAB:RB->node | ||
4638 | | cmp dword NODE:KBASE->val.it, LJ_TNIL; je >7 | ||
4639 | | lea DISPATCH, [RC+DISPATCH+1] | ||
4640 | | // Copy key and value from hash slot. | ||
4641 | |.if X64 | ||
4642 | | mov RBa, NODE:KBASE->key | ||
4643 | | mov RCa, NODE:KBASE->val | ||
4644 | | mov [BASE+RA*8], RBa | ||
4645 | | mov [BASE+RA*8+8], RCa | ||
4646 | |.else | ||
4647 | | mov RB, NODE:KBASE->key.gcr | ||
4648 | | mov RC, NODE:KBASE->key.it | ||
4649 | | mov [BASE+RA*8], RB | ||
4650 | | mov [BASE+RA*8+4], RC | ||
4651 | | mov RB, NODE:KBASE->val.gcr | ||
4652 | | mov RC, NODE:KBASE->val.it | ||
4653 | | mov [BASE+RA*8+8], RB | ||
4654 | | mov [BASE+RA*8+12], RC | ||
4655 | |.endif | ||
4656 | | mov [BASE+RA*8-8], DISPATCH | ||
4657 | | jmp <2 | ||
4658 | | | ||
4659 | |7: // Skip holes in hash part. | ||
4660 | | add RC, 1 | ||
4661 | | jmp <6 | ||
4662 | break; | ||
4663 | |||
4664 | case BC_ISNEXT: | ||
4665 | | ins_AD // RA = base, RD = target (points to ITERN) | ||
4666 | | cmp dword [BASE+RA*8-20], LJ_TFUNC; jne >5 | ||
4667 | | mov CFUNC:RB, [BASE+RA*8-24] | ||
4668 | | cmp dword [BASE+RA*8-12], LJ_TTAB; jne >5 | ||
4669 | | cmp dword [BASE+RA*8-4], LJ_TNIL; jne >5 | ||
4670 | | cmp byte CFUNC:RB->ffid, FF_next_N; jne >5 | ||
4671 | | branchPC RD | ||
4672 | | mov dword [BASE+RA*8-8], 0 // Initialize control var. | ||
4673 | |1: | ||
4674 | | ins_next | ||
4675 | |5: // Despecialize bytecode if any of the checks fail. | ||
4676 | | mov PC_OP, BC_JMP | ||
4677 | | branchPC RD | ||
4678 | | mov byte [PC], BC_ITERC | ||
4679 | | jmp <1 | ||
4680 | break; | ||
4681 | |||
4579 | case BC_VARG: | 4682 | case BC_VARG: |
4580 | | ins_ABC // RA = base, RB = nresults+1, RC = numparams | 4683 | | ins_ABC // RA = base, RB = nresults+1, RC = numparams |
4581 | | mov TMP1, KBASE // Need one more free register. | 4684 | | mov TMP1, KBASE // Need one more free register. |