diff options
author | Mike Pall <mike> | 2011-04-08 02:48:55 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2011-04-08 02:48:55 +0200 |
commit | 3af41060c736e926ebb303999793fac0f5e9da12 (patch) | |
tree | 454951f0736c6883c760d89e0ebfb6699cee31bd /src | |
parent | 83e302938b690ac76d73937d242ebb0d5b7513c2 (diff) | |
download | luajit-3af41060c736e926ebb303999793fac0f5e9da12.tar.gz luajit-3af41060c736e926ebb303999793fac0f5e9da12.tar.bz2 luajit-3af41060c736e926ebb303999793fac0f5e9da12.zip |
ARM: Add test/copy and comparison instructions.
Diffstat (limited to 'src')
-rw-r--r-- | src/buildvm_arm.dasc | 213 |
1 files changed, 207 insertions, 6 deletions
diff --git a/src/buildvm_arm.dasc b/src/buildvm_arm.dasc index dbc31e1a..4411d46b 100644 --- a/src/buildvm_arm.dasc +++ b/src/buildvm_arm.dasc | |||
@@ -1356,33 +1356,234 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
1356 | /* Remember: all ops branch for a true comparison, fall through otherwise. */ | 1356 | /* Remember: all ops branch for a true comparison, fall through otherwise. */ |
1357 | 1357 | ||
1358 | case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT: | 1358 | case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT: |
1359 | | NYI | 1359 | | // RA = src1*8, RC = src2, JMP with RC = target |
1360 | | lsl RC, RC, #3 | ||
1361 | | ldrd CARG12, [RA, BASE]! | ||
1362 | | ldrh RB, [PC, #2] | ||
1363 | | ldrd CARG34, [RC, BASE]! | ||
1364 | | add PC, PC, #4 | ||
1365 | | add RB, PC, RB, lsl #2 | ||
1366 | | checktp CARG2, LJ_TISNUM | ||
1367 | | bne >3 | ||
1368 | | checktp CARG4, LJ_TISNUM | ||
1369 | | bne >4 | ||
1370 | | cmp CARG1, CARG3 | ||
1371 | if (op == BC_ISLT) { | ||
1372 | | sublt PC, RB, #0x20000 | ||
1373 | } else if (op == BC_ISGE) { | ||
1374 | | subge PC, RB, #0x20000 | ||
1375 | } else if (op == BC_ISLE) { | ||
1376 | | suble PC, RB, #0x20000 | ||
1377 | } else { | ||
1378 | | subgt PC, RB, #0x20000 | ||
1379 | } | ||
1380 | |1: | ||
1381 | | ins_next | ||
1382 | | | ||
1383 | |3: // CARG12 is not an integer. | ||
1384 | | bhi ->vmeta_comp | ||
1385 | | // CARG12 is a number. | ||
1386 | | checktp CARG4, LJ_TISNUM | ||
1387 | | movlo RA, RB // Save RB. | ||
1388 | | blo >5 | ||
1389 | | // CARG12 is a number, CARG3 is an integer. | ||
1390 | | mov CARG1, CARG3 | ||
1391 | | mov RC, RA | ||
1392 | | mov RA, RB // Save RB. | ||
1393 | | bl extern __aeabi_i2d | ||
1394 | | mov CARG3, CARG1 | ||
1395 | | mov CARG4, CARG2 | ||
1396 | | ldrd CARG12, [RC] // Restore first operand. | ||
1397 | | b >5 | ||
1398 | |4: // CARG1 is an integer, CARG34 is not an integer. | ||
1399 | | bhi ->vmeta_comp | ||
1400 | | // CARG1 is an integer, CARG34 is a number | ||
1401 | | mov RA, RB // Save RB. | ||
1402 | | bl extern __aeabi_i2d | ||
1403 | | ldrd CARG34, [RC] // Restore second operand. | ||
1404 | |5: // CARG12 and CARG34 are numbers. | ||
1405 | | bl extern __aeabi_cdcmple | ||
1406 | | // To preserve NaN semantics GE/GT branch on unordered, but LT/LE don't. | ||
1407 | if (op == BC_ISLT) { | ||
1408 | | sublo PC, RA, #0x20000 | ||
1409 | } else if (op == BC_ISGE) { | ||
1410 | | subhs PC, RA, #0x20000 | ||
1411 | } else if (op == BC_ISLE) { | ||
1412 | | subls PC, RA, #0x20000 | ||
1413 | } else { | ||
1414 | | subhi PC, RA, #0x20000 | ||
1415 | } | ||
1416 | | b <1 | ||
1360 | break; | 1417 | break; |
1361 | 1418 | ||
1362 | case BC_ISEQV: case BC_ISNEV: | 1419 | case BC_ISEQV: case BC_ISNEV: |
1363 | vk = op == BC_ISEQV; | 1420 | vk = op == BC_ISEQV; |
1364 | | NYI | 1421 | | // RA = src1*8, RC = src2, JMP with RC = target |
1422 | | lsl RC, RC, #3 | ||
1423 | | ldrd CARG12, [RA, BASE]! | ||
1424 | | ldrh RB, [PC, #2] | ||
1425 | | ldrd CARG34, [RC, BASE]! | ||
1426 | | add PC, PC, #4 | ||
1427 | | add RB, PC, RB, lsl #2 | ||
1428 | | checktp CARG2, LJ_TISNUM | ||
1429 | | cmnls CARG4, #-LJ_TISNUM | ||
1430 | if (vk) { | ||
1431 | | bls ->BC_ISEQN_Z | ||
1432 | } else { | ||
1433 | | bls ->BC_ISNEN_Z | ||
1434 | } | ||
1435 | | // Either or both types are not numbers. | ||
1436 | | cmp CARG2, CARG4 // Compare types. | ||
1437 | | bne >2 // Not the same type? | ||
1438 | | checktp CARG2, LJ_TISPRI | ||
1439 | | bhs >1 // Same type and primitive type? | ||
1440 | | | ||
1441 | | // Same types and not a primitive type. Compare GCobj or pvalue. | ||
1442 | | cmp CARG1, CARG3 | ||
1443 | if (vk) { | ||
1444 | | bne >3 // Different GCobjs or pvalues? | ||
1445 | |1: // Branch if same. | ||
1446 | | sub PC, RB, #0x20000 | ||
1447 | |2: // Different. | ||
1448 | | ins_next | ||
1449 | |3: | ||
1450 | | checktp CARG2, LJ_TISTABUD | ||
1451 | | bhi <2 // Different objects and not table/ud? | ||
1452 | } else { | ||
1453 | | beq >1 // Same GCobjs or pvalues? | ||
1454 | | checktp CARG2, LJ_TISTABUD | ||
1455 | | bhi >2 // Different objects and not table/ud? | ||
1456 | } | ||
1457 | | // Different tables or userdatas. Need to check __eq metamethod. | ||
1458 | | // Field metatable must be at same offset for GCtab and GCudata! | ||
1459 | | ldr TAB:RA, TAB:CARG1->metatable | ||
1460 | | cmp TAB:RA, #0 | ||
1461 | if (vk) { | ||
1462 | | beq <2 // No metatable? | ||
1463 | } else { | ||
1464 | | beq >2 // No metatable? | ||
1465 | } | ||
1466 | | ldrb RA, TAB:RA->nomm | ||
1467 | | mov CARG4, #1-vk // ne = 0 or 1. | ||
1468 | | mov CARG2, CARG1 | ||
1469 | | tst RA, #1<<MM_eq | ||
1470 | | beq ->vmeta_equal // 'no __eq' flag not set? | ||
1471 | if (!vk) { | ||
1472 | |2: // Branch if different. | ||
1473 | | sub PC, RB, #0x20000 | ||
1474 | |1: // Same. | ||
1475 | | ins_next | ||
1476 | } | ||
1365 | break; | 1477 | break; |
1366 | 1478 | ||
1367 | case BC_ISEQS: case BC_ISNES: | 1479 | case BC_ISEQS: case BC_ISNES: |
1368 | vk = op == BC_ISEQS; | 1480 | vk = op == BC_ISEQS; |
1369 | | NYI | 1481 | | // RA = src*8, RC = str_const (~), JMP with RC = target |
1482 | | mvn RC, RC | ||
1483 | | ldrd CARG12, [BASE, RA] | ||
1484 | | ldrh RB, [PC, #2] | ||
1485 | | ldr STR:CARG3, [KBASE, RC, lsl #2] | ||
1486 | | add PC, PC, #4 | ||
1487 | | add RB, PC, RB, lsl #2 | ||
1488 | | checktp CARG2, LJ_TSTR | ||
1489 | | cmpeq CARG1, CARG3 | ||
1490 | if (vk) { | ||
1491 | | subeq PC, RB, #0x20000 | ||
1492 | } else { | ||
1493 | | subne PC, RB, #0x20000 | ||
1494 | } | ||
1495 | | ins_next | ||
1370 | break; | 1496 | break; |
1371 | 1497 | ||
1372 | case BC_ISEQN: case BC_ISNEN: | 1498 | case BC_ISEQN: case BC_ISNEN: |
1373 | vk = op == BC_ISEQN; | 1499 | vk = op == BC_ISEQN; |
1374 | | NYI | 1500 | | // RA = src*8, RC = num_const (~), JMP with RC = target |
1501 | | lsl RC, RC, #3 | ||
1502 | | ldrd CARG12, [RA, BASE]! | ||
1503 | | ldrh RB, [PC, #2] | ||
1504 | | ldrd CARG34, [RC, KBASE]! | ||
1505 | | add PC, PC, #4 | ||
1506 | | add RB, PC, RB, lsl #2 | ||
1507 | if (vk) { | ||
1508 | |->BC_ISEQN_Z: | ||
1509 | } else { | ||
1510 | |->BC_ISNEN_Z: | ||
1511 | } | ||
1512 | | checktp CARG2, LJ_TISNUM | ||
1513 | | bne >3 | ||
1514 | | checktp CARG4, LJ_TISNUM | ||
1515 | | bne >4 | ||
1516 | | cmp CARG1, CARG3 | ||
1517 | if (vk) { | ||
1518 | | subeq PC, RB, #0x20000 | ||
1519 | } else { | ||
1520 | | subne PC, RB, #0x20000 | ||
1521 | } | ||
1522 | |1: | ||
1523 | | ins_next | ||
1524 | | | ||
1525 | |3: // CARG12 is not an integer. | ||
1526 | | bhi <1 | ||
1527 | | // CARG12 is a number. | ||
1528 | | checktp CARG4, LJ_TISNUM | ||
1529 | | movlo RA, RB // Save RB. | ||
1530 | | blo >5 | ||
1531 | | // CARG12 is a number, CARG3 is an integer. | ||
1532 | | mov CARG1, CARG3 | ||
1533 | | mov RC, RA | ||
1534 | |4: // CARG1 is an integer, CARG34 is a number. | ||
1535 | | mov RA, RB // Save RB. | ||
1536 | | bl extern __aeabi_i2d | ||
1537 | | ldrd CARG34, [RC] // Restore other operand. | ||
1538 | |5: // CARG12 and CARG34 are numbers. | ||
1539 | | bl extern __aeabi_cdcmpeq | ||
1540 | if (vk) { | ||
1541 | | subeq PC, RA, #0x20000 | ||
1542 | } else { | ||
1543 | | subne PC, RA, #0x20000 | ||
1544 | } | ||
1545 | | b <1 | ||
1375 | break; | 1546 | break; |
1376 | 1547 | ||
1377 | case BC_ISEQP: case BC_ISNEP: | 1548 | case BC_ISEQP: case BC_ISNEP: |
1378 | vk = op == BC_ISEQP; | 1549 | vk = op == BC_ISEQP; |
1379 | | NYI | 1550 | | // RA = src*8, RC = primitive_type (~), JMP with RC = target |
1551 | | ldrd CARG12, [BASE, RA] | ||
1552 | | ldrh RB, [PC, #2] | ||
1553 | | add PC, PC, #4 | ||
1554 | | mvn RC, RC | ||
1555 | | add RB, PC, RB, lsl #2 | ||
1556 | | cmp CARG2, RC | ||
1557 | if (vk) { | ||
1558 | | subeq PC, RB, #0x20000 | ||
1559 | } else { | ||
1560 | | subne PC, RB, #0x20000 | ||
1561 | } | ||
1562 | | ins_next | ||
1380 | break; | 1563 | break; |
1381 | 1564 | ||
1382 | /* -- Unary test and copy ops ------------------------------------------- */ | 1565 | /* -- Unary test and copy ops ------------------------------------------- */ |
1383 | 1566 | ||
1384 | case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF: | 1567 | case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF: |
1385 | | NYI | 1568 | | // RA = dst*8 or unused, RC = src, JMP with RC = target |
1569 | | add RC, BASE, RC, lsl #3 | ||
1570 | | ldrh RB, [PC, #2] | ||
1571 | | ldrd CARG12, [RC] | ||
1572 | | add PC, PC, #4 | ||
1573 | | add RB, PC, RB, lsl #2 | ||
1574 | | checktp CARG2, LJ_TTRUE | ||
1575 | if (op == BC_ISTC || op == BC_IST) { | ||
1576 | | subls PC, RB, #0x20000 | ||
1577 | if (op == BC_ISTC) { | ||
1578 | | strdls CARG12, [BASE, RA] | ||
1579 | } | ||
1580 | } else { | ||
1581 | | subhi PC, RB, #0x20000 | ||
1582 | if (op == BC_ISFC) { | ||
1583 | | strdhi CARG12, [BASE, RA] | ||
1584 | } | ||
1585 | } | ||
1586 | | ins_next | ||
1386 | break; | 1587 | break; |
1387 | 1588 | ||
1388 | /* -- Unary ops --------------------------------------------------------- */ | 1589 | /* -- Unary ops --------------------------------------------------------- */ |