aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-09-03 19:31:07 +0200
committerMike Pall <mike>2010-09-03 19:31:07 +0200
commit5043efae7d7a5b680127eea1b7f8c1c18360f652 (patch)
tree4ede0646aec104ff86b91d364c515f89fdd82f16 /src
parentf708d31bcc63d1d6f20cb1b1a2dc6ebf69ef41a3 (diff)
downloadluajit-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.dasc145
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