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 -------------------------------------------------- */ |