| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include <math.h> // for isnan. | 5 #include <math.h> // for isnan. |
| 6 #include <setjmp.h> | 6 #include <setjmp.h> |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 | 8 |
| 9 #include "vm/globals.h" | 9 #include "vm/globals.h" |
| 10 #if defined(TARGET_ARCH_ARM) | 10 #if defined(TARGET_ARCH_ARM) |
| (...skipping 1679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1690 if (instr->Bits(21, 3) == 3) { // mls | 1690 if (instr->Bits(21, 3) == 3) { // mls |
| 1691 alu_out = -alu_out; | 1691 alu_out = -alu_out; |
| 1692 } | 1692 } |
| 1693 alu_out += rd_val; | 1693 alu_out += rd_val; |
| 1694 set_register(rn, alu_out); | 1694 set_register(rn, alu_out); |
| 1695 if (instr->HasS()) { | 1695 if (instr->HasS()) { |
| 1696 SetNZFlags(alu_out); | 1696 SetNZFlags(alu_out); |
| 1697 } | 1697 } |
| 1698 break; | 1698 break; |
| 1699 } | 1699 } |
| 1700 case 4: { | 1700 case 4: |
| 1701 // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. | 1701 // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. |
| 1702 // Format(instr, "umull'cond's 'rd, 'rn, 'rm, 'rs"); | 1702 // Format(instr, "umull'cond's 'rd, 'rn, 'rm, 'rs"); |
| 1703 uint64_t left_op = static_cast<uint32_t>(rm_val); | 1703 case 6: { |
| 1704 uint64_t right_op = static_cast<uint32_t>(rs_val); | 1704 // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. |
| 1705 uint64_t result = left_op * right_op; | 1705 // Format(instr, "smull'cond's 'rd, 'rn, 'rm, 'rs"); |
| 1706 int64_t result; |
| 1707 if (instr->Bits(21, 3) == 4) { // umull |
| 1708 uint64_t left_op = static_cast<uint32_t>(rm_val); |
| 1709 uint64_t right_op = static_cast<uint32_t>(rs_val); |
| 1710 result = left_op * right_op; // Unsigned nultiplication. |
| 1711 } else { // smull |
| 1712 int64_t left_op = static_cast<int32_t>(rm_val); |
| 1713 int64_t right_op = static_cast<int32_t>(rs_val); |
| 1714 result = left_op * right_op; // Signed nultiplication. |
| 1715 } |
| 1706 int32_t hi_res = Utils::High32Bits(result); | 1716 int32_t hi_res = Utils::High32Bits(result); |
| 1707 int32_t lo_res = Utils::Low32Bits(result); | 1717 int32_t lo_res = Utils::Low32Bits(result); |
| 1708 set_register(rd, lo_res); | 1718 set_register(rd, lo_res); |
| 1709 set_register(rn, hi_res); | |
| 1710 if (instr->HasS()) { | |
| 1711 if (lo_res != 0) { | |
| 1712 // Collapse bits 0..31 into bit 32 so that 32-bit Z check works. | |
| 1713 hi_res |= 1; | |
| 1714 } | |
| 1715 ASSERT((result == 0) == (hi_res == 0)); // Z bit | |
| 1716 ASSERT(((result & (1LL << 63)) != 0) == (hi_res < 0)); // N bit | |
| 1717 SetNZFlags(hi_res); | |
| 1718 } | |
| 1719 break; | |
| 1720 } | |
| 1721 case 6: { | |
| 1722 // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. | |
| 1723 // Format(instr, "smull'cond's 'rd, 'rn, 'rm, 'rs"); | |
| 1724 int64_t left_op = static_cast<int32_t>(rm_val); | |
| 1725 int64_t right_op = static_cast<int32_t>(rs_val); | |
| 1726 int64_t result = left_op * right_op; | |
| 1727 int32_t hi_res = Utils::High32Bits(result); | |
| 1728 int32_t lo_res = Utils::Low32Bits(result); | |
| 1729 set_register(rd, lo_res); | |
| 1730 set_register(rn, hi_res); | 1719 set_register(rn, hi_res); |
| 1731 if (instr->HasS()) { | 1720 if (instr->HasS()) { |
| 1732 if (lo_res != 0) { | 1721 if (lo_res != 0) { |
| 1733 // Collapse bits 0..31 into bit 32 so that 32-bit Z check works. | 1722 // Collapse bits 0..31 into bit 32 so that 32-bit Z check works. |
| 1734 hi_res |= 1; | 1723 hi_res |= 1; |
| 1735 } | 1724 } |
| 1736 ASSERT((result == 0) == (hi_res == 0)); // Z bit | 1725 ASSERT((result == 0) == (hi_res == 0)); // Z bit |
| 1737 ASSERT(((result & (1LL << 63)) != 0) == (hi_res < 0)); // N bit | 1726 ASSERT(((result & (1LL << 63)) != 0) == (hi_res < 0)); // N bit |
| 1738 SetNZFlags(hi_res); | 1727 SetNZFlags(hi_res); |
| 1739 } | 1728 } |
| 1740 break; | 1729 break; |
| 1741 } | 1730 } |
| 1731 case 5: |
| 1732 // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. |
| 1733 // Format(instr, "umlal'cond's 'rd, 'rn, 'rm, 'rs"); |
| 1742 case 7: { | 1734 case 7: { |
| 1743 // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. | 1735 // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. |
| 1744 // Format(instr, "smlal'cond's 'rd, 'rn, 'rm, 'rs"); | 1736 // Format(instr, "smlal'cond's 'rd, 'rn, 'rm, 'rs"); |
| 1745 int32_t rd_lo_val = get_register(rd); | 1737 int32_t rd_lo_val = get_register(rd); |
| 1746 int32_t rd_hi_val = get_register(rn); | 1738 int32_t rd_hi_val = get_register(rn); |
| 1747 int64_t left_op = static_cast<int32_t>(rm_val); | |
| 1748 int64_t right_op = static_cast<int32_t>(rs_val); | |
| 1749 uint32_t accum_lo = static_cast<uint32_t>(rd_lo_val); | 1739 uint32_t accum_lo = static_cast<uint32_t>(rd_lo_val); |
| 1750 int32_t accum_hi = static_cast<int32_t>(rd_hi_val); | 1740 int32_t accum_hi = static_cast<int32_t>(rd_hi_val); |
| 1751 int64_t accum = Utils::LowHighTo64Bits(accum_lo, accum_hi); | 1741 int64_t accum = Utils::LowHighTo64Bits(accum_lo, accum_hi); |
| 1752 int64_t result = accum + left_op * right_op; | 1742 int64_t result; |
| 1743 if (instr->Bits(21, 3) == 5) { // umlal |
| 1744 uint64_t left_op = static_cast<uint32_t>(rm_val); |
| 1745 uint64_t right_op = static_cast<uint32_t>(rs_val); |
| 1746 result = accum + left_op * right_op; // Unsigned nultiplication. |
| 1747 } else { // smlal |
| 1748 int64_t left_op = static_cast<int32_t>(rm_val); |
| 1749 int64_t right_op = static_cast<int32_t>(rs_val); |
| 1750 result = accum + left_op * right_op; // Signed nultiplication. |
| 1751 } |
| 1753 int32_t hi_res = Utils::High32Bits(result); | 1752 int32_t hi_res = Utils::High32Bits(result); |
| 1754 int32_t lo_res = Utils::Low32Bits(result); | 1753 int32_t lo_res = Utils::Low32Bits(result); |
| 1755 set_register(rd, lo_res); | 1754 set_register(rd, lo_res); |
| 1756 set_register(rn, hi_res); | 1755 set_register(rn, hi_res); |
| 1757 if (instr->HasS()) { | 1756 if (instr->HasS()) { |
| 1758 if (lo_res != 0) { | 1757 if (lo_res != 0) { |
| 1759 // Collapse bits 0..31 into bit 32 so that 32-bit Z check works. | 1758 // Collapse bits 0..31 into bit 32 so that 32-bit Z check works. |
| 1760 hi_res |= 1; | 1759 hi_res |= 1; |
| 1761 } | 1760 } |
| 1762 ASSERT((result == 0) == (hi_res == 0)); // Z bit | 1761 ASSERT((result == 0) == (hi_res == 0)); // Z bit |
| (...skipping 1354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3117 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); | 3116 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); |
| 3118 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); | 3117 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); |
| 3119 buf->Longjmp(); | 3118 buf->Longjmp(); |
| 3120 } | 3119 } |
| 3121 | 3120 |
| 3122 } // namespace dart | 3121 } // namespace dart |
| 3123 | 3122 |
| 3124 #endif // !defined(HOST_ARCH_ARM) | 3123 #endif // !defined(HOST_ARCH_ARM) |
| 3125 | 3124 |
| 3126 #endif // defined TARGET_ARCH_ARM | 3125 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |