Index: src/arm64/simulator-arm64.cc |
diff --git a/src/arm64/simulator-arm64.cc b/src/arm64/simulator-arm64.cc |
index 819a89765d03c4b5c5925b280d0de3a6be976381..54ad4b08b29c65bb4c7a5d59c077bfd2a68f875d 100644 |
--- a/src/arm64/simulator-arm64.cc |
+++ b/src/arm64/simulator-arm64.cc |
@@ -903,10 +903,11 @@ T Simulator::ShiftOperand(T value, Shift shift_type, unsigned amount) { |
return static_cast<unsignedT>(value) >> amount; |
case ASR: |
return value >> amount; |
- case ROR: |
+ case ROR: { |
+ unsignedT mask = (static_cast<unsignedT>(1) << amount) - 1; |
return (static_cast<unsignedT>(value) >> amount) | |
- ((value & ((1L << amount) - 1L)) << |
- (sizeof(unsignedT) * 8 - amount)); |
+ ((value & mask) << (sizeof(mask) * 8 - amount)); |
+ } |
default: |
UNIMPLEMENTED(); |
return 0; |
@@ -1399,7 +1400,8 @@ void Simulator::VisitAddSubShifted(Instruction* instr) { |
int64_t op2 = ShiftOperand(xreg(instr->Rm()), shift_type, shift_amount); |
AddSubHelper(instr, op2); |
} else { |
- int32_t op2 = ShiftOperand(wreg(instr->Rm()), shift_type, shift_amount); |
+ int32_t op2 = static_cast<int32_t>( |
+ ShiftOperand(wreg(instr->Rm()), shift_type, shift_amount)); |
AddSubHelper(instr, op2); |
} |
} |
@@ -1410,7 +1412,7 @@ void Simulator::VisitAddSubImmediate(Instruction* instr) { |
if (instr->SixtyFourBits()) { |
AddSubHelper<int64_t>(instr, op2); |
} else { |
- AddSubHelper<int32_t>(instr, op2); |
+ AddSubHelper<int32_t>(instr, static_cast<int32_t>(op2)); |
} |
} |
@@ -1457,7 +1459,7 @@ void Simulator::VisitLogicalImmediate(Instruction* instr) { |
if (instr->SixtyFourBits()) { |
LogicalHelper<int64_t>(instr, instr->ImmLogical()); |
} else { |
- LogicalHelper<int32_t>(instr, instr->ImmLogical()); |
+ LogicalHelper<int32_t>(instr, static_cast<int32_t>(instr->ImmLogical())); |
} |
} |
@@ -1879,7 +1881,7 @@ void Simulator::VisitMoveWideImmediate(Instruction* instr) { |
// Get the shifted immediate. |
int64_t shift = instr->ShiftMoveWide() * 16; |
- int64_t shifted_imm16 = instr->ImmMoveWide() << shift; |
+ int64_t shifted_imm16 = static_cast<int64_t>(instr->ImmMoveWide()) << shift; |
// Compute the new value. |
switch (mov_op) { |
@@ -1912,25 +1914,32 @@ void Simulator::VisitMoveWideImmediate(Instruction* instr) { |
void Simulator::VisitConditionalSelect(Instruction* instr) { |
+ uint64_t new_val = xreg(instr->Rn()); |
if (ConditionFailed(static_cast<Condition>(instr->Condition()))) { |
- uint64_t new_val = xreg(instr->Rm()); |
+ new_val = xreg(instr->Rm()); |
switch (instr->Mask(ConditionalSelectMask)) { |
- case CSEL_w: set_wreg(instr->Rd(), new_val); break; |
- case CSEL_x: set_xreg(instr->Rd(), new_val); break; |
- case CSINC_w: set_wreg(instr->Rd(), new_val + 1); break; |
- case CSINC_x: set_xreg(instr->Rd(), new_val + 1); break; |
- case CSINV_w: set_wreg(instr->Rd(), ~new_val); break; |
- case CSINV_x: set_xreg(instr->Rd(), ~new_val); break; |
- case CSNEG_w: set_wreg(instr->Rd(), -new_val); break; |
- case CSNEG_x: set_xreg(instr->Rd(), -new_val); break; |
+ case CSEL_w: |
+ case CSEL_x: |
+ break; |
+ case CSINC_w: |
+ case CSINC_x: |
+ new_val++; |
+ break; |
+ case CSINV_w: |
+ case CSINV_x: |
+ new_val = ~new_val; |
+ break; |
+ case CSNEG_w: |
+ case CSNEG_x: |
+ new_val = -new_val; |
+ break; |
default: UNIMPLEMENTED(); |
} |
+ } |
+ if (instr->SixtyFourBits()) { |
+ set_xreg(instr->Rd(), new_val); |
} else { |
- if (instr->SixtyFourBits()) { |
- set_xreg(instr->Rd(), xreg(instr->Rn())); |
- } else { |
- set_wreg(instr->Rd(), wreg(instr->Rn())); |
- } |
+ set_wreg(instr->Rd(), static_cast<uint32_t>(new_val)); |
} |
} |
@@ -1940,13 +1949,27 @@ void Simulator::VisitDataProcessing1Source(Instruction* instr) { |
unsigned src = instr->Rn(); |
switch (instr->Mask(DataProcessing1SourceMask)) { |
- case RBIT_w: set_wreg(dst, ReverseBits(wreg(src), kWRegSizeInBits)); break; |
- case RBIT_x: set_xreg(dst, ReverseBits(xreg(src), kXRegSizeInBits)); break; |
- case REV16_w: set_wreg(dst, ReverseBytes(wreg(src), Reverse16)); break; |
- case REV16_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse16)); break; |
- case REV_w: set_wreg(dst, ReverseBytes(wreg(src), Reverse32)); break; |
- case REV32_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse32)); break; |
- case REV_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse64)); break; |
+ case RBIT_w: |
+ set_wreg(dst, ReverseBits(wreg(src))); |
+ break; |
+ case RBIT_x: |
+ set_xreg(dst, ReverseBits(xreg(src))); |
+ break; |
+ case REV16_w: |
+ set_wreg(dst, ReverseBytes(wreg(src), 1)); |
+ break; |
+ case REV16_x: |
+ set_xreg(dst, ReverseBytes(xreg(src), 1)); |
+ break; |
+ case REV_w: |
+ set_wreg(dst, ReverseBytes(wreg(src), 2)); |
+ break; |
+ case REV32_x: |
+ set_xreg(dst, ReverseBytes(xreg(src), 2)); |
+ break; |
+ case REV_x: |
+ set_xreg(dst, ReverseBytes(xreg(src), 3)); |
+ break; |
case CLZ_w: set_wreg(dst, CountLeadingZeros(wreg(src), kWRegSizeInBits)); |
break; |
case CLZ_x: set_xreg(dst, CountLeadingZeros(xreg(src), kXRegSizeInBits)); |
@@ -1964,44 +1987,6 @@ void Simulator::VisitDataProcessing1Source(Instruction* instr) { |
} |
-uint64_t Simulator::ReverseBits(uint64_t value, unsigned num_bits) { |
- DCHECK((num_bits == kWRegSizeInBits) || (num_bits == kXRegSizeInBits)); |
- uint64_t result = 0; |
- for (unsigned i = 0; i < num_bits; i++) { |
- result = (result << 1) | (value & 1); |
- value >>= 1; |
- } |
- return result; |
-} |
- |
- |
-uint64_t Simulator::ReverseBytes(uint64_t value, ReverseByteMode mode) { |
- // Split the 64-bit value into an 8-bit array, where b[0] is the least |
- // significant byte, and b[7] is the most significant. |
- uint8_t bytes[8]; |
- uint64_t mask = 0xff00000000000000UL; |
- for (int i = 7; i >= 0; i--) { |
- bytes[i] = (value & mask) >> (i * 8); |
- mask >>= 8; |
- } |
- |
- // Permutation tables for REV instructions. |
- // permute_table[Reverse16] is used by REV16_x, REV16_w |
- // permute_table[Reverse32] is used by REV32_x, REV_w |
- // permute_table[Reverse64] is used by REV_x |
- DCHECK((Reverse16 == 0) && (Reverse32 == 1) && (Reverse64 == 2)); |
- static const uint8_t permute_table[3][8] = { {6, 7, 4, 5, 2, 3, 0, 1}, |
- {4, 5, 6, 7, 0, 1, 2, 3}, |
- {0, 1, 2, 3, 4, 5, 6, 7} }; |
- uint64_t result = 0; |
- for (int i = 0; i < 8; i++) { |
- result <<= 8; |
- result |= bytes[permute_table[mode][i]]; |
- } |
- return result; |
-} |
- |
- |
template <typename T> |
void Simulator::DataProcessing2Source(Instruction* instr) { |
Shift shift_op = NO_SHIFT; |
@@ -2121,7 +2106,7 @@ void Simulator::VisitDataProcessing3Source(Instruction* instr) { |
if (instr->SixtyFourBits()) { |
set_xreg(instr->Rd(), result); |
} else { |
- set_wreg(instr->Rd(), result); |
+ set_wreg(instr->Rd(), static_cast<int32_t>(result)); |
} |
} |
@@ -2138,8 +2123,9 @@ void Simulator::BitfieldHelper(Instruction* instr) { |
mask = diff < reg_size - 1 ? (static_cast<T>(1) << (diff + 1)) - 1 |
: static_cast<T>(-1); |
} else { |
- mask = ((1L << (S + 1)) - 1); |
- mask = (static_cast<uint64_t>(mask) >> R) | (mask << (reg_size - R)); |
+ uint64_t umask = ((1L << (S + 1)) - 1); |
+ umask = (umask >> R) | (umask << (reg_size - R)); |
+ mask = static_cast<T>(umask); |
diff += reg_size; |
} |
@@ -2563,7 +2549,7 @@ static T FPRound(int64_t sign, int64_t exponent, uint64_t mantissa, |
// Bail out early for zero inputs. |
if (mantissa == 0) { |
- return sign << sign_offset; |
+ return static_cast<T>(sign << sign_offset); |
} |
// If all bits in the exponent are set, the value is infinite or NaN. |
@@ -2580,9 +2566,9 @@ static T FPRound(int64_t sign, int64_t exponent, uint64_t mantissa, |
// FPTieEven rounding mode handles overflows using infinities. |
exponent = infinite_exponent; |
mantissa = 0; |
- return (sign << sign_offset) | |
- (exponent << exponent_offset) | |
- (mantissa << mantissa_offset); |
+ return static_cast<T>((sign << sign_offset) | |
+ (exponent << exponent_offset) | |
+ (mantissa << mantissa_offset)); |
} |
// Calculate the shift required to move the top mantissa bit to the proper |
@@ -2605,7 +2591,7 @@ static T FPRound(int64_t sign, int64_t exponent, uint64_t mantissa, |
// non-zero result after rounding. |
if (shift > (highest_significant_bit + 1)) { |
// The result will always be +/-0.0. |
- return sign << sign_offset; |
+ return static_cast<T>(sign << sign_offset); |
} |
// Properly encode the exponent for a subnormal output. |
@@ -2624,9 +2610,9 @@ static T FPRound(int64_t sign, int64_t exponent, uint64_t mantissa, |
uint64_t adjusted = mantissa - (halfbit_mantissa & ~onebit_mantissa); |
T halfbit_adjusted = (adjusted >> (shift-1)) & 1; |
- T result = (sign << sign_offset) | |
- (exponent << exponent_offset) | |
- ((mantissa >> shift) << mantissa_offset); |
+ T result = |
+ static_cast<T>((sign << sign_offset) | (exponent << exponent_offset) | |
+ ((mantissa >> shift) << mantissa_offset)); |
// A very large mantissa can overflow during rounding. If this happens, the |
// exponent should be incremented and the mantissa set to 1.0 (encoded as |
@@ -2641,9 +2627,9 @@ static T FPRound(int64_t sign, int64_t exponent, uint64_t mantissa, |
// We have to shift the mantissa to the left (or not at all). The input |
// mantissa is exactly representable in the output mantissa, so apply no |
// rounding correction. |
- return (sign << sign_offset) | |
- (exponent << exponent_offset) | |
- ((mantissa << -shift) << mantissa_offset); |
+ return static_cast<T>((sign << sign_offset) | |
+ (exponent << exponent_offset) | |
+ ((mantissa << -shift) << mantissa_offset)); |
} |
} |
@@ -2838,7 +2824,8 @@ float Simulator::FPToFloat(double value, FPRounding round_mode) { |
uint32_t sign = raw >> 63; |
uint32_t exponent = (1 << 8) - 1; |
- uint32_t payload = unsigned_bitextract_64(50, 52 - 23, raw); |
+ uint32_t payload = |
+ static_cast<uint32_t>(unsigned_bitextract_64(50, 52 - 23, raw)); |
payload |= (1 << 22); // Force a quiet NaN. |
return rawbits_to_float((sign << 31) | (exponent << 23) | payload); |
@@ -2859,7 +2846,8 @@ float Simulator::FPToFloat(double value, FPRounding round_mode) { |
// Extract the IEEE-754 double components. |
uint32_t sign = raw >> 63; |
// Extract the exponent and remove the IEEE-754 encoding bias. |
- int32_t exponent = unsigned_bitextract_64(62, 52, raw) - 1023; |
+ int32_t exponent = |
+ static_cast<int32_t>(unsigned_bitextract_64(62, 52, raw)) - 1023; |
// Extract the mantissa and add the implicit '1' bit. |
uint64_t mantissa = unsigned_bitextract_64(51, 0, raw); |
if (std::fpclassify(value) == FP_NORMAL) { |
@@ -3210,11 +3198,11 @@ void Simulator::VisitSystem(Instruction* instr) { |
case MSR: { |
switch (instr->ImmSystemRegister()) { |
case NZCV: |
- nzcv().SetRawValue(xreg(instr->Rt())); |
+ nzcv().SetRawValue(wreg(instr->Rt())); |
LogSystemRegister(NZCV); |
break; |
case FPCR: |
- fpcr().SetRawValue(xreg(instr->Rt())); |
+ fpcr().SetRawValue(wreg(instr->Rt())); |
LogSystemRegister(FPCR); |
break; |
default: UNIMPLEMENTED(); |