PPC: Add getmetatable(), setmetatable() and rawget() fast functions.

This commit is contained in:
Mike Pall 2010-10-05 01:41:51 +02:00
parent 8b096c5d08
commit 08ac8b0c96

View File

@ -240,6 +240,7 @@
|.macro checkok, label; blt label; .endmacro
|.macro checkfail, label; bge label; .endmacro
|.macro checkanyfail, label; bns label; .endmacro
|.macro checkallok, label; bso label; .endmacro
|.endif
|
|.macro branch_RD
@ -950,13 +951,80 @@ static void build_subroutines(BuildCtx *ctx)
|//-- Base library: getters and setters ---------------------------------
|
|.ffunc_1 getmetatable
| NYI
| checktab CARG1
| evmergehi TMP1, CARG1, CARG1
| checkfail >6
|1: // Field metatable must be at same offset for GCtab and GCudata!
| lwz TAB:RB, TAB:CARG1->metatable
|2:
| evmr CRET1, TISNIL
| cmplwi TAB:RB, 0
| lwz STR:RC, DISPATCH_GL(gcroot[GCROOT_MMNAME+MM_metatable])(DISPATCH)
| beq ->fff_restv
| lwz TMP0, TAB:RB->hmask
| evmergelo CRET1, TISTAB, TAB:RB // Use metatable as default result.
| lwz TMP1, STR:RC->hash
| lwz NODE:TMP2, TAB:RB->node
| evmergelo STR:RC, TISSTR, STR:RC
| and TMP1, TMP1, TMP0 // idx = str->hash & tab->hmask
| slwi TMP0, TMP1, 5
| slwi TMP1, TMP1, 3
| sub TMP1, TMP0, TMP1
| add NODE:TMP2, NODE:TMP2, TMP1 // node = tab->node + (idx*32-idx*8)
|3: // Rearranged logic, because we expect _not_ to find the key.
| evldd TMP0, NODE:TMP2->key
| evldd TMP1, NODE:TMP2->val
| evcmpeq TMP0, STR:RC
| lwz NODE:TMP2, NODE:TMP2->next
| checkallok >5
| cmplwi NODE:TMP2, 0
| beq ->fff_restv // Not found, keep default result.
| b <3
|5:
| checknil TMP1
| checkok ->fff_restv // Ditto for nil value.
| evmr CRET1, TMP1 // Return value of mt.__metatable.
| b ->fff_restv
|
|6:
| cmpwi TMP1, LJ_TUDATA
| not TMP1, TMP1
| beq <1
| checknum CARG1
| slwi TMP1, TMP1, 2
| li TMP2, 4*~LJ_TNUMX
| isellt TMP1, TMP2, TMP1
| la TMP2, DISPATCH_GL(gcroot[GCROOT_BASEMT])(DISPATCH)
| lwzx TAB:RB, TMP2, TMP1
| b <2
|
|.ffunc_2 setmetatable
| NYI
| // Fast path: no mt for table yet and not clearing the mt.
| evmergehi TMP0, TAB:CARG1, TAB:CARG2
| checktab TMP0
| checkanyfail ->fff_fallback
| lwz TAB:TMP1, TAB:CARG1->metatable
| cmplwi TAB:TMP1, 0
| lbz TMP3, TAB:CARG1->marked
| bne ->fff_fallback
| andi. TMP0, TMP3, LJ_GC_BLACK // isblack(table)
| stw TAB:CARG2, TAB:CARG1->metatable
| beq ->fff_restv
| barrierback TAB:CARG1, TMP3, TMP0
| b ->fff_restv
|
|.ffunc_2 rawget
| NYI
|.ffunc rawget
| cmplwi NARGS8:RC, 16
| evldd CARG2, 0(BASE)
| blt ->fff_fallback
| checktab CARG2
| la CARG3, 8(BASE)
| checkfail ->fff_fallback
| mr CARG1, L
| bl extern lj_tab_get // (lua_State *L, GCtab *t, cTValue *key)
| // Returns cTValue *.
| evldd CRET1, 0(CRET1)
| b ->fff_restv
|
|//-- Base library: conversions ------------------------------------------
|