diff options
| author | Mike Pall <mike> | 2011-03-30 21:54:33 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2011-03-30 21:54:33 +0200 |
| commit | a0e47110556130957f261ede57383d3a3eb73d52 (patch) | |
| tree | 38be95c9520cb61f2292f264096555b7b54716d0 /src | |
| parent | 7b0a125cf76e67df2f1e43f8e3ac4ca08851a7b3 (diff) | |
| download | luajit-a0e47110556130957f261ede57383d3a3eb73d52.tar.gz luajit-a0e47110556130957f261ede57383d3a3eb73d52.tar.bz2 luajit-a0e47110556130957f261ede57383d3a3eb73d52.zip | |
ARM: Add basic loop and branch instructions.
Diffstat (limited to 'src')
| -rw-r--r-- | src/buildvm_arm.dasc | 139 |
1 files changed, 134 insertions, 5 deletions
diff --git a/src/buildvm_arm.dasc b/src/buildvm_arm.dasc index 0389e6ce..cec04893 100644 --- a/src/buildvm_arm.dasc +++ b/src/buildvm_arm.dasc | |||
| @@ -462,7 +462,24 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 462 | |//-- Argument coercion for 'for' statement ------------------------------ | 462 | |//-- Argument coercion for 'for' statement ------------------------------ |
| 463 | | | 463 | | |
| 464 | |->vmeta_for: | 464 | |->vmeta_for: |
| 465 | | NYI | 465 | | mov CARG1, L |
| 466 | | str BASE, L->base | ||
| 467 | | mov CARG2, RA | ||
| 468 | | str PC, SAVE_PC | ||
| 469 | | bl extern lj_meta_for // (lua_State *L, TValue *base) | ||
| 470 | #if LJ_HASJIT | ||
| 471 | | ldrb OP, [PC, #-4] | ||
| 472 | #endif | ||
| 473 | | ldr INS, [PC, #-4] | ||
| 474 | #if LJ_HASJIT | ||
| 475 | | cmp OP, #BC_JFORI | ||
| 476 | #endif | ||
| 477 | | decode_RA8 RA, INS | ||
| 478 | | decode_RD RC, INS | ||
| 479 | #if LJ_HASJIT | ||
| 480 | | beq =>BC_JFORI | ||
| 481 | #endif | ||
| 482 | | b =>BC_FORI | ||
| 466 | | | 483 | | |
| 467 | |//----------------------------------------------------------------------- | 484 | |//----------------------------------------------------------------------- |
| 468 | |//-- Fast functions ----------------------------------------------------- | 485 | |//-- Fast functions ----------------------------------------------------- |
| @@ -1166,6 +1183,11 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 1166 | 1183 | ||
| 1167 | /* -- Loops and branches ------------------------------------------------ */ | 1184 | /* -- Loops and branches ------------------------------------------------ */ |
| 1168 | 1185 | ||
| 1186 | |.define FOR_IDX, [RA]; .define FOR_TIDX, [RA, #4] | ||
| 1187 | |.define FOR_STOP, [RA, #8]; .define FOR_TSTOP, [RA, #12] | ||
| 1188 | |.define FOR_STEP, [RA, #16]; .define FOR_TSTEP, [RA, #20] | ||
| 1189 | |.define FOR_EXT, [RA, #24]; .define FOR_TEXT, [RA, #28] | ||
| 1190 | |||
| 1169 | case BC_FORL: | 1191 | case BC_FORL: |
| 1170 | #if LJ_HASJIT | 1192 | #if LJ_HASJIT |
| 1171 | | hotloop | 1193 | | hotloop |
| @@ -1180,8 +1202,105 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 1180 | #endif | 1202 | #endif |
| 1181 | case BC_FORI: | 1203 | case BC_FORI: |
| 1182 | case BC_IFORL: | 1204 | case BC_IFORL: |
| 1205 | | // RA = base*8, RC = target (after end of loop or start of loop) | ||
| 1183 | vk = (op == BC_IFORL || op == BC_JFORL); | 1206 | vk = (op == BC_IFORL || op == BC_JFORL); |
| 1184 | | NYI | 1207 | | ldrd CARG12, [RA, BASE]! |
| 1208 | | add RC, PC, RC, lsl #2 | ||
| 1209 | if (!vk) { | ||
| 1210 | | ldrd CARG34, FOR_STOP | ||
| 1211 | | cmn CARG2, #-LJ_TISNUM | ||
| 1212 | | ldr RB, FOR_TSTEP | ||
| 1213 | | bne >5 | ||
| 1214 | | cmn CARG4, #-LJ_TISNUM | ||
| 1215 | | ldr CARG4, FOR_STEP | ||
| 1216 | | cmneq RB, #-LJ_TISNUM | ||
| 1217 | | bne ->vmeta_for | ||
| 1218 | | cmp CARG4, #0 | ||
| 1219 | | blt >4 | ||
| 1220 | | cmp CARG1, CARG3 | ||
| 1221 | } else { | ||
| 1222 | | ldrd CARG34, FOR_STEP | ||
| 1223 | | cmn CARG2, #-LJ_TISNUM | ||
| 1224 | | bne >5 | ||
| 1225 | | adds CARG1, CARG1, CARG3 | ||
| 1226 | | ldr CARG4, FOR_STOP | ||
| 1227 | if (op == BC_IFORL) { | ||
| 1228 | | addvs RC, PC, #0x20000 // Overflow: prevent branch. | ||
| 1229 | } else { | ||
| 1230 | | NYI | ||
| 1231 | } | ||
| 1232 | | cmp CARG3, #0 | ||
| 1233 | | blt >4 | ||
| 1234 | | cmp CARG1, CARG4 | ||
| 1235 | } | ||
| 1236 | |1: | ||
| 1237 | if (op == BC_FORI) { | ||
| 1238 | | subgt PC, RC, #0x20000 | ||
| 1239 | } else if (op == BC_JFORI) { | ||
| 1240 | | NYI | ||
| 1241 | } else if (op == BC_IFORL) { | ||
| 1242 | | suble PC, RC, #0x20000 | ||
| 1243 | } else { | ||
| 1244 | | NYI | ||
| 1245 | } | ||
| 1246 | if (vk) { | ||
| 1247 | | strd CARG12, FOR_IDX | ||
| 1248 | } | ||
| 1249 | | ins_next1 | ||
| 1250 | | ins_next2 | ||
| 1251 | | strd CARG12, FOR_EXT | ||
| 1252 | |3: | ||
| 1253 | | ins_next3 | ||
| 1254 | | | ||
| 1255 | |4: // Invert check for negative step. | ||
| 1256 | if (!vk) { | ||
| 1257 | | cmp CARG3, CARG1 | ||
| 1258 | } else { | ||
| 1259 | | cmp CARG4, CARG1 | ||
| 1260 | } | ||
| 1261 | | b <1 | ||
| 1262 | | | ||
| 1263 | |5: // FP loop. | ||
| 1264 | if (!vk) { | ||
| 1265 | | cmnlo CARG4, #-LJ_TISNUM | ||
| 1266 | | cmnlo RB, #-LJ_TISNUM | ||
| 1267 | | bhs ->vmeta_for | ||
| 1268 | | cmp RB, #0 | ||
| 1269 | | strd CARG12, FOR_IDX | ||
| 1270 | | blt >8 | ||
| 1271 | } else { | ||
| 1272 | | cmp CARG4, #0 | ||
| 1273 | | blt >8 | ||
| 1274 | | bl extern __aeabi_dadd | ||
| 1275 | | strd CARG12, FOR_IDX | ||
| 1276 | | ldrd CARG34, FOR_STOP | ||
| 1277 | | strd CARG12, FOR_EXT | ||
| 1278 | } | ||
| 1279 | |6: | ||
| 1280 | | bl extern __aeabi_cdcmple | ||
| 1281 | if (op == BC_FORI) { | ||
| 1282 | | subhi PC, RC, #0x20000 | ||
| 1283 | } else if (op == BC_JFORI) { | ||
| 1284 | | NYI | ||
| 1285 | } else if (op == BC_IFORL) { | ||
| 1286 | | subls PC, RC, #0x20000 | ||
| 1287 | } else { | ||
| 1288 | | NYI | ||
| 1289 | } | ||
| 1290 | | ins_next1 | ||
| 1291 | | ins_next2 | ||
| 1292 | | b <3 | ||
| 1293 | | | ||
| 1294 | |8: // Invert check for negative step. | ||
| 1295 | if (vk) { | ||
| 1296 | | bl extern __aeabi_dadd | ||
| 1297 | | strd CARG12, FOR_IDX | ||
| 1298 | | strd CARG12, FOR_EXT | ||
| 1299 | } | ||
| 1300 | | mov CARG3, CARG1 | ||
| 1301 | | mov CARG4, CARG2 | ||
| 1302 | | ldrd CARG12, FOR_STOP | ||
| 1303 | | b <6 | ||
| 1185 | break; | 1304 | break; |
| 1186 | 1305 | ||
| 1187 | case BC_ITERL: | 1306 | case BC_ITERL: |
| @@ -1200,11 +1319,18 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 1200 | break; | 1319 | break; |
| 1201 | 1320 | ||
| 1202 | case BC_LOOP: | 1321 | case BC_LOOP: |
| 1203 | | NYI | 1322 | | // RA = base*8, RC = target (loop extent) |
| 1323 | | // Note: RA/RC is only used by trace recorder to determine scope/extent | ||
| 1324 | | // This opcode does NOT jump, it's only purpose is to detect a hot loop. | ||
| 1325 | #if LJ_HASJIT | ||
| 1326 | | hotloop | ||
| 1327 | #endif | ||
| 1328 | | // Fall through. Assumes BC_ILOOP follows. | ||
| 1204 | break; | 1329 | break; |
| 1205 | 1330 | ||
| 1206 | case BC_ILOOP: | 1331 | case BC_ILOOP: |
| 1207 | | NYI | 1332 | | // RA = base*8, RC = target (loop extent) |
| 1333 | | ins_next | ||
| 1208 | break; | 1334 | break; |
| 1209 | 1335 | ||
| 1210 | case BC_JLOOP: | 1336 | case BC_JLOOP: |
| @@ -1214,7 +1340,10 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 1214 | break; | 1340 | break; |
| 1215 | 1341 | ||
| 1216 | case BC_JMP: | 1342 | case BC_JMP: |
| 1217 | | NYI | 1343 | | // RA = base*8 (only used by trace recorder), RC = target |
| 1344 | | add RC, PC, RC, lsl #2 | ||
| 1345 | | sub PC, RC, #0x20000 | ||
| 1346 | | ins_next | ||
| 1218 | break; | 1347 | break; |
| 1219 | 1348 | ||
| 1220 | /* -- Function headers -------------------------------------------------- */ | 1349 | /* -- Function headers -------------------------------------------------- */ |
