OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64) | 10 #if defined(TARGET_ARCH_ARM64) |
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
889 const Register rn = instr->RnField(); | 889 const Register rn = instr->RnField(); |
890 const uint32_t imm = (instr->Bit(22) == 1) ? (instr->Imm12Field() << 12) | 890 const uint32_t imm = (instr->Bit(22) == 1) ? (instr->Imm12Field() << 12) |
891 : (instr->Imm12Field()); | 891 : (instr->Imm12Field()); |
892 if (instr->SFField()) { | 892 if (instr->SFField()) { |
893 // 64-bit add. | 893 // 64-bit add. |
894 const int64_t rn_val = get_register(rn, instr->RnMode()); | 894 const int64_t rn_val = get_register(rn, instr->RnMode()); |
895 const int64_t alu_out = addition ? (rn_val + imm) : (rn_val - imm); | 895 const int64_t alu_out = addition ? (rn_val + imm) : (rn_val - imm); |
896 set_register(rd, alu_out, instr->RdMode()); | 896 set_register(rd, alu_out, instr->RdMode()); |
897 if (instr->HasS()) { | 897 if (instr->HasS()) { |
898 SetNZFlagsX(alu_out); | 898 SetNZFlagsX(alu_out); |
899 SetCFlag(CarryFromX(rn_val, imm)); | 899 if (addition) { |
| 900 SetCFlag(CarryFromX(rn_val, imm)); |
| 901 } else { |
| 902 SetCFlag(!BorrowFromX(rn_val, imm)); |
| 903 } |
900 SetVFlag(OverflowFromX(alu_out, rn_val, imm, addition)); | 904 SetVFlag(OverflowFromX(alu_out, rn_val, imm, addition)); |
901 } | 905 } |
902 } else { | 906 } else { |
903 // 32-bit add. | 907 // 32-bit add. |
904 const int32_t rn_val = get_wregister(rn, instr->RnMode()); | 908 const int32_t rn_val = get_wregister(rn, instr->RnMode()); |
905 const int32_t alu_out = addition ? (rn_val + imm) : (rn_val - imm); | 909 const int32_t alu_out = addition ? (rn_val + imm) : (rn_val - imm); |
906 set_wregister(rd, alu_out, instr->RdMode()); | 910 set_wregister(rd, alu_out, instr->RdMode()); |
907 if (instr->HasS()) { | 911 if (instr->HasS()) { |
908 SetNZFlagsW(alu_out); | 912 SetNZFlagsW(alu_out); |
909 SetCFlag(CarryFromW(rn_val, imm)); | 913 if (addition) { |
| 914 SetCFlag(CarryFromW(rn_val, imm)); |
| 915 } else { |
| 916 SetCFlag(!BorrowFromW(rn_val, imm)); |
| 917 } |
910 SetVFlag(OverflowFromW(alu_out, rn_val, imm, addition)); | 918 SetVFlag(OverflowFromW(alu_out, rn_val, imm, addition)); |
911 } | 919 } |
912 } | 920 } |
913 } | 921 } |
914 | 922 |
915 | 923 |
916 void Simulator::DecodeLogicalImm(Instr* instr) { | 924 void Simulator::DecodeLogicalImm(Instr* instr) { |
917 const int op = instr->Bits(29, 2); | 925 const int op = instr->Bits(29, 2); |
918 const bool set_flags = op == 3; | 926 const bool set_flags = op == 3; |
919 const int out_size = ((instr->SFField() == 0) && (instr->NField() == 0)) | 927 const int out_size = ((instr->SFField() == 0) && (instr->NField() == 0)) |
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1595 const int64_t rn_val = get_register(rn, instr->RnMode()); | 1603 const int64_t rn_val = get_register(rn, instr->RnMode()); |
1596 int64_t alu_out = 0; | 1604 int64_t alu_out = 0; |
1597 if (subtract) { | 1605 if (subtract) { |
1598 alu_out = rn_val - rm_val; | 1606 alu_out = rn_val - rm_val; |
1599 } else { | 1607 } else { |
1600 alu_out = rn_val + rm_val; | 1608 alu_out = rn_val + rm_val; |
1601 } | 1609 } |
1602 set_register(rd, alu_out, instr->RdMode()); | 1610 set_register(rd, alu_out, instr->RdMode()); |
1603 if (instr->HasS()) { | 1611 if (instr->HasS()) { |
1604 SetNZFlagsX(alu_out); | 1612 SetNZFlagsX(alu_out); |
1605 SetCFlag(CarryFromX(rn_val, rm_val)); | 1613 if (subtract) { |
| 1614 SetCFlag(!BorrowFromX(rn_val, rm_val)); |
| 1615 } else { |
| 1616 SetCFlag(CarryFromX(rn_val, rm_val)); |
| 1617 } |
1606 SetVFlag(OverflowFromX(alu_out, rn_val, rm_val, !subtract)); | 1618 SetVFlag(OverflowFromX(alu_out, rn_val, rm_val, !subtract)); |
1607 } | 1619 } |
1608 } else { | 1620 } else { |
1609 // 32-bit add. | 1621 // 32-bit add. |
1610 const int32_t rn_val = get_wregister(rn, instr->RnMode()); | 1622 const int32_t rn_val = get_wregister(rn, instr->RnMode()); |
1611 const int32_t rm_val32 = static_cast<int32_t>(rm_val & kWRegMask); | 1623 const int32_t rm_val32 = static_cast<int32_t>(rm_val & kWRegMask); |
1612 int32_t alu_out = 0; | 1624 int32_t alu_out = 0; |
1613 if (subtract) { | 1625 if (subtract) { |
1614 alu_out = rn_val - rm_val32; | 1626 alu_out = rn_val - rm_val32; |
1615 } else { | 1627 } else { |
1616 alu_out = rn_val + rm_val32; | 1628 alu_out = rn_val + rm_val32; |
1617 } | 1629 } |
1618 set_wregister(rd, alu_out, instr->RdMode()); | 1630 set_wregister(rd, alu_out, instr->RdMode()); |
1619 if (instr->HasS()) { | 1631 if (instr->HasS()) { |
1620 SetNZFlagsW(alu_out); | 1632 SetNZFlagsW(alu_out); |
1621 SetCFlag(CarryFromW(rn_val, rm_val32)); | 1633 if (subtract) { |
| 1634 SetCFlag(!BorrowFromW(rn_val, rm_val32)); |
| 1635 } else { |
| 1636 SetCFlag(CarryFromW(rn_val, rm_val32)); |
| 1637 } |
1622 SetVFlag(OverflowFromW(alu_out, rn_val, rm_val32, !subtract)); | 1638 SetVFlag(OverflowFromW(alu_out, rn_val, rm_val32, !subtract)); |
1623 } | 1639 } |
1624 } | 1640 } |
1625 } | 1641 } |
1626 | 1642 |
1627 | 1643 |
1628 void Simulator::DecodeLogicalShift(Instr* instr) { | 1644 void Simulator::DecodeLogicalShift(Instr* instr) { |
1629 const int op = (instr->Bits(29, 2) << 1) | instr->Bit(21); | 1645 const int op = (instr->Bits(29, 2) << 1) | instr->Bit(21); |
1630 const Register rd = instr->RdField(); | 1646 const Register rd = instr->RdField(); |
1631 const Register rn = instr->RnField(); | 1647 const Register rn = instr->RnField(); |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2047 int64_t return_value; | 2063 int64_t return_value; |
2048 return_value = get_register(R0); | 2064 return_value = get_register(R0); |
2049 return return_value; | 2065 return return_value; |
2050 } | 2066 } |
2051 | 2067 |
2052 } // namespace dart | 2068 } // namespace dart |
2053 | 2069 |
2054 #endif // !defined(HOST_ARCH_ARM64) | 2070 #endif // !defined(HOST_ARCH_ARM64) |
2055 | 2071 |
2056 #endif // defined TARGET_ARCH_ARM64 | 2072 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |