aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-03-30 21:54:33 +0200
committerMike Pall <mike>2011-03-30 21:54:33 +0200
commita0e47110556130957f261ede57383d3a3eb73d52 (patch)
tree38be95c9520cb61f2292f264096555b7b54716d0 /src
parent7b0a125cf76e67df2f1e43f8e3ac4ca08851a7b3 (diff)
downloadluajit-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.dasc139
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 -------------------------------------------------- */