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 |