aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-04-08 02:48:55 +0200
committerMike Pall <mike>2011-04-08 02:48:55 +0200
commit3af41060c736e926ebb303999793fac0f5e9da12 (patch)
tree454951f0736c6883c760d89e0ebfb6699cee31bd /src
parent83e302938b690ac76d73937d242ebb0d5b7513c2 (diff)
downloadluajit-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.dasc213
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 --------------------------------------------------------- */