PPC: Add metamethod handlers and continuations for comparisons.

This commit is contained in:
Mike Pall 2010-09-17 16:07:01 +02:00
parent 9dc98280d2
commit 9203d278d0

View File

@ -665,7 +665,25 @@ static void build_subroutines(BuildCtx *ctx)
|//-- Comparison metamethods --------------------------------------------- |//-- Comparison metamethods ---------------------------------------------
| |
|->vmeta_comp: |->vmeta_comp:
| NYI | mr CARG1, L
| subi PC, PC, 4
| add CARG2, BASE, RA
| stw PC, SAVE_PC
| add CARG3, BASE, RD
| stw BASE, L->base
| decode_OP1 CARG4, INS
| bl extern lj_meta_comp // (lua_State *L, TValue *o1, *o2, int op)
| // Returns 0/1 or TValue * (metamethod).
|3:
| cmplwi CRET1, 1
| bgt ->vmeta_binop
|4:
| lwz INS, 0(PC)
| addi PC, PC, 4
| decode_RD4 TMP2, INS
| addis TMP3, PC, -(BCBIAS_J*4 >> 16)
| add TMP2, TMP2, TMP3
| isellt PC, PC, TMP2
|->cont_nop: |->cont_nop:
| ins_next | ins_next
| |
@ -676,14 +694,27 @@ static void build_subroutines(BuildCtx *ctx)
| evstddx TMP0, BASE, TMP1 | evstddx TMP0, BASE, TMP1
| b ->cont_nop | b ->cont_nop
| |
|->cont_condt: |->cont_condt: // RA = resultptr
| NYI | lwz TMP0, 0(RA)
| li TMP1, LJ_TTRUE
| cmplw TMP1, TMP0 // Branch if result is true.
| b <4
| |
|->cont_condf: |->cont_condf: // RA = resultptr
| NYI | lwz TMP0, 0(RA)
| li TMP1, LJ_TFALSE
| cmplw TMP0, TMP1 // Branch if result is false.
| b <4
| |
|->vmeta_equal: |->vmeta_equal:
| NYI | // CARG2, CARG3, CARG4 are already set by BC_ISEQV/BC_ISNEV.
| subi PC, PC, 4
| stw BASE, L->base
| mr CARG1, L
| stw PC, SAVE_PC
| bl extern lj_meta_equal // (lua_State *L, GCobj *o1, *o2, int ne)
| // Returns 0/1 or TValue * (metamethod).
| b <3
| |
|//-- Arithmetic metamethods --------------------------------------------- |//-- Arithmetic metamethods ---------------------------------------------
| |
@ -1255,17 +1286,17 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
case BC_ISEQV: case BC_ISNEV: case BC_ISEQV: case BC_ISNEV:
vk = op == BC_ISEQV; vk = op == BC_ISEQV;
| // RA = src1*8, RD = src2*8, JMP with RD = target | // RA = src1*8, RD = src2*8, JMP with RD = target
| evlddx TMP0, BASE, RA | evlddx CARG2, BASE, RA
| addi PC, PC, 4 | addi PC, PC, 4
| evlddx TMP1, BASE, RD | evlddx CARG3, BASE, RD
| addis TMP3, PC, -(BCBIAS_J*4 >> 16) | addis TMP3, PC, -(BCBIAS_J*4 >> 16)
| lwz INS, -4(PC) | lwz TMP2, -4(PC)
| evmergehi RB, TMP0, TMP1 | evmergehi RB, CARG2, CARG3
| decode_RD4 TMP2, INS | decode_RD4 TMP2, TMP2
| checknum RB | checknum RB
| add TMP2, TMP2, TMP3 | add TMP2, TMP2, TMP3
| checkanyfail >5 | checkanyfail >5
| efdcmpeq TMP0, TMP1 | efdcmpeq CARG2, CARG3
if (vk) { if (vk) {
| iselgt PC, TMP2, PC | iselgt PC, TMP2, PC
} else { } else {
@ -1275,7 +1306,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
| ins_next | ins_next
| |
|5: // Either or both types are not numbers. |5: // Either or both types are not numbers.
| evcmpeq TMP0, TMP1 | evcmpeq CARG2, CARG3
| not TMP3, RB | not TMP3, RB
| cmplwi cr1, TMP3, ~LJ_TISPRI // Primitive? | cmplwi cr1, TMP3, ~LJ_TISPRI // Primitive?
| crorc 4*cr7+lt, 4*cr0+so, 4*cr0+lt // 1: Same tv or different type. | crorc 4*cr7+lt, 4*cr0+so, 4*cr0+lt // 1: Same tv or different type.
@ -1298,12 +1329,12 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
| |
| // Different tables or userdatas. Need to check __eq metamethod. | // Different tables or userdatas. Need to check __eq metamethod.
| // Field metatable must be at same offset for GCtab and GCudata! | // Field metatable must be at same offset for GCtab and GCudata!
| lwz TAB:TMP3, TAB:TMP1->metatable | lwz TAB:TMP2, TAB:CARG2->metatable
| li RB, 1-vk // ne = 0 or 1. | li CARG4, 1-vk // ne = 0 or 1.
| cmplwi TAB:TMP3, 0 | cmplwi TAB:TMP2, 0
| beq <1 // No metatable? | beq <1 // No metatable?
| lbz TMP0, TAB:TMP3->nomm | lbz TMP2, TAB:TMP2->nomm
| andi. TMP0, TMP0, 1<<MM_eq | andi. TMP2, TMP2, 1<<MM_eq
| bne <1 // Or 'no __eq' flag set? | bne <1 // Or 'no __eq' flag set?
| mr PC, SAVE0 // Restore old PC. | mr PC, SAVE0 // Restore old PC.
| b ->vmeta_equal // Handle __eq metamethod. | b ->vmeta_equal // Handle __eq metamethod.