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