diff options
author | Mike Pall <mike> | 2010-09-03 19:31:07 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2010-09-03 19:31:07 +0200 |
commit | 5043efae7d7a5b680127eea1b7f8c1c18360f652 (patch) | |
tree | 4ede0646aec104ff86b91d364c515f89fdd82f16 /src | |
parent | f708d31bcc63d1d6f20cb1b1a2dc6ebf69ef41a3 (diff) | |
download | luajit-5043efae7d7a5b680127eea1b7f8c1c18360f652.tar.gz luajit-5043efae7d7a5b680127eea1b7f8c1c18360f652.tar.bz2 luajit-5043efae7d7a5b680127eea1b7f8c1c18360f652.zip |
PPC: Add table indexing with string keys. Add get/set global.
Diffstat (limited to 'src')
-rw-r--r-- | src/buildvm_ppc.dasc | 145 |
1 files changed, 142 insertions, 3 deletions
diff --git a/src/buildvm_ppc.dasc b/src/buildvm_ppc.dasc index f4452ee9..53b72156 100644 --- a/src/buildvm_ppc.dasc +++ b/src/buildvm_ppc.dasc | |||
@@ -247,6 +247,16 @@ | |||
247 | |.macro li_vmstate, st; li TMP0, ~LJ_VMST_..st; .endmacro | 247 | |.macro li_vmstate, st; li TMP0, ~LJ_VMST_..st; .endmacro |
248 | |.macro st_vmstate; stw TMP0, DISPATCH_GL(vmstate)(DISPATCH); .endmacro | 248 | |.macro st_vmstate; stw TMP0, DISPATCH_GL(vmstate)(DISPATCH); .endmacro |
249 | | | 249 | | |
250 | |// Move table write barrier back. Overwrites mark and tmp. | ||
251 | |.macro barrierback, tab, mark, tmp | ||
252 | | lwz tmp, DISPATCH_GL(gc.grayagain)(DISPATCH) | ||
253 | | // Assumes LJ_GC_BLACK is 0x04. | ||
254 | | rlwinm mark, mark, 0, 30, 28 // black2gray(tab) | ||
255 | | stw tab, DISPATCH_GL(gc.grayagain)(DISPATCH) | ||
256 | | stb mark, tab->marked | ||
257 | | stw tmp, tab->gclist | ||
258 | |.endmacro | ||
259 | | | ||
250 | |//----------------------------------------------------------------------- | 260 | |//----------------------------------------------------------------------- |
251 | 261 | ||
252 | /* Generate subroutines used by opcodes and other parts of the VM. */ | 262 | /* Generate subroutines used by opcodes and other parts of the VM. */ |
@@ -500,6 +510,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
500 | | | 510 | | |
501 | |//-- Table indexing metamethods ----------------------------------------- | 511 | |//-- Table indexing metamethods ----------------------------------------- |
502 | | | 512 | | |
513 | |->vmeta_tgets1: | ||
503 | |->vmeta_tgets: | 514 | |->vmeta_tgets: |
504 | | NYI | 515 | | NYI |
505 | | | 516 | | |
@@ -511,6 +522,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
511 | | | 522 | | |
512 | |//----------------------------------------------------------------------- | 523 | |//----------------------------------------------------------------------- |
513 | | | 524 | | |
525 | |->vmeta_tsets1: | ||
514 | |->vmeta_tsets: | 526 | |->vmeta_tsets: |
515 | | NYI | 527 | | NYI |
516 | | | 528 | | |
@@ -1222,15 +1234,69 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
1222 | break; | 1234 | break; |
1223 | 1235 | ||
1224 | case BC_GGET: | 1236 | case BC_GGET: |
1237 | | // RA = dst*8, RD = str_const*8 (~) | ||
1225 | case BC_GSET: | 1238 | case BC_GSET: |
1226 | | NYI | 1239 | | // RA = src*8, RD = str_const*8 (~) |
1240 | | lwz LFUNC:TMP2, FRAME_FUNC(BASE) | ||
1241 | | srwi TMP1, RD, 1 | ||
1242 | | lwz TAB:RB, LFUNC:TMP2->env | ||
1243 | | subfic TMP1, TMP1, -4 | ||
1244 | | lwzx STR:RC, KBASE, TMP1 // KBASE-4-str_const*4 | ||
1245 | if (op == BC_GGET) { | ||
1246 | | b ->BC_TGETS_Z | ||
1247 | } else { | ||
1248 | | b ->BC_TSETS_Z | ||
1249 | } | ||
1227 | break; | 1250 | break; |
1228 | 1251 | ||
1229 | case BC_TGETV: | 1252 | case BC_TGETV: |
1230 | | NYI | 1253 | | NYI |
1231 | break; | 1254 | break; |
1232 | case BC_TGETS: | 1255 | case BC_TGETS: |
1233 | | NYI | 1256 | | // RA = dst*8, RB = table*8, RC = str_const*8 (~) |
1257 | | evlddx TAB:RB, BASE, RB | ||
1258 | | srwi TMP1, RC, 1 | ||
1259 | | checktab TAB:RB | ||
1260 | | subfic TMP1, TMP1, -4 | ||
1261 | | lwzx STR:RC, KBASE, TMP1 // KBASE-4-str_const*4 | ||
1262 | | checkfail ->vmeta_tgets1 | ||
1263 | |->BC_TGETS_Z: | ||
1264 | | // TAB:RB = GCtab *, STR:RC = GCstr *, RA = dst*8 | ||
1265 | | lwz TMP0, TAB:RB->hmask | ||
1266 | | lwz TMP1, STR:RC->hash | ||
1267 | | lwz NODE:TMP2, TAB:RB->node | ||
1268 | | evmergelo STR:RC, TISSTR, STR:RC | ||
1269 | | and TMP1, TMP1, TMP0 // idx = str->hash & tab->hmask | ||
1270 | | slwi TMP0, TMP1, 5 | ||
1271 | | slwi TMP1, TMP1, 3 | ||
1272 | | sub TMP1, TMP0, TMP1 | ||
1273 | | add NODE:TMP2, NODE:TMP2, TMP1 // node = tab->node + (idx*32-idx*8) | ||
1274 | |1: | ||
1275 | | evldd TMP0, NODE:TMP2->key | ||
1276 | | evldd TMP1, NODE:TMP2->val | ||
1277 | | evcmpeq TMP0, STR:RC | ||
1278 | | checkanyfail >4 | ||
1279 | | checknil TMP1 | ||
1280 | | checkok >5 // Key found, but nil value? | ||
1281 | |3: | ||
1282 | | evstddx TMP1, BASE, RA | ||
1283 | | ins_next | ||
1284 | | | ||
1285 | |4: // Follow hash chain. | ||
1286 | | lwz NODE:TMP2, NODE:TMP2->next | ||
1287 | | cmpwi NODE:TMP2, 0 | ||
1288 | | bne <1 | ||
1289 | | // End of hash chain: key not found, nil result. | ||
1290 | | evmr TMP1, TISNIL | ||
1291 | | | ||
1292 | |5: // Check for __index if table value is nil. | ||
1293 | | lwz TAB:TMP2, TAB:RB->metatable | ||
1294 | | cmpwi TAB:TMP2, 0 | ||
1295 | | beq <3 // No metatable: done. | ||
1296 | | lbz TMP0, TAB:TMP2->nomm | ||
1297 | | andi. TMP0, TMP0, 1<<MM_index | ||
1298 | | bne <3 // 'no __index' flag set: done. | ||
1299 | | b ->vmeta_tgets | ||
1234 | break; | 1300 | break; |
1235 | case BC_TGETB: | 1301 | case BC_TGETB: |
1236 | | NYI | 1302 | | NYI |
@@ -1240,7 +1306,80 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
1240 | | NYI | 1306 | | NYI |
1241 | break; | 1307 | break; |
1242 | case BC_TSETS: | 1308 | case BC_TSETS: |
1243 | | NYI | 1309 | | // RA = src*8, RB = table*8, RC = str_const*8 (~) |
1310 | | evlddx TAB:RB, BASE, RB | ||
1311 | | srwi TMP1, RC, 1 | ||
1312 | | checktab TAB:RB | ||
1313 | | subfic TMP1, TMP1, -4 | ||
1314 | | lwzx STR:RC, KBASE, TMP1 // KBASE-4-str_const*4 | ||
1315 | | checkfail ->vmeta_tsets1 | ||
1316 | |->BC_TSETS_Z: | ||
1317 | | // TAB:RB = GCtab *, STR:RC = GCstr *, RA = src*8 | ||
1318 | | lwz TMP0, TAB:RB->hmask | ||
1319 | | lwz TMP1, STR:RC->hash | ||
1320 | | lwz NODE:TMP2, TAB:RB->node | ||
1321 | | li TMP3, 0 | ||
1322 | | evmergelo STR:RC, TISSTR, STR:RC | ||
1323 | | stb TMP3, TAB:RB->nomm // Clear metamethod cache. | ||
1324 | | and TMP1, TMP1, TMP0 // idx = str->hash & tab->hmask | ||
1325 | | evlddx SAVE0, BASE, RA | ||
1326 | | slwi TMP0, TMP1, 5 | ||
1327 | | slwi TMP1, TMP1, 3 | ||
1328 | | sub TMP1, TMP0, TMP1 | ||
1329 | | lbz TMP3, TAB:RB->marked | ||
1330 | | add NODE:TMP2, NODE:TMP2, TMP1 // node = tab->node + (idx*32-idx*8) | ||
1331 | |1: | ||
1332 | | evldd TMP0, NODE:TMP2->key | ||
1333 | | evldd TMP1, NODE:TMP2->val | ||
1334 | | evcmpeq TMP0, STR:RC | ||
1335 | | checkanyfail >5 | ||
1336 | | checknil TMP1 | ||
1337 | | checkok >4 // Key found, but nil value? | ||
1338 | |2: | ||
1339 | | andi. TMP0, TMP3, LJ_GC_BLACK // isblack(table) | ||
1340 | | evstdd SAVE0, NODE:TMP2->val | ||
1341 | | bne >7 | ||
1342 | |3: | ||
1343 | | ins_next | ||
1344 | | | ||
1345 | |4: // Check for __newindex if previous value is nil. | ||
1346 | | lwz TAB:TMP1, TAB:RB->metatable | ||
1347 | | cmpwi TAB:TMP1, 0 | ||
1348 | | beq <2 // No metatable: done. | ||
1349 | | lbz TMP0, TAB:TMP1->nomm | ||
1350 | | andi. TMP0, TMP0, 1<<MM_newindex | ||
1351 | | bne <2 // 'no __newindex' flag set: done. | ||
1352 | | b ->vmeta_tsets | ||
1353 | | | ||
1354 | |5: // Follow hash chain. | ||
1355 | | lwz NODE:TMP2, NODE:TMP2->next | ||
1356 | | cmpwi NODE:TMP2, 0 | ||
1357 | | bne <1 | ||
1358 | | // End of hash chain: key not found, add a new one. | ||
1359 | | | ||
1360 | | // But check for __newindex first. | ||
1361 | | lwz TAB:TMP1, TAB:RB->metatable | ||
1362 | | la CARG3, DISPATCH_GL(tmptv)(DISPATCH) | ||
1363 | | stw PC, SAVE_PC | ||
1364 | | mr CARG1, L | ||
1365 | | cmpwi TAB:TMP1, 0 | ||
1366 | | stw BASE, L->base | ||
1367 | | beq >6 // No metatable: continue. | ||
1368 | | lbz TMP0, TAB:TMP1->nomm | ||
1369 | | andi. TMP0, TMP0, 1<<MM_newindex | ||
1370 | | beq ->vmeta_tsets // 'no __newindex' flag NOT set: check. | ||
1371 | |6: | ||
1372 | | mr CARG2, TAB:RB | ||
1373 | | evstdd STR:RC, 0(CARG3) | ||
1374 | | bl extern lj_tab_newkey // (lua_State *L, GCtab *t, TValue *k) | ||
1375 | | // Returns TValue *. | ||
1376 | | lwz BASE, L->base | ||
1377 | | evstdd SAVE0, 0(CRET1) | ||
1378 | | b <3 // No 2nd write barrier needed. | ||
1379 | | | ||
1380 | |7: // Possible table write barrier for the value. Skip valiswhite check. | ||
1381 | | barrierback TAB:RB, TMP3, TMP0 | ||
1382 | | b <3 | ||
1244 | break; | 1383 | break; |
1245 | case BC_TSETB: | 1384 | case BC_TSETB: |
1246 | | NYI | 1385 | | NYI |