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: |
