| 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();
|
|
|