| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 | 299 |
| 300 CorruptRegisters(®ister_list, kCallerSavedRegisterCorruptionValue); | 300 CorruptRegisters(®ister_list, kCallerSavedRegisterCorruptionValue); |
| 301 CorruptRegisters(&fpregister_list, kCallerSavedFPRegisterCorruptionValue); | 301 CorruptRegisters(&fpregister_list, kCallerSavedFPRegisterCorruptionValue); |
| 302 } | 302 } |
| 303 #endif | 303 #endif |
| 304 | 304 |
| 305 | 305 |
| 306 // Extending the stack by 2 * 64 bits is required for stack alignment purposes. | 306 // Extending the stack by 2 * 64 bits is required for stack alignment purposes. |
| 307 // TODO(all): Insert a marker in the extra space allocated on the stack. | 307 // TODO(all): Insert a marker in the extra space allocated on the stack. |
| 308 uintptr_t Simulator::PushAddress(uintptr_t address) { | 308 uintptr_t Simulator::PushAddress(uintptr_t address) { |
| 309 ASSERT(sizeof(uintptr_t) < 2 * kXRegSizeInBytes); | 309 ASSERT(sizeof(uintptr_t) < 2 * kXRegSize); |
| 310 intptr_t new_sp = sp() - 2 * kXRegSizeInBytes; | 310 intptr_t new_sp = sp() - 2 * kXRegSize; |
| 311 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp); | 311 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp); |
| 312 *stack_slot = address; | 312 *stack_slot = address; |
| 313 set_sp(new_sp); | 313 set_sp(new_sp); |
| 314 return new_sp; | 314 return new_sp; |
| 315 } | 315 } |
| 316 | 316 |
| 317 | 317 |
| 318 uintptr_t Simulator::PopAddress() { | 318 uintptr_t Simulator::PopAddress() { |
| 319 intptr_t current_sp = sp(); | 319 intptr_t current_sp = sp(); |
| 320 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); | 320 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); |
| 321 uintptr_t address = *stack_slot; | 321 uintptr_t address = *stack_slot; |
| 322 ASSERT(sizeof(uintptr_t) < 2 * kXRegSizeInBytes); | 322 ASSERT(sizeof(uintptr_t) < 2 * kXRegSize); |
| 323 set_sp(current_sp + 2 * kXRegSizeInBytes); | 323 set_sp(current_sp + 2 * kXRegSize); |
| 324 return address; | 324 return address; |
| 325 } | 325 } |
| 326 | 326 |
| 327 | 327 |
| 328 // Returns the limit of the stack area to enable checking for stack overflows. | 328 // Returns the limit of the stack area to enable checking for stack overflows. |
| 329 uintptr_t Simulator::StackLimit() const { | 329 uintptr_t Simulator::StackLimit() const { |
| 330 // Leave a safety margin of 1024 bytes to prevent overrunning the stack when | 330 // Leave a safety margin of 1024 bytes to prevent overrunning the stack when |
| 331 // pushing values. | 331 // pushing values. |
| 332 // TODO(all): Increase the stack limit protection. | 332 // TODO(all): Increase the stack limit protection. |
| 333 | 333 |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 607 } | 607 } |
| 608 | 608 |
| 609 | 609 |
| 610 // Helpers --------------------------------------------------------------------- | 610 // Helpers --------------------------------------------------------------------- |
| 611 int64_t Simulator::AddWithCarry(unsigned reg_size, | 611 int64_t Simulator::AddWithCarry(unsigned reg_size, |
| 612 bool set_flags, | 612 bool set_flags, |
| 613 int64_t src1, | 613 int64_t src1, |
| 614 int64_t src2, | 614 int64_t src2, |
| 615 int64_t carry_in) { | 615 int64_t carry_in) { |
| 616 ASSERT((carry_in == 0) || (carry_in == 1)); | 616 ASSERT((carry_in == 0) || (carry_in == 1)); |
| 617 ASSERT((reg_size == kXRegSize) || (reg_size == kWRegSize)); | 617 ASSERT((reg_size == kXRegSizeInBits) || (reg_size == kWRegSizeInBits)); |
| 618 | 618 |
| 619 uint64_t u1, u2; | 619 uint64_t u1, u2; |
| 620 int64_t result; | 620 int64_t result; |
| 621 int64_t signed_sum = src1 + src2 + carry_in; | 621 int64_t signed_sum = src1 + src2 + carry_in; |
| 622 | 622 |
| 623 uint32_t N, Z, C, V; | 623 uint32_t N, Z, C, V; |
| 624 | 624 |
| 625 if (reg_size == kWRegSize) { | 625 if (reg_size == kWRegSizeInBits) { |
| 626 u1 = static_cast<uint64_t>(src1) & kWRegMask; | 626 u1 = static_cast<uint64_t>(src1) & kWRegMask; |
| 627 u2 = static_cast<uint64_t>(src2) & kWRegMask; | 627 u2 = static_cast<uint64_t>(src2) & kWRegMask; |
| 628 | 628 |
| 629 result = signed_sum & kWRegMask; | 629 result = signed_sum & kWRegMask; |
| 630 // Compute the C flag by comparing the sum to the max unsigned integer. | 630 // Compute the C flag by comparing the sum to the max unsigned integer. |
| 631 C = ((kWMaxUInt - u1) < (u2 + carry_in)) || | 631 C = ((kWMaxUInt - u1) < (u2 + carry_in)) || |
| 632 ((kWMaxUInt - u1 - carry_in) < u2); | 632 ((kWMaxUInt - u1 - carry_in) < u2); |
| 633 // Overflow iff the sign bit is the same for the two inputs and different | 633 // Overflow iff the sign bit is the same for the two inputs and different |
| 634 // for the result. | 634 // for the result. |
| 635 int64_t s_src1 = src1 << (kXRegSize - kWRegSize); | 635 int64_t s_src1 = src1 << (kXRegSizeInBits - kWRegSizeInBits); |
| 636 int64_t s_src2 = src2 << (kXRegSize - kWRegSize); | 636 int64_t s_src2 = src2 << (kXRegSizeInBits - kWRegSizeInBits); |
| 637 int64_t s_result = result << (kXRegSize - kWRegSize); | 637 int64_t s_result = result << (kXRegSizeInBits - kWRegSizeInBits); |
| 638 V = ((s_src1 ^ s_src2) >= 0) && ((s_src1 ^ s_result) < 0); | 638 V = ((s_src1 ^ s_src2) >= 0) && ((s_src1 ^ s_result) < 0); |
| 639 | 639 |
| 640 } else { | 640 } else { |
| 641 u1 = static_cast<uint64_t>(src1); | 641 u1 = static_cast<uint64_t>(src1); |
| 642 u2 = static_cast<uint64_t>(src2); | 642 u2 = static_cast<uint64_t>(src2); |
| 643 | 643 |
| 644 result = signed_sum; | 644 result = signed_sum; |
| 645 // Compute the C flag by comparing the sum to the max unsigned integer. | 645 // Compute the C flag by comparing the sum to the max unsigned integer. |
| 646 C = ((kXMaxUInt - u1) < (u2 + carry_in)) || | 646 C = ((kXMaxUInt - u1) < (u2 + carry_in)) || |
| 647 ((kXMaxUInt - u1 - carry_in) < u2); | 647 ((kXMaxUInt - u1 - carry_in) < u2); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 663 } | 663 } |
| 664 | 664 |
| 665 | 665 |
| 666 int64_t Simulator::ShiftOperand(unsigned reg_size, | 666 int64_t Simulator::ShiftOperand(unsigned reg_size, |
| 667 int64_t value, | 667 int64_t value, |
| 668 Shift shift_type, | 668 Shift shift_type, |
| 669 unsigned amount) { | 669 unsigned amount) { |
| 670 if (amount == 0) { | 670 if (amount == 0) { |
| 671 return value; | 671 return value; |
| 672 } | 672 } |
| 673 int64_t mask = reg_size == kXRegSize ? kXRegMask : kWRegMask; | 673 int64_t mask = reg_size == kXRegSizeInBits ? kXRegMask : kWRegMask; |
| 674 switch (shift_type) { | 674 switch (shift_type) { |
| 675 case LSL: | 675 case LSL: |
| 676 return (value << amount) & mask; | 676 return (value << amount) & mask; |
| 677 case LSR: | 677 case LSR: |
| 678 return static_cast<uint64_t>(value) >> amount; | 678 return static_cast<uint64_t>(value) >> amount; |
| 679 case ASR: { | 679 case ASR: { |
| 680 // Shift used to restore the sign. | 680 // Shift used to restore the sign. |
| 681 unsigned s_shift = kXRegSize - reg_size; | 681 unsigned s_shift = kXRegSizeInBits - reg_size; |
| 682 // Value with its sign restored. | 682 // Value with its sign restored. |
| 683 int64_t s_value = (value << s_shift) >> s_shift; | 683 int64_t s_value = (value << s_shift) >> s_shift; |
| 684 return (s_value >> amount) & mask; | 684 return (s_value >> amount) & mask; |
| 685 } | 685 } |
| 686 case ROR: { | 686 case ROR: { |
| 687 if (reg_size == kWRegSize) { | 687 if (reg_size == kWRegSizeInBits) { |
| 688 value &= kWRegMask; | 688 value &= kWRegMask; |
| 689 } | 689 } |
| 690 return (static_cast<uint64_t>(value) >> amount) | | 690 return (static_cast<uint64_t>(value) >> amount) | |
| 691 ((value & ((1L << amount) - 1L)) << (reg_size - amount)); | 691 ((value & ((1L << amount) - 1L)) << (reg_size - amount)); |
| 692 } | 692 } |
| 693 default: | 693 default: |
| 694 UNIMPLEMENTED(); | 694 UNIMPLEMENTED(); |
| 695 return 0; | 695 return 0; |
| 696 } | 696 } |
| 697 } | 697 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 719 break; | 719 break; |
| 720 case SXTW: | 720 case SXTW: |
| 721 value = (value << 32) >> 32; | 721 value = (value << 32) >> 32; |
| 722 break; | 722 break; |
| 723 case UXTX: | 723 case UXTX: |
| 724 case SXTX: | 724 case SXTX: |
| 725 break; | 725 break; |
| 726 default: | 726 default: |
| 727 UNREACHABLE(); | 727 UNREACHABLE(); |
| 728 } | 728 } |
| 729 int64_t mask = (reg_size == kXRegSize) ? kXRegMask : kWRegMask; | 729 int64_t mask = (reg_size == kXRegSizeInBits) ? kXRegMask : kWRegMask; |
| 730 return (value << left_shift) & mask; | 730 return (value << left_shift) & mask; |
| 731 } | 731 } |
| 732 | 732 |
| 733 | 733 |
| 734 void Simulator::FPCompare(double val0, double val1) { | 734 void Simulator::FPCompare(double val0, double val1) { |
| 735 AssertSupportedFPCR(); | 735 AssertSupportedFPCR(); |
| 736 | 736 |
| 737 // TODO(jbramley): This assumes that the C++ implementation handles | 737 // TODO(jbramley): This assumes that the C++ implementation handles |
| 738 // comparisons in the way that we expect (as per AssertSupportedFPCR()). | 738 // comparisons in the way that we expect (as per AssertSupportedFPCR()). |
| 739 if ((std::isnan(val0) != 0) || (std::isnan(val1) != 0)) { | 739 if ((std::isnan(val0) != 0) || (std::isnan(val1) != 0)) { |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1049 case CBNZ_x: take_branch = (xreg(rt) != 0); break; | 1049 case CBNZ_x: take_branch = (xreg(rt) != 0); break; |
| 1050 default: UNIMPLEMENTED(); | 1050 default: UNIMPLEMENTED(); |
| 1051 } | 1051 } |
| 1052 if (take_branch) { | 1052 if (take_branch) { |
| 1053 set_pc(instr->ImmPCOffsetTarget()); | 1053 set_pc(instr->ImmPCOffsetTarget()); |
| 1054 } | 1054 } |
| 1055 } | 1055 } |
| 1056 | 1056 |
| 1057 | 1057 |
| 1058 void Simulator::AddSubHelper(Instruction* instr, int64_t op2) { | 1058 void Simulator::AddSubHelper(Instruction* instr, int64_t op2) { |
| 1059 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; | 1059 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits |
| 1060 : kWRegSizeInBits; |
| 1060 bool set_flags = instr->FlagsUpdate(); | 1061 bool set_flags = instr->FlagsUpdate(); |
| 1061 int64_t new_val = 0; | 1062 int64_t new_val = 0; |
| 1062 Instr operation = instr->Mask(AddSubOpMask); | 1063 Instr operation = instr->Mask(AddSubOpMask); |
| 1063 | 1064 |
| 1064 switch (operation) { | 1065 switch (operation) { |
| 1065 case ADD: | 1066 case ADD: |
| 1066 case ADDS: { | 1067 case ADDS: { |
| 1067 new_val = AddWithCarry(reg_size, | 1068 new_val = AddWithCarry(reg_size, |
| 1068 set_flags, | 1069 set_flags, |
| 1069 reg(reg_size, instr->Rn(), instr->RnMode()), | 1070 reg(reg_size, instr->Rn(), instr->RnMode()), |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1080 break; | 1081 break; |
| 1081 } | 1082 } |
| 1082 default: UNREACHABLE(); | 1083 default: UNREACHABLE(); |
| 1083 } | 1084 } |
| 1084 | 1085 |
| 1085 set_reg(reg_size, instr->Rd(), new_val, instr->RdMode()); | 1086 set_reg(reg_size, instr->Rd(), new_val, instr->RdMode()); |
| 1086 } | 1087 } |
| 1087 | 1088 |
| 1088 | 1089 |
| 1089 void Simulator::VisitAddSubShifted(Instruction* instr) { | 1090 void Simulator::VisitAddSubShifted(Instruction* instr) { |
| 1090 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; | 1091 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits |
| 1092 : kWRegSizeInBits; |
| 1091 int64_t op2 = ShiftOperand(reg_size, | 1093 int64_t op2 = ShiftOperand(reg_size, |
| 1092 reg(reg_size, instr->Rm()), | 1094 reg(reg_size, instr->Rm()), |
| 1093 static_cast<Shift>(instr->ShiftDP()), | 1095 static_cast<Shift>(instr->ShiftDP()), |
| 1094 instr->ImmDPShift()); | 1096 instr->ImmDPShift()); |
| 1095 AddSubHelper(instr, op2); | 1097 AddSubHelper(instr, op2); |
| 1096 } | 1098 } |
| 1097 | 1099 |
| 1098 | 1100 |
| 1099 void Simulator::VisitAddSubImmediate(Instruction* instr) { | 1101 void Simulator::VisitAddSubImmediate(Instruction* instr) { |
| 1100 int64_t op2 = instr->ImmAddSub() << ((instr->ShiftAddSub() == 1) ? 12 : 0); | 1102 int64_t op2 = instr->ImmAddSub() << ((instr->ShiftAddSub() == 1) ? 12 : 0); |
| 1101 AddSubHelper(instr, op2); | 1103 AddSubHelper(instr, op2); |
| 1102 } | 1104 } |
| 1103 | 1105 |
| 1104 | 1106 |
| 1105 void Simulator::VisitAddSubExtended(Instruction* instr) { | 1107 void Simulator::VisitAddSubExtended(Instruction* instr) { |
| 1106 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; | 1108 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits |
| 1109 : kWRegSizeInBits; |
| 1107 int64_t op2 = ExtendValue(reg_size, | 1110 int64_t op2 = ExtendValue(reg_size, |
| 1108 reg(reg_size, instr->Rm()), | 1111 reg(reg_size, instr->Rm()), |
| 1109 static_cast<Extend>(instr->ExtendMode()), | 1112 static_cast<Extend>(instr->ExtendMode()), |
| 1110 instr->ImmExtendShift()); | 1113 instr->ImmExtendShift()); |
| 1111 AddSubHelper(instr, op2); | 1114 AddSubHelper(instr, op2); |
| 1112 } | 1115 } |
| 1113 | 1116 |
| 1114 | 1117 |
| 1115 void Simulator::VisitAddSubWithCarry(Instruction* instr) { | 1118 void Simulator::VisitAddSubWithCarry(Instruction* instr) { |
| 1116 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; | 1119 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits |
| 1120 : kWRegSizeInBits; |
| 1117 int64_t op2 = reg(reg_size, instr->Rm()); | 1121 int64_t op2 = reg(reg_size, instr->Rm()); |
| 1118 int64_t new_val; | 1122 int64_t new_val; |
| 1119 | 1123 |
| 1120 if ((instr->Mask(AddSubOpMask) == SUB) || instr->Mask(AddSubOpMask) == SUBS) { | 1124 if ((instr->Mask(AddSubOpMask) == SUB) || instr->Mask(AddSubOpMask) == SUBS) { |
| 1121 op2 = ~op2; | 1125 op2 = ~op2; |
| 1122 } | 1126 } |
| 1123 | 1127 |
| 1124 new_val = AddWithCarry(reg_size, | 1128 new_val = AddWithCarry(reg_size, |
| 1125 instr->FlagsUpdate(), | 1129 instr->FlagsUpdate(), |
| 1126 reg(reg_size, instr->Rn()), | 1130 reg(reg_size, instr->Rn()), |
| 1127 op2, | 1131 op2, |
| 1128 C()); | 1132 C()); |
| 1129 | 1133 |
| 1130 set_reg(reg_size, instr->Rd(), new_val); | 1134 set_reg(reg_size, instr->Rd(), new_val); |
| 1131 } | 1135 } |
| 1132 | 1136 |
| 1133 | 1137 |
| 1134 void Simulator::VisitLogicalShifted(Instruction* instr) { | 1138 void Simulator::VisitLogicalShifted(Instruction* instr) { |
| 1135 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; | 1139 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits |
| 1140 : kWRegSizeInBits; |
| 1136 Shift shift_type = static_cast<Shift>(instr->ShiftDP()); | 1141 Shift shift_type = static_cast<Shift>(instr->ShiftDP()); |
| 1137 unsigned shift_amount = instr->ImmDPShift(); | 1142 unsigned shift_amount = instr->ImmDPShift(); |
| 1138 int64_t op2 = ShiftOperand(reg_size, reg(reg_size, instr->Rm()), shift_type, | 1143 int64_t op2 = ShiftOperand(reg_size, reg(reg_size, instr->Rm()), shift_type, |
| 1139 shift_amount); | 1144 shift_amount); |
| 1140 if (instr->Mask(NOT) == NOT) { | 1145 if (instr->Mask(NOT) == NOT) { |
| 1141 op2 = ~op2; | 1146 op2 = ~op2; |
| 1142 } | 1147 } |
| 1143 LogicalHelper(instr, op2); | 1148 LogicalHelper(instr, op2); |
| 1144 } | 1149 } |
| 1145 | 1150 |
| 1146 | 1151 |
| 1147 void Simulator::VisitLogicalImmediate(Instruction* instr) { | 1152 void Simulator::VisitLogicalImmediate(Instruction* instr) { |
| 1148 LogicalHelper(instr, instr->ImmLogical()); | 1153 LogicalHelper(instr, instr->ImmLogical()); |
| 1149 } | 1154 } |
| 1150 | 1155 |
| 1151 | 1156 |
| 1152 void Simulator::LogicalHelper(Instruction* instr, int64_t op2) { | 1157 void Simulator::LogicalHelper(Instruction* instr, int64_t op2) { |
| 1153 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; | 1158 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits |
| 1159 : kWRegSizeInBits; |
| 1154 int64_t op1 = reg(reg_size, instr->Rn()); | 1160 int64_t op1 = reg(reg_size, instr->Rn()); |
| 1155 int64_t result = 0; | 1161 int64_t result = 0; |
| 1156 bool update_flags = false; | 1162 bool update_flags = false; |
| 1157 | 1163 |
| 1158 // Switch on the logical operation, stripping out the NOT bit, as it has a | 1164 // Switch on the logical operation, stripping out the NOT bit, as it has a |
| 1159 // different meaning for logical immediate instructions. | 1165 // different meaning for logical immediate instructions. |
| 1160 switch (instr->Mask(LogicalOpMask & ~NOT)) { | 1166 switch (instr->Mask(LogicalOpMask & ~NOT)) { |
| 1161 case ANDS: update_flags = true; // Fall through. | 1167 case ANDS: update_flags = true; // Fall through. |
| 1162 case AND: result = op1 & op2; break; | 1168 case AND: result = op1 & op2; break; |
| 1163 case ORR: result = op1 | op2; break; | 1169 case ORR: result = op1 | op2; break; |
| 1164 case EOR: result = op1 ^ op2; break; | 1170 case EOR: result = op1 ^ op2; break; |
| 1165 default: | 1171 default: |
| 1166 UNIMPLEMENTED(); | 1172 UNIMPLEMENTED(); |
| 1167 } | 1173 } |
| 1168 | 1174 |
| 1169 if (update_flags) { | 1175 if (update_flags) { |
| 1170 nzcv().SetN(CalcNFlag(result, reg_size)); | 1176 nzcv().SetN(CalcNFlag(result, reg_size)); |
| 1171 nzcv().SetZ(CalcZFlag(result)); | 1177 nzcv().SetZ(CalcZFlag(result)); |
| 1172 nzcv().SetC(0); | 1178 nzcv().SetC(0); |
| 1173 nzcv().SetV(0); | 1179 nzcv().SetV(0); |
| 1174 } | 1180 } |
| 1175 | 1181 |
| 1176 set_reg(reg_size, instr->Rd(), result, instr->RdMode()); | 1182 set_reg(reg_size, instr->Rd(), result, instr->RdMode()); |
| 1177 } | 1183 } |
| 1178 | 1184 |
| 1179 | 1185 |
| 1180 void Simulator::VisitConditionalCompareRegister(Instruction* instr) { | 1186 void Simulator::VisitConditionalCompareRegister(Instruction* instr) { |
| 1181 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; | 1187 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits |
| 1188 : kWRegSizeInBits; |
| 1182 ConditionalCompareHelper(instr, reg(reg_size, instr->Rm())); | 1189 ConditionalCompareHelper(instr, reg(reg_size, instr->Rm())); |
| 1183 } | 1190 } |
| 1184 | 1191 |
| 1185 | 1192 |
| 1186 void Simulator::VisitConditionalCompareImmediate(Instruction* instr) { | 1193 void Simulator::VisitConditionalCompareImmediate(Instruction* instr) { |
| 1187 ConditionalCompareHelper(instr, instr->ImmCondCmp()); | 1194 ConditionalCompareHelper(instr, instr->ImmCondCmp()); |
| 1188 } | 1195 } |
| 1189 | 1196 |
| 1190 | 1197 |
| 1191 void Simulator::ConditionalCompareHelper(Instruction* instr, int64_t op2) { | 1198 void Simulator::ConditionalCompareHelper(Instruction* instr, int64_t op2) { |
| 1192 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; | 1199 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits |
| 1200 : kWRegSizeInBits; |
| 1193 int64_t op1 = reg(reg_size, instr->Rn()); | 1201 int64_t op1 = reg(reg_size, instr->Rn()); |
| 1194 | 1202 |
| 1195 if (ConditionPassed(static_cast<Condition>(instr->Condition()))) { | 1203 if (ConditionPassed(static_cast<Condition>(instr->Condition()))) { |
| 1196 // If the condition passes, set the status flags to the result of comparing | 1204 // If the condition passes, set the status flags to the result of comparing |
| 1197 // the operands. | 1205 // the operands. |
| 1198 if (instr->Mask(ConditionalCompareMask) == CCMP) { | 1206 if (instr->Mask(ConditionalCompareMask) == CCMP) { |
| 1199 AddWithCarry(reg_size, true, op1, ~op2, 1); | 1207 AddWithCarry(reg_size, true, op1, ~op2, 1); |
| 1200 } else { | 1208 } else { |
| 1201 ASSERT(instr->Mask(ConditionalCompareMask) == CCMN); | 1209 ASSERT(instr->Mask(ConditionalCompareMask) == CCMN); |
| 1202 AddWithCarry(reg_size, true, op1, op2, 0); | 1210 AddWithCarry(reg_size, true, op1, op2, 0); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1227 void Simulator::VisitLoadStorePostIndex(Instruction* instr) { | 1235 void Simulator::VisitLoadStorePostIndex(Instruction* instr) { |
| 1228 LoadStoreHelper(instr, instr->ImmLS(), PostIndex); | 1236 LoadStoreHelper(instr, instr->ImmLS(), PostIndex); |
| 1229 } | 1237 } |
| 1230 | 1238 |
| 1231 | 1239 |
| 1232 void Simulator::VisitLoadStoreRegisterOffset(Instruction* instr) { | 1240 void Simulator::VisitLoadStoreRegisterOffset(Instruction* instr) { |
| 1233 Extend ext = static_cast<Extend>(instr->ExtendMode()); | 1241 Extend ext = static_cast<Extend>(instr->ExtendMode()); |
| 1234 ASSERT((ext == UXTW) || (ext == UXTX) || (ext == SXTW) || (ext == SXTX)); | 1242 ASSERT((ext == UXTW) || (ext == UXTX) || (ext == SXTW) || (ext == SXTX)); |
| 1235 unsigned shift_amount = instr->ImmShiftLS() * instr->SizeLS(); | 1243 unsigned shift_amount = instr->ImmShiftLS() * instr->SizeLS(); |
| 1236 | 1244 |
| 1237 int64_t offset = ExtendValue(kXRegSize, xreg(instr->Rm()), ext, | 1245 int64_t offset = ExtendValue(kXRegSizeInBits, xreg(instr->Rm()), ext, |
| 1238 shift_amount); | 1246 shift_amount); |
| 1239 LoadStoreHelper(instr, offset, Offset); | 1247 LoadStoreHelper(instr, offset, Offset); |
| 1240 } | 1248 } |
| 1241 | 1249 |
| 1242 | 1250 |
| 1243 void Simulator::LoadStoreHelper(Instruction* instr, | 1251 void Simulator::LoadStoreHelper(Instruction* instr, |
| 1244 int64_t offset, | 1252 int64_t offset, |
| 1245 AddrMode addrmode) { | 1253 AddrMode addrmode) { |
| 1246 unsigned srcdst = instr->Rt(); | 1254 unsigned srcdst = instr->Rt(); |
| 1247 unsigned addr_reg = instr->Rn(); | 1255 unsigned addr_reg = instr->Rn(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1268 switch (op) { | 1276 switch (op) { |
| 1269 case LDRB_w: | 1277 case LDRB_w: |
| 1270 case LDRH_w: | 1278 case LDRH_w: |
| 1271 case LDR_w: | 1279 case LDR_w: |
| 1272 case LDR_x: set_xreg(srcdst, MemoryRead(address, num_bytes)); break; | 1280 case LDR_x: set_xreg(srcdst, MemoryRead(address, num_bytes)); break; |
| 1273 case STRB_w: | 1281 case STRB_w: |
| 1274 case STRH_w: | 1282 case STRH_w: |
| 1275 case STR_w: | 1283 case STR_w: |
| 1276 case STR_x: MemoryWrite(address, xreg(srcdst), num_bytes); break; | 1284 case STR_x: MemoryWrite(address, xreg(srcdst), num_bytes); break; |
| 1277 case LDRSB_w: { | 1285 case LDRSB_w: { |
| 1278 set_wreg(srcdst, ExtendValue(kWRegSize, MemoryRead8(address), SXTB)); | 1286 set_wreg(srcdst, |
| 1287 ExtendValue(kWRegSizeInBits, MemoryRead8(address), SXTB)); |
| 1279 break; | 1288 break; |
| 1280 } | 1289 } |
| 1281 case LDRSB_x: { | 1290 case LDRSB_x: { |
| 1282 set_xreg(srcdst, ExtendValue(kXRegSize, MemoryRead8(address), SXTB)); | 1291 set_xreg(srcdst, |
| 1292 ExtendValue(kXRegSizeInBits, MemoryRead8(address), SXTB)); |
| 1283 break; | 1293 break; |
| 1284 } | 1294 } |
| 1285 case LDRSH_w: { | 1295 case LDRSH_w: { |
| 1286 set_wreg(srcdst, ExtendValue(kWRegSize, MemoryRead16(address), SXTH)); | 1296 set_wreg(srcdst, |
| 1297 ExtendValue(kWRegSizeInBits, MemoryRead16(address), SXTH)); |
| 1287 break; | 1298 break; |
| 1288 } | 1299 } |
| 1289 case LDRSH_x: { | 1300 case LDRSH_x: { |
| 1290 set_xreg(srcdst, ExtendValue(kXRegSize, MemoryRead16(address), SXTH)); | 1301 set_xreg(srcdst, |
| 1302 ExtendValue(kXRegSizeInBits, MemoryRead16(address), SXTH)); |
| 1291 break; | 1303 break; |
| 1292 } | 1304 } |
| 1293 case LDRSW_x: { | 1305 case LDRSW_x: { |
| 1294 set_xreg(srcdst, ExtendValue(kXRegSize, MemoryRead32(address), SXTW)); | 1306 set_xreg(srcdst, |
| 1307 ExtendValue(kXRegSizeInBits, MemoryRead32(address), SXTW)); |
| 1295 break; | 1308 break; |
| 1296 } | 1309 } |
| 1297 case LDR_s: set_sreg(srcdst, MemoryReadFP32(address)); break; | 1310 case LDR_s: set_sreg(srcdst, MemoryReadFP32(address)); break; |
| 1298 case LDR_d: set_dreg(srcdst, MemoryReadFP64(address)); break; | 1311 case LDR_d: set_dreg(srcdst, MemoryReadFP64(address)); break; |
| 1299 case STR_s: MemoryWriteFP32(address, sreg(srcdst)); break; | 1312 case STR_s: MemoryWriteFP32(address, sreg(srcdst)); break; |
| 1300 case STR_d: MemoryWriteFP64(address, dreg(srcdst)); break; | 1313 case STR_d: MemoryWriteFP64(address, dreg(srcdst)); break; |
| 1301 default: UNIMPLEMENTED(); | 1314 default: UNIMPLEMENTED(); |
| 1302 } | 1315 } |
| 1303 | 1316 |
| 1304 // Handle the writeback for loads after the load to ensure safe pop | 1317 // Handle the writeback for loads after the load to ensure safe pop |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1365 | 1378 |
| 1366 LoadStorePairOp op = | 1379 LoadStorePairOp op = |
| 1367 static_cast<LoadStorePairOp>(instr->Mask(LoadStorePairMask)); | 1380 static_cast<LoadStorePairOp>(instr->Mask(LoadStorePairMask)); |
| 1368 | 1381 |
| 1369 // 'rt' and 'rt2' can only be aliased for stores. | 1382 // 'rt' and 'rt2' can only be aliased for stores. |
| 1370 ASSERT(((op & LoadStorePairLBit) == 0) || (rt != rt2)); | 1383 ASSERT(((op & LoadStorePairLBit) == 0) || (rt != rt2)); |
| 1371 | 1384 |
| 1372 switch (op) { | 1385 switch (op) { |
| 1373 case LDP_w: { | 1386 case LDP_w: { |
| 1374 set_wreg(rt, MemoryRead32(address)); | 1387 set_wreg(rt, MemoryRead32(address)); |
| 1375 set_wreg(rt2, MemoryRead32(address + kWRegSizeInBytes)); | 1388 set_wreg(rt2, MemoryRead32(address + kWRegSize)); |
| 1376 break; | 1389 break; |
| 1377 } | 1390 } |
| 1378 case LDP_s: { | 1391 case LDP_s: { |
| 1379 set_sreg(rt, MemoryReadFP32(address)); | 1392 set_sreg(rt, MemoryReadFP32(address)); |
| 1380 set_sreg(rt2, MemoryReadFP32(address + kSRegSizeInBytes)); | 1393 set_sreg(rt2, MemoryReadFP32(address + kSRegSize)); |
| 1381 break; | 1394 break; |
| 1382 } | 1395 } |
| 1383 case LDP_x: { | 1396 case LDP_x: { |
| 1384 set_xreg(rt, MemoryRead64(address)); | 1397 set_xreg(rt, MemoryRead64(address)); |
| 1385 set_xreg(rt2, MemoryRead64(address + kXRegSizeInBytes)); | 1398 set_xreg(rt2, MemoryRead64(address + kXRegSize)); |
| 1386 break; | 1399 break; |
| 1387 } | 1400 } |
| 1388 case LDP_d: { | 1401 case LDP_d: { |
| 1389 set_dreg(rt, MemoryReadFP64(address)); | 1402 set_dreg(rt, MemoryReadFP64(address)); |
| 1390 set_dreg(rt2, MemoryReadFP64(address + kDRegSizeInBytes)); | 1403 set_dreg(rt2, MemoryReadFP64(address + kDRegSize)); |
| 1391 break; | 1404 break; |
| 1392 } | 1405 } |
| 1393 case LDPSW_x: { | 1406 case LDPSW_x: { |
| 1394 set_xreg(rt, ExtendValue(kXRegSize, MemoryRead32(address), SXTW)); | 1407 set_xreg(rt, ExtendValue(kXRegSizeInBits, MemoryRead32(address), SXTW)); |
| 1395 set_xreg(rt2, ExtendValue(kXRegSize, | 1408 set_xreg(rt2, ExtendValue(kXRegSizeInBits, |
| 1396 MemoryRead32(address + kWRegSizeInBytes), SXTW)); | 1409 MemoryRead32(address + kWRegSize), SXTW)); |
| 1397 break; | 1410 break; |
| 1398 } | 1411 } |
| 1399 case STP_w: { | 1412 case STP_w: { |
| 1400 MemoryWrite32(address, wreg(rt)); | 1413 MemoryWrite32(address, wreg(rt)); |
| 1401 MemoryWrite32(address + kWRegSizeInBytes, wreg(rt2)); | 1414 MemoryWrite32(address + kWRegSize, wreg(rt2)); |
| 1402 break; | 1415 break; |
| 1403 } | 1416 } |
| 1404 case STP_s: { | 1417 case STP_s: { |
| 1405 MemoryWriteFP32(address, sreg(rt)); | 1418 MemoryWriteFP32(address, sreg(rt)); |
| 1406 MemoryWriteFP32(address + kSRegSizeInBytes, sreg(rt2)); | 1419 MemoryWriteFP32(address + kSRegSize, sreg(rt2)); |
| 1407 break; | 1420 break; |
| 1408 } | 1421 } |
| 1409 case STP_x: { | 1422 case STP_x: { |
| 1410 MemoryWrite64(address, xreg(rt)); | 1423 MemoryWrite64(address, xreg(rt)); |
| 1411 MemoryWrite64(address + kXRegSizeInBytes, xreg(rt2)); | 1424 MemoryWrite64(address + kXRegSize, xreg(rt2)); |
| 1412 break; | 1425 break; |
| 1413 } | 1426 } |
| 1414 case STP_d: { | 1427 case STP_d: { |
| 1415 MemoryWriteFP64(address, dreg(rt)); | 1428 MemoryWriteFP64(address, dreg(rt)); |
| 1416 MemoryWriteFP64(address + kDRegSizeInBytes, dreg(rt2)); | 1429 MemoryWriteFP64(address + kDRegSize, dreg(rt2)); |
| 1417 break; | 1430 break; |
| 1418 } | 1431 } |
| 1419 default: UNREACHABLE(); | 1432 default: UNREACHABLE(); |
| 1420 } | 1433 } |
| 1421 | 1434 |
| 1422 // Handle the writeback for loads after the load to ensure safe pop | 1435 // Handle the writeback for loads after the load to ensure safe pop |
| 1423 // operation even when interrupted in the middle of it. The stack pointer | 1436 // operation even when interrupted in the middle of it. The stack pointer |
| 1424 // is only updated after the load so pop(fp) will never break the invariant | 1437 // is only updated after the load so pop(fp) will never break the invariant |
| 1425 // sp <= fp expected while walking the stack in the sampler. | 1438 // sp <= fp expected while walking the stack in the sampler. |
| 1426 if (instr->IsLoad()) { | 1439 if (instr->IsLoad()) { |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1617 case CSEL_x: break; | 1630 case CSEL_x: break; |
| 1618 case CSINC_w: | 1631 case CSINC_w: |
| 1619 case CSINC_x: new_val++; break; | 1632 case CSINC_x: new_val++; break; |
| 1620 case CSINV_w: | 1633 case CSINV_w: |
| 1621 case CSINV_x: new_val = ~new_val; break; | 1634 case CSINV_x: new_val = ~new_val; break; |
| 1622 case CSNEG_w: | 1635 case CSNEG_w: |
| 1623 case CSNEG_x: new_val = -new_val; break; | 1636 case CSNEG_x: new_val = -new_val; break; |
| 1624 default: UNIMPLEMENTED(); | 1637 default: UNIMPLEMENTED(); |
| 1625 } | 1638 } |
| 1626 } | 1639 } |
| 1627 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; | 1640 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits |
| 1641 : kWRegSizeInBits; |
| 1628 set_reg(reg_size, instr->Rd(), new_val); | 1642 set_reg(reg_size, instr->Rd(), new_val); |
| 1629 } | 1643 } |
| 1630 | 1644 |
| 1631 | 1645 |
| 1632 void Simulator::VisitDataProcessing1Source(Instruction* instr) { | 1646 void Simulator::VisitDataProcessing1Source(Instruction* instr) { |
| 1633 unsigned dst = instr->Rd(); | 1647 unsigned dst = instr->Rd(); |
| 1634 unsigned src = instr->Rn(); | 1648 unsigned src = instr->Rn(); |
| 1635 | 1649 |
| 1636 switch (instr->Mask(DataProcessing1SourceMask)) { | 1650 switch (instr->Mask(DataProcessing1SourceMask)) { |
| 1637 case RBIT_w: set_wreg(dst, ReverseBits(wreg(src), kWRegSize)); break; | 1651 case RBIT_w: set_wreg(dst, ReverseBits(wreg(src), kWRegSizeInBits)); break; |
| 1638 case RBIT_x: set_xreg(dst, ReverseBits(xreg(src), kXRegSize)); break; | 1652 case RBIT_x: set_xreg(dst, ReverseBits(xreg(src), kXRegSizeInBits)); break; |
| 1639 case REV16_w: set_wreg(dst, ReverseBytes(wreg(src), Reverse16)); break; | 1653 case REV16_w: set_wreg(dst, ReverseBytes(wreg(src), Reverse16)); break; |
| 1640 case REV16_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse16)); break; | 1654 case REV16_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse16)); break; |
| 1641 case REV_w: set_wreg(dst, ReverseBytes(wreg(src), Reverse32)); break; | 1655 case REV_w: set_wreg(dst, ReverseBytes(wreg(src), Reverse32)); break; |
| 1642 case REV32_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse32)); break; | 1656 case REV32_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse32)); break; |
| 1643 case REV_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse64)); break; | 1657 case REV_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse64)); break; |
| 1644 case CLZ_w: set_wreg(dst, CountLeadingZeros(wreg(src), kWRegSize)); break; | 1658 case CLZ_w: set_wreg(dst, CountLeadingZeros(wreg(src), kWRegSizeInBits)); |
| 1645 case CLZ_x: set_xreg(dst, CountLeadingZeros(xreg(src), kXRegSize)); break; | 1659 break; |
| 1660 case CLZ_x: set_xreg(dst, CountLeadingZeros(xreg(src), kXRegSizeInBits)); |
| 1661 break; |
| 1646 case CLS_w: { | 1662 case CLS_w: { |
| 1647 set_wreg(dst, CountLeadingSignBits(wreg(src), kWRegSize)); | 1663 set_wreg(dst, CountLeadingSignBits(wreg(src), kWRegSizeInBits)); |
| 1648 break; | 1664 break; |
| 1649 } | 1665 } |
| 1650 case CLS_x: { | 1666 case CLS_x: { |
| 1651 set_xreg(dst, CountLeadingSignBits(xreg(src), kXRegSize)); | 1667 set_xreg(dst, CountLeadingSignBits(xreg(src), kXRegSizeInBits)); |
| 1652 break; | 1668 break; |
| 1653 } | 1669 } |
| 1654 default: UNIMPLEMENTED(); | 1670 default: UNIMPLEMENTED(); |
| 1655 } | 1671 } |
| 1656 } | 1672 } |
| 1657 | 1673 |
| 1658 | 1674 |
| 1659 uint64_t Simulator::ReverseBits(uint64_t value, unsigned num_bits) { | 1675 uint64_t Simulator::ReverseBits(uint64_t value, unsigned num_bits) { |
| 1660 ASSERT((num_bits == kWRegSize) || (num_bits == kXRegSize)); | 1676 ASSERT((num_bits == kWRegSizeInBits) || (num_bits == kXRegSizeInBits)); |
| 1661 uint64_t result = 0; | 1677 uint64_t result = 0; |
| 1662 for (unsigned i = 0; i < num_bits; i++) { | 1678 for (unsigned i = 0; i < num_bits; i++) { |
| 1663 result = (result << 1) | (value & 1); | 1679 result = (result << 1) | (value & 1); |
| 1664 value >>= 1; | 1680 value >>= 1; |
| 1665 } | 1681 } |
| 1666 return result; | 1682 return result; |
| 1667 } | 1683 } |
| 1668 | 1684 |
| 1669 | 1685 |
| 1670 uint64_t Simulator::ReverseBytes(uint64_t value, ReverseByteMode mode) { | 1686 uint64_t Simulator::ReverseBytes(uint64_t value, ReverseByteMode mode) { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1755 case LSLV_x: shift_op = LSL; break; | 1771 case LSLV_x: shift_op = LSL; break; |
| 1756 case LSRV_w: | 1772 case LSRV_w: |
| 1757 case LSRV_x: shift_op = LSR; break; | 1773 case LSRV_x: shift_op = LSR; break; |
| 1758 case ASRV_w: | 1774 case ASRV_w: |
| 1759 case ASRV_x: shift_op = ASR; break; | 1775 case ASRV_x: shift_op = ASR; break; |
| 1760 case RORV_w: | 1776 case RORV_w: |
| 1761 case RORV_x: shift_op = ROR; break; | 1777 case RORV_x: shift_op = ROR; break; |
| 1762 default: UNIMPLEMENTED(); | 1778 default: UNIMPLEMENTED(); |
| 1763 } | 1779 } |
| 1764 | 1780 |
| 1765 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; | 1781 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits |
| 1782 : kWRegSizeInBits; |
| 1766 if (shift_op != NO_SHIFT) { | 1783 if (shift_op != NO_SHIFT) { |
| 1767 // Shift distance encoded in the least-significant five/six bits of the | 1784 // Shift distance encoded in the least-significant five/six bits of the |
| 1768 // register. | 1785 // register. |
| 1769 int mask = (instr->SixtyFourBits() == 1) ? 0x3f : 0x1f; | 1786 int mask = (instr->SixtyFourBits() == 1) ? 0x3f : 0x1f; |
| 1770 unsigned shift = wreg(instr->Rm()) & mask; | 1787 unsigned shift = wreg(instr->Rm()) & mask; |
| 1771 result = ShiftOperand(reg_size, reg(reg_size, instr->Rn()), shift_op, | 1788 result = ShiftOperand(reg_size, reg(reg_size, instr->Rn()), shift_op, |
| 1772 shift); | 1789 shift); |
| 1773 } | 1790 } |
| 1774 set_reg(reg_size, instr->Rd(), result); | 1791 set_reg(reg_size, instr->Rd(), result); |
| 1775 } | 1792 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1791 t = u1 * v0 + (w0 >> 32); | 1808 t = u1 * v0 + (w0 >> 32); |
| 1792 w1 = t & 0xffffffffL; | 1809 w1 = t & 0xffffffffL; |
| 1793 w2 = t >> 32; | 1810 w2 = t >> 32; |
| 1794 w1 = u0 * v1 + w1; | 1811 w1 = u0 * v1 + w1; |
| 1795 | 1812 |
| 1796 return u1 * v1 + w2 + (w1 >> 32); | 1813 return u1 * v1 + w2 + (w1 >> 32); |
| 1797 } | 1814 } |
| 1798 | 1815 |
| 1799 | 1816 |
| 1800 void Simulator::VisitDataProcessing3Source(Instruction* instr) { | 1817 void Simulator::VisitDataProcessing3Source(Instruction* instr) { |
| 1801 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; | 1818 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits |
| 1819 : kWRegSizeInBits; |
| 1802 | 1820 |
| 1803 int64_t result = 0; | 1821 int64_t result = 0; |
| 1804 // Extract and sign- or zero-extend 32-bit arguments for widening operations. | 1822 // Extract and sign- or zero-extend 32-bit arguments for widening operations. |
| 1805 uint64_t rn_u32 = reg<uint32_t>(instr->Rn()); | 1823 uint64_t rn_u32 = reg<uint32_t>(instr->Rn()); |
| 1806 uint64_t rm_u32 = reg<uint32_t>(instr->Rm()); | 1824 uint64_t rm_u32 = reg<uint32_t>(instr->Rm()); |
| 1807 int64_t rn_s32 = reg<int32_t>(instr->Rn()); | 1825 int64_t rn_s32 = reg<int32_t>(instr->Rn()); |
| 1808 int64_t rm_s32 = reg<int32_t>(instr->Rm()); | 1826 int64_t rm_s32 = reg<int32_t>(instr->Rm()); |
| 1809 switch (instr->Mask(DataProcessing3SourceMask)) { | 1827 switch (instr->Mask(DataProcessing3SourceMask)) { |
| 1810 case MADD_w: | 1828 case MADD_w: |
| 1811 case MADD_x: | 1829 case MADD_x: |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1823 ASSERT(instr->Ra() == kZeroRegCode); | 1841 ASSERT(instr->Ra() == kZeroRegCode); |
| 1824 result = MultiplyHighSigned(xreg(instr->Rn()), xreg(instr->Rm())); | 1842 result = MultiplyHighSigned(xreg(instr->Rn()), xreg(instr->Rm())); |
| 1825 break; | 1843 break; |
| 1826 default: UNIMPLEMENTED(); | 1844 default: UNIMPLEMENTED(); |
| 1827 } | 1845 } |
| 1828 set_reg(reg_size, instr->Rd(), result); | 1846 set_reg(reg_size, instr->Rd(), result); |
| 1829 } | 1847 } |
| 1830 | 1848 |
| 1831 | 1849 |
| 1832 void Simulator::VisitBitfield(Instruction* instr) { | 1850 void Simulator::VisitBitfield(Instruction* instr) { |
| 1833 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; | 1851 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits |
| 1852 : kWRegSizeInBits; |
| 1834 int64_t reg_mask = instr->SixtyFourBits() ? kXRegMask : kWRegMask; | 1853 int64_t reg_mask = instr->SixtyFourBits() ? kXRegMask : kWRegMask; |
| 1835 int64_t R = instr->ImmR(); | 1854 int64_t R = instr->ImmR(); |
| 1836 int64_t S = instr->ImmS(); | 1855 int64_t S = instr->ImmS(); |
| 1837 int64_t diff = S - R; | 1856 int64_t diff = S - R; |
| 1838 int64_t mask; | 1857 int64_t mask; |
| 1839 if (diff >= 0) { | 1858 if (diff >= 0) { |
| 1840 mask = diff < reg_size - 1 ? (1L << (diff + 1)) - 1 | 1859 mask = diff < reg_size - 1 ? (1L << (diff + 1)) - 1 |
| 1841 : reg_mask; | 1860 : reg_mask; |
| 1842 } else { | 1861 } else { |
| 1843 mask = ((1L << (S + 1)) - 1); | 1862 mask = ((1L << (S + 1)) - 1); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1877 | 1896 |
| 1878 // Merge sign extension, dest/zero and bitfield. | 1897 // Merge sign extension, dest/zero and bitfield. |
| 1879 result = signbits | (result & mask) | (dst & ~mask); | 1898 result = signbits | (result & mask) | (dst & ~mask); |
| 1880 | 1899 |
| 1881 set_reg(reg_size, instr->Rd(), result); | 1900 set_reg(reg_size, instr->Rd(), result); |
| 1882 } | 1901 } |
| 1883 | 1902 |
| 1884 | 1903 |
| 1885 void Simulator::VisitExtract(Instruction* instr) { | 1904 void Simulator::VisitExtract(Instruction* instr) { |
| 1886 unsigned lsb = instr->ImmS(); | 1905 unsigned lsb = instr->ImmS(); |
| 1887 unsigned reg_size = (instr->SixtyFourBits() == 1) ? kXRegSize | 1906 unsigned reg_size = (instr->SixtyFourBits() == 1) ? kXRegSizeInBits |
| 1888 : kWRegSize; | 1907 : kWRegSizeInBits; |
| 1889 set_reg(reg_size, | 1908 set_reg(reg_size, |
| 1890 instr->Rd(), | 1909 instr->Rd(), |
| 1891 (static_cast<uint64_t>(reg(reg_size, instr->Rm())) >> lsb) | | 1910 (static_cast<uint64_t>(reg(reg_size, instr->Rm())) >> lsb) | |
| 1892 (reg(reg_size, instr->Rn()) << (reg_size - lsb))); | 1911 (reg(reg_size, instr->Rn()) << (reg_size - lsb))); |
| 1893 } | 1912 } |
| 1894 | 1913 |
| 1895 | 1914 |
| 1896 void Simulator::VisitFPImmediate(Instruction* instr) { | 1915 void Simulator::VisitFPImmediate(Instruction* instr) { |
| 1897 AssertSupportedFPCR(); | 1916 AssertSupportedFPCR(); |
| 1898 | 1917 |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2074 } else if (value < 0.0) { | 2093 } else if (value < 0.0) { |
| 2075 return 0; | 2094 return 0; |
| 2076 } | 2095 } |
| 2077 return std::isnan(value) ? 0 : static_cast<uint64_t>(value); | 2096 return std::isnan(value) ? 0 : static_cast<uint64_t>(value); |
| 2078 } | 2097 } |
| 2079 | 2098 |
| 2080 | 2099 |
| 2081 void Simulator::VisitFPCompare(Instruction* instr) { | 2100 void Simulator::VisitFPCompare(Instruction* instr) { |
| 2082 AssertSupportedFPCR(); | 2101 AssertSupportedFPCR(); |
| 2083 | 2102 |
| 2084 unsigned reg_size = instr->FPType() == FP32 ? kSRegSize : kDRegSize; | 2103 unsigned reg_size = instr->FPType() == FP32 ? kSRegSizeInBits |
| 2104 : kDRegSizeInBits; |
| 2085 double fn_val = fpreg(reg_size, instr->Rn()); | 2105 double fn_val = fpreg(reg_size, instr->Rn()); |
| 2086 | 2106 |
| 2087 switch (instr->Mask(FPCompareMask)) { | 2107 switch (instr->Mask(FPCompareMask)) { |
| 2088 case FCMP_s: | 2108 case FCMP_s: |
| 2089 case FCMP_d: FPCompare(fn_val, fpreg(reg_size, instr->Rm())); break; | 2109 case FCMP_d: FPCompare(fn_val, fpreg(reg_size, instr->Rm())); break; |
| 2090 case FCMP_s_zero: | 2110 case FCMP_s_zero: |
| 2091 case FCMP_d_zero: FPCompare(fn_val, 0.0); break; | 2111 case FCMP_d_zero: FPCompare(fn_val, 0.0); break; |
| 2092 default: UNIMPLEMENTED(); | 2112 default: UNIMPLEMENTED(); |
| 2093 } | 2113 } |
| 2094 } | 2114 } |
| 2095 | 2115 |
| 2096 | 2116 |
| 2097 void Simulator::VisitFPConditionalCompare(Instruction* instr) { | 2117 void Simulator::VisitFPConditionalCompare(Instruction* instr) { |
| 2098 AssertSupportedFPCR(); | 2118 AssertSupportedFPCR(); |
| 2099 | 2119 |
| 2100 switch (instr->Mask(FPConditionalCompareMask)) { | 2120 switch (instr->Mask(FPConditionalCompareMask)) { |
| 2101 case FCCMP_s: | 2121 case FCCMP_s: |
| 2102 case FCCMP_d: { | 2122 case FCCMP_d: { |
| 2103 if (ConditionPassed(static_cast<Condition>(instr->Condition()))) { | 2123 if (ConditionPassed(static_cast<Condition>(instr->Condition()))) { |
| 2104 // If the condition passes, set the status flags to the result of | 2124 // If the condition passes, set the status flags to the result of |
| 2105 // comparing the operands. | 2125 // comparing the operands. |
| 2106 unsigned reg_size = instr->FPType() == FP32 ? kSRegSize : kDRegSize; | 2126 unsigned reg_size = instr->FPType() == FP32 ? kSRegSizeInBits |
| 2127 : kDRegSizeInBits; |
| 2107 FPCompare(fpreg(reg_size, instr->Rn()), fpreg(reg_size, instr->Rm())); | 2128 FPCompare(fpreg(reg_size, instr->Rn()), fpreg(reg_size, instr->Rm())); |
| 2108 } else { | 2129 } else { |
| 2109 // If the condition fails, set the status flags to the nzcv immediate. | 2130 // If the condition fails, set the status flags to the nzcv immediate. |
| 2110 nzcv().SetFlags(instr->Nzcv()); | 2131 nzcv().SetFlags(instr->Nzcv()); |
| 2111 } | 2132 } |
| 2112 break; | 2133 break; |
| 2113 } | 2134 } |
| 2114 default: UNIMPLEMENTED(); | 2135 default: UNIMPLEMENTED(); |
| 2115 } | 2136 } |
| 2116 } | 2137 } |
| (...skipping 1312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3429 default: | 3450 default: |
| 3430 UNIMPLEMENTED(); | 3451 UNIMPLEMENTED(); |
| 3431 } | 3452 } |
| 3432 } | 3453 } |
| 3433 | 3454 |
| 3434 #endif // USE_SIMULATOR | 3455 #endif // USE_SIMULATOR |
| 3435 | 3456 |
| 3436 } } // namespace v8::internal | 3457 } } // namespace v8::internal |
| 3437 | 3458 |
| 3438 #endif // V8_TARGET_ARCH_A64 | 3459 #endif // V8_TARGET_ARCH_A64 |
| OLD | NEW |