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