diff options
author | Mike Pall <mike> | 2010-09-03 19:35:44 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2010-09-03 19:35:44 +0200 |
commit | b4c8b05ad58364291ff6c210dd4e85bb1b5eb973 (patch) | |
tree | 658faf1799735e6af44873c46d1ead093dbe8c2a /src | |
parent | 5043efae7d7a5b680127eea1b7f8c1c18360f652 (diff) | |
download | luajit-b4c8b05ad58364291ff6c210dd4e85bb1b5eb973.tar.gz luajit-b4c8b05ad58364291ff6c210dd4e85bb1b5eb973.tar.bz2 luajit-b4c8b05ad58364291ff6c210dd4e85bb1b5eb973.zip |
PPC: Add table indexing with variable keys or uint8_t.
Diffstat (limited to 'src')
-rw-r--r-- | src/buildvm_ppc.dasc | 136 |
1 files changed, 132 insertions, 4 deletions
diff --git a/src/buildvm_ppc.dasc b/src/buildvm_ppc.dasc index 53b72156..647fe387 100644 --- a/src/buildvm_ppc.dasc +++ b/src/buildvm_ppc.dasc | |||
@@ -1250,7 +1250,43 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
1250 | break; | 1250 | break; |
1251 | 1251 | ||
1252 | case BC_TGETV: | 1252 | case BC_TGETV: |
1253 | | NYI | 1253 | | // RA = dst*8, RB = table*8, RC = key*8 |
1254 | | evlddx TAB:RB, BASE, RB | ||
1255 | | evlddx RC, BASE, RC | ||
1256 | | checktab TAB:RB | ||
1257 | | checkfail ->vmeta_tgetv | ||
1258 | | checknum RC | ||
1259 | | checkfail >5 | ||
1260 | | // Convert number key to integer | ||
1261 | | efdctsi TMP2, RC | ||
1262 | | lwz TMP0, TAB:RB->asize | ||
1263 | | efdcfsi TMP1, TMP2 | ||
1264 | | cmplw cr0, TMP0, TMP2 | ||
1265 | | efdcmpeq cr1, RC, TMP1 | ||
1266 | | lwz TMP1, TAB:RB->array | ||
1267 | | crand 4*cr0+gt, 4*cr0+gt, 4*cr1+gt | ||
1268 | | slwi TMP2, TMP2, 3 | ||
1269 | | ble ->vmeta_tgetv // Integer key and in array part? | ||
1270 | | evlddx TMP1, TMP1, TMP2 | ||
1271 | | checknil TMP1 | ||
1272 | | checkok >2 | ||
1273 | |1: | ||
1274 | | evstddx TMP1, BASE, RA | ||
1275 | | ins_next | ||
1276 | | | ||
1277 | |2: // Check for __index if table value is nil. | ||
1278 | | lwz TAB:TMP2, TAB:RB->metatable | ||
1279 | | cmpwi TAB:TMP2, 0 | ||
1280 | | beq <1 // No metatable: done. | ||
1281 | | lbz TMP0, TAB:TMP2->nomm | ||
1282 | | andi. TMP0, TMP0, 1<<MM_index | ||
1283 | | bne <1 // 'no __index' flag set: done. | ||
1284 | | b ->vmeta_tgetv | ||
1285 | | | ||
1286 | |5: | ||
1287 | | checkstr STR:RC // String key? | ||
1288 | | checkok ->BC_TGETS_Z | ||
1289 | | b ->vmeta_tgetv | ||
1254 | break; | 1290 | break; |
1255 | case BC_TGETS: | 1291 | case BC_TGETS: |
1256 | | // RA = dst*8, RB = table*8, RC = str_const*8 (~) | 1292 | | // RA = dst*8, RB = table*8, RC = str_const*8 (~) |
@@ -1299,11 +1335,71 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
1299 | | b ->vmeta_tgets | 1335 | | b ->vmeta_tgets |
1300 | break; | 1336 | break; |
1301 | case BC_TGETB: | 1337 | case BC_TGETB: |
1302 | | NYI | 1338 | | // RA = dst*8, RB = table*8, RC = index*8 |
1339 | | evlddx TAB:RB, BASE, RB | ||
1340 | | srwi TMP0, RC, 3 | ||
1341 | | checktab TAB:RB | ||
1342 | | checkfail ->vmeta_tgetb | ||
1343 | | lwz TMP1, TAB:RB->asize | ||
1344 | | lwz TMP2, TAB:RB->array | ||
1345 | | cmplw TMP0, TMP1 | ||
1346 | | bge ->vmeta_tgetb | ||
1347 | | evlddx TMP1, TMP2, RC | ||
1348 | | checknil TMP1 | ||
1349 | | checkok >5 | ||
1350 | |1: | ||
1351 | | evstddx TMP1, BASE, RA | ||
1352 | | ins_next | ||
1353 | | | ||
1354 | |5: // Check for __index if table value is nil. | ||
1355 | | lwz TAB:TMP2, TAB:RB->metatable | ||
1356 | | cmpwi TAB:TMP2, 0 | ||
1357 | | beq <1 // No metatable: done. | ||
1358 | | lbz TMP2, TAB:TMP2->nomm | ||
1359 | | andi. TMP2, TMP2, 1<<MM_index | ||
1360 | | bne <1 // 'no __index' flag set: done. | ||
1361 | | b ->vmeta_tgetb // Caveat: preserve TMP0! | ||
1303 | break; | 1362 | break; |
1304 | 1363 | ||
1305 | case BC_TSETV: | 1364 | case BC_TSETV: |
1306 | | NYI | 1365 | | // RA = src*8, RB = table*8, RC = key*8 |
1366 | | evlddx TAB:RB, BASE, RB | ||
1367 | | evlddx RC, BASE, RC | ||
1368 | | checktab TAB:RB | ||
1369 | | checkfail ->vmeta_tsetv | ||
1370 | | checknum RC | ||
1371 | | checkfail >5 | ||
1372 | | // Convert number key to integer | ||
1373 | | efdctsi TMP2, RC | ||
1374 | | evlddx SAVE0, BASE, RA | ||
1375 | | lwz TMP0, TAB:RB->asize | ||
1376 | | efdcfsi TMP1, TMP2 | ||
1377 | | cmplw cr0, TMP0, TMP2 | ||
1378 | | efdcmpeq cr1, RC, TMP1 | ||
1379 | | lwz TMP1, TAB:RB->array | ||
1380 | | crand 4*cr0+gt, 4*cr0+gt, 4*cr1+gt | ||
1381 | | slwi TMP2, TMP2, 3 | ||
1382 | | ble ->vmeta_tsetv // Integer key and in array part? | ||
1383 | | evlddx TMP0, TMP1, TMP2 | ||
1384 | | checknil TMP0 | ||
1385 | | checkok >2 | ||
1386 | |1: | ||
1387 | | evstddx SAVE0, TMP1, TMP2 | ||
1388 | | ins_next | ||
1389 | | | ||
1390 | |2: // Check for __newindex if previous value is nil. | ||
1391 | | lwz TAB:TMP3, TAB:RB->metatable | ||
1392 | | cmpwi TAB:TMP3, 0 | ||
1393 | | beq <1 // No metatable: done. | ||
1394 | | lbz TMP0, TAB:TMP3->nomm | ||
1395 | | andi. TMP0, TMP0, 1<<MM_newindex | ||
1396 | | bne <1 // 'no __newindex' flag set: done. | ||
1397 | | b ->vmeta_tsetv | ||
1398 | | | ||
1399 | |5: | ||
1400 | | checkstr STR:RC // String key? | ||
1401 | | checkok ->BC_TSETS_Z | ||
1402 | | b ->vmeta_tsetv | ||
1307 | break; | 1403 | break; |
1308 | case BC_TSETS: | 1404 | case BC_TSETS: |
1309 | | // RA = src*8, RB = table*8, RC = str_const*8 (~) | 1405 | | // RA = src*8, RB = table*8, RC = str_const*8 (~) |
@@ -1382,7 +1478,39 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
1382 | | b <3 | 1478 | | b <3 |
1383 | break; | 1479 | break; |
1384 | case BC_TSETB: | 1480 | case BC_TSETB: |
1385 | | NYI | 1481 | | // RA = src*8, RB = table*8, RC = index*8 |
1482 | | evlddx TAB:RB, BASE, RB | ||
1483 | | srwi TMP0, RC, 3 | ||
1484 | | checktab TAB:RB | ||
1485 | | checkfail ->vmeta_tsetb | ||
1486 | | lwz TMP1, TAB:RB->asize | ||
1487 | | lwz TMP2, TAB:RB->array | ||
1488 | | lbz TMP3, TAB:RB->marked | ||
1489 | | cmplw TMP0, TMP1 | ||
1490 | | evlddx SAVE0, BASE, RA | ||
1491 | | bge ->vmeta_tsetb | ||
1492 | | evlddx TMP1, TMP2, RC | ||
1493 | | checknil TMP1 | ||
1494 | | checkok >5 | ||
1495 | |1: | ||
1496 | | andi. TMP0, TMP3, LJ_GC_BLACK // isblack(table) | ||
1497 | | evstddx SAVE0, TMP2, RC | ||
1498 | | bne >7 | ||
1499 | |2: | ||
1500 | | ins_next | ||
1501 | | | ||
1502 | |5: // Check for __newindex if previous value is nil. | ||
1503 | | lwz TAB:TMP1, TAB:RB->metatable | ||
1504 | | cmpwi TAB:TMP1, 0 | ||
1505 | | beq <1 // No metatable: done. | ||
1506 | | lbz TMP1, TAB:TMP1->nomm | ||
1507 | | andi. TMP1, TMP1, 1<<MM_newindex | ||
1508 | | bne <1 // 'no __newindex' flag set: done. | ||
1509 | | b ->vmeta_tsetb // Caveat: preserve TMP0! | ||
1510 | | | ||
1511 | |7: // Possible table write barrier for the value. Skip valiswhite check. | ||
1512 | | barrierback TAB:RB, TMP3, TMP0 | ||
1513 | | b <2 | ||
1386 | break; | 1514 | break; |
1387 | 1515 | ||
1388 | case BC_TSETM: | 1516 | case BC_TSETM: |