Commit 77a17022 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[cleanup] Fix NOLINT(runtime/references) for MIPS simulator.

R=clemensh@chromium.org
BUG=v8:9429,v8:9396

Change-Id: I1d8b5b67e5cd1b1788e6c0dcb45762c555b6f0e0
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1695471Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62666}
parent 99df710d
......@@ -1356,8 +1356,8 @@ bool Simulator::set_fcsr_round64_error(float original, float rounded) {
return ret;
}
void Simulator::round_according_to_fcsr(double toRound, double& rounded,
int32_t& rounded_int, double fs) {
void Simulator::round_according_to_fcsr(double toRound, double* rounded,
int32_t* rounded_int, double fs) {
// 0 RN (round to nearest): Round a result to the nearest
// representable value; if the result is exactly halfway between
// two representable values, round to zero. Behave like round_w_d.
......@@ -1373,32 +1373,32 @@ void Simulator::round_according_to_fcsr(double toRound, double& rounded,
// the next representable value down. Behave like floor_w_d.
switch (get_fcsr_rounding_mode()) {
case kRoundToNearest:
rounded = std::floor(fs + 0.5);
rounded_int = static_cast<int32_t>(rounded);
if ((rounded_int & 1) != 0 && rounded_int - fs == 0.5) {
*rounded = std::floor(fs + 0.5);
*rounded_int = static_cast<int32_t>(*rounded);
if ((*rounded_int & 1) != 0 && *rounded_int - fs == 0.5) {
// If the number is halfway between two integers,
// round to the even one.
rounded_int--;
rounded -= 1.;
*rounded_int -= 1;
*rounded -= 1.;
}
break;
case kRoundToZero:
rounded = trunc(fs);
rounded_int = static_cast<int32_t>(rounded);
*rounded = trunc(fs);
*rounded_int = static_cast<int32_t>(*rounded);
break;
case kRoundToPlusInf:
rounded = std::ceil(fs);
rounded_int = static_cast<int32_t>(rounded);
*rounded = std::ceil(fs);
*rounded_int = static_cast<int32_t>(*rounded);
break;
case kRoundToMinusInf:
rounded = std::floor(fs);
rounded_int = static_cast<int32_t>(rounded);
*rounded = std::floor(fs);
*rounded_int = static_cast<int32_t>(*rounded);
break;
}
}
void Simulator::round_according_to_fcsr(float toRound, float& rounded,
int32_t& rounded_int, float fs) {
void Simulator::round_according_to_fcsr(float toRound, float* rounded,
int32_t* rounded_int, float fs) {
// 0 RN (round to nearest): Round a result to the nearest
// representable value; if the result is exactly halfway between
// two representable values, round to zero. Behave like round_w_d.
......@@ -1414,33 +1414,33 @@ void Simulator::round_according_to_fcsr(float toRound, float& rounded,
// the next representable value down. Behave like floor_w_d.
switch (get_fcsr_rounding_mode()) {
case kRoundToNearest:
rounded = std::floor(fs + 0.5);
rounded_int = static_cast<int32_t>(rounded);
if ((rounded_int & 1) != 0 && rounded_int - fs == 0.5) {
*rounded = std::floor(fs + 0.5);
*rounded_int = static_cast<int32_t>(*rounded);
if ((*rounded_int & 1) != 0 && *rounded_int - fs == 0.5) {
// If the number is halfway between two integers,
// round to the even one.
rounded_int--;
rounded -= 1.f;
*rounded_int -= 1;
*rounded -= 1.f;
}
break;
case kRoundToZero:
rounded = trunc(fs);
rounded_int = static_cast<int32_t>(rounded);
*rounded = trunc(fs);
*rounded_int = static_cast<int32_t>(*rounded);
break;
case kRoundToPlusInf:
rounded = std::ceil(fs);
rounded_int = static_cast<int32_t>(rounded);
*rounded = std::ceil(fs);
*rounded_int = static_cast<int32_t>(*rounded);
break;
case kRoundToMinusInf:
rounded = std::floor(fs);
rounded_int = static_cast<int32_t>(rounded);
*rounded = std::floor(fs);
*rounded_int = static_cast<int32_t>(*rounded);
break;
}
}
template <typename T_fp, typename T_int>
void Simulator::round_according_to_msacsr(T_fp toRound, T_fp& rounded,
T_int& rounded_int) {
void Simulator::round_according_to_msacsr(T_fp toRound, T_fp* rounded,
T_int* rounded_int) {
// 0 RN (round to nearest): Round a result to the nearest
// representable value; if the result is exactly halfway between
// two representable values, round to zero. Behave like round_w_d.
......@@ -1456,32 +1456,32 @@ void Simulator::round_according_to_msacsr(T_fp toRound, T_fp& rounded,
// the next representable value down. Behave like floor_w_d.
switch (get_msacsr_rounding_mode()) {
case kRoundToNearest:
rounded = std::floor(toRound + 0.5);
rounded_int = static_cast<T_int>(rounded);
if ((rounded_int & 1) != 0 && rounded_int - toRound == 0.5) {
*rounded = std::floor(toRound + 0.5);
*rounded_int = static_cast<T_int>(*rounded);
if ((*rounded_int & 1) != 0 && *rounded_int - toRound == 0.5) {
// If the number is halfway between two integers,
// round to the even one.
rounded_int--;
rounded -= 1;
*rounded_int -= 1;
*rounded -= 1;
}
break;
case kRoundToZero:
rounded = trunc(toRound);
rounded_int = static_cast<T_int>(rounded);
*rounded = trunc(toRound);
*rounded_int = static_cast<T_int>(*rounded);
break;
case kRoundToPlusInf:
rounded = std::ceil(toRound);
rounded_int = static_cast<T_int>(rounded);
*rounded = std::ceil(toRound);
*rounded_int = static_cast<T_int>(*rounded);
break;
case kRoundToMinusInf:
rounded = std::floor(toRound);
rounded_int = static_cast<T_int>(rounded);
*rounded = std::floor(toRound);
*rounded_int = static_cast<T_int>(*rounded);
break;
}
}
void Simulator::round64_according_to_fcsr(double toRound, double& rounded,
int64_t& rounded_int, double fs) {
void Simulator::round64_according_to_fcsr(double toRound, double* rounded,
int64_t* rounded_int, double fs) {
// 0 RN (round to nearest): Round a result to the nearest
// representable value; if the result is exactly halfway between
// two representable values, round to zero. Behave like round_w_d.
......@@ -1497,32 +1497,32 @@ void Simulator::round64_according_to_fcsr(double toRound, double& rounded,
// the next representable value down. Behave like floor_w_d.
switch (FCSR_ & 3) {
case kRoundToNearest:
rounded = std::floor(fs + 0.5);
rounded_int = static_cast<int64_t>(rounded);
if ((rounded_int & 1) != 0 && rounded_int - fs == 0.5) {
*rounded = std::floor(fs + 0.5);
*rounded_int = static_cast<int64_t>(*rounded);
if ((*rounded_int & 1) != 0 && *rounded_int - fs == 0.5) {
// If the number is halfway between two integers,
// round to the even one.
rounded_int--;
rounded -= 1.;
*rounded_int -= 1;
*rounded -= 1.;
}
break;
case kRoundToZero:
rounded = trunc(fs);
rounded_int = static_cast<int64_t>(rounded);
*rounded = trunc(fs);
*rounded_int = static_cast<int64_t>(*rounded);
break;
case kRoundToPlusInf:
rounded = std::ceil(fs);
rounded_int = static_cast<int64_t>(rounded);
*rounded = std::ceil(fs);
*rounded_int = static_cast<int64_t>(*rounded);
break;
case kRoundToMinusInf:
rounded = std::floor(fs);
rounded_int = static_cast<int64_t>(rounded);
*rounded = std::floor(fs);
*rounded_int = static_cast<int64_t>(*rounded);
break;
}
}
void Simulator::round64_according_to_fcsr(float toRound, float& rounded,
int64_t& rounded_int, float fs) {
void Simulator::round64_according_to_fcsr(float toRound, float* rounded,
int64_t* rounded_int, float fs) {
// 0 RN (round to nearest): Round a result to the nearest
// representable value; if the result is exactly halfway between
// two representable values, round to zero. Behave like round_w_d.
......@@ -1538,26 +1538,26 @@ void Simulator::round64_according_to_fcsr(float toRound, float& rounded,
// the next representable value down. Behave like floor_w_d.
switch (FCSR_ & 3) {
case kRoundToNearest:
rounded = std::floor(fs + 0.5);
rounded_int = static_cast<int64_t>(rounded);
if ((rounded_int & 1) != 0 && rounded_int - fs == 0.5) {
*rounded = std::floor(fs + 0.5);
*rounded_int = static_cast<int64_t>(*rounded);
if ((*rounded_int & 1) != 0 && *rounded_int - fs == 0.5) {
// If the number is halfway between two integers,
// round to the even one.
rounded_int--;
rounded -= 1.f;
*rounded_int -= 1;
*rounded -= 1.f;
}
break;
case kRoundToZero:
rounded = trunc(fs);
rounded_int = static_cast<int64_t>(rounded);
*rounded = trunc(fs);
*rounded_int = static_cast<int64_t>(*rounded);
break;
case kRoundToPlusInf:
rounded = std::ceil(fs);
rounded_int = static_cast<int64_t>(rounded);
*rounded = std::ceil(fs);
*rounded_int = static_cast<int64_t>(*rounded);
break;
case kRoundToMinusInf:
rounded = std::floor(fs);
rounded_int = static_cast<int64_t>(rounded);
*rounded = std::floor(fs);
*rounded_int = static_cast<int64_t>(*rounded);
break;
}
}
......@@ -2512,19 +2512,18 @@ float FPAbs<float>(float a) {
}
template <typename T>
static bool FPUProcessNaNsAndZeros(T a, T b, MaxMinKind kind,
T& result) { // NOLINT(runtime/references)
static bool FPUProcessNaNsAndZeros(T a, T b, MaxMinKind kind, T* result) {
if (std::isnan(a) && std::isnan(b)) {
result = a;
*result = a;
} else if (std::isnan(a)) {
result = b;
*result = b;
} else if (std::isnan(b)) {
result = a;
*result = a;
} else if (b == a) {
// Handle -0.0 == 0.0 case.
// std::signbit() returns int 0 or 1 so subtracting MaxMinKind::kMax
// negates the result.
result = std::signbit(b) - static_cast<int>(kind) ? b : a;
*result = std::signbit(b) - static_cast<int>(kind) ? b : a;
} else {
return false;
}
......@@ -2534,7 +2533,7 @@ static bool FPUProcessNaNsAndZeros(T a, T b, MaxMinKind kind,
template <typename T>
static T FPUMin(T a, T b) {
T result;
if (FPUProcessNaNsAndZeros(a, b, MaxMinKind::kMin, result)) {
if (FPUProcessNaNsAndZeros(a, b, MaxMinKind::kMin, &result)) {
return result;
} else {
return b < a ? b : a;
......@@ -2544,7 +2543,7 @@ static T FPUMin(T a, T b) {
template <typename T>
static T FPUMax(T a, T b) {
T result;
if (FPUProcessNaNsAndZeros(a, b, MaxMinKind::kMax, result)) {
if (FPUProcessNaNsAndZeros(a, b, MaxMinKind::kMax, &result)) {
return result;
} else {
return b > a ? b : a;
......@@ -2554,7 +2553,7 @@ static T FPUMax(T a, T b) {
template <typename T>
static T FPUMinA(T a, T b) {
T result;
if (!FPUProcessNaNsAndZeros(a, b, MaxMinKind::kMin, result)) {
if (!FPUProcessNaNsAndZeros(a, b, MaxMinKind::kMin, &result)) {
if (FPAbs(a) < FPAbs(b)) {
result = a;
} else if (FPAbs(b) < FPAbs(a)) {
......@@ -2569,7 +2568,7 @@ static T FPUMinA(T a, T b) {
template <typename T>
static T FPUMaxA(T a, T b) {
T result;
if (!FPUProcessNaNsAndZeros(a, b, MaxMinKind::kMin, result)) {
if (!FPUProcessNaNsAndZeros(a, b, MaxMinKind::kMin, &result)) {
if (FPAbs(a) > FPAbs(b)) {
result = a;
} else if (FPAbs(b) > FPAbs(a)) {
......@@ -2823,7 +2822,7 @@ void Simulator::DecodeTypeRegisterDRsType() {
case CVT_W_D: { // Convert double to word.
double rounded;
int32_t result;
round_according_to_fcsr(fs, rounded, result, fs);
round_according_to_fcsr(fs, &rounded, &result, fs);
SetFPUWordResult(fd_reg(), result);
if (set_fcsr_round_error(fs, rounded)) {
set_fpu_register_word_invalid_result(fs, rounded);
......@@ -2877,7 +2876,7 @@ void Simulator::DecodeTypeRegisterDRsType() {
if (IsFp64Mode()) {
int64_t result;
double rounded;
round64_according_to_fcsr(fs, rounded, result, fs);
round64_according_to_fcsr(fs, &rounded, &result, fs);
SetFPUResult(fd_reg(), result);
if (set_fcsr_round64_error(fs, rounded)) {
set_fpu_register_invalid_result64(fs, rounded);
......@@ -3490,7 +3489,7 @@ void Simulator::DecodeTypeRegisterSRsType() {
if (IsFp64Mode()) {
int64_t result;
float rounded;
round64_according_to_fcsr(fs, rounded, result, fs);
round64_according_to_fcsr(fs, &rounded, &result, fs);
SetFPUResult(fd_reg(), result);
if (set_fcsr_round64_error(fs, rounded)) {
set_fpu_register_invalid_result64(fs, rounded);
......@@ -3503,7 +3502,7 @@ void Simulator::DecodeTypeRegisterSRsType() {
case CVT_W_S: {
float rounded;
int32_t result;
round_according_to_fcsr(fs, rounded, result, fs);
round_according_to_fcsr(fs, &rounded, &result, fs);
SetFPUWordResult(fd_reg(), result);
if (set_fcsr_round_error(fs, rounded)) {
set_fpu_register_word_invalid_result(fs, rounded);
......@@ -5272,129 +5271,128 @@ void Simulator::DecodeTypeMsa3R() {
}
template <typename T_int, typename T_fp, typename T_reg>
void Msa3RFInstrHelper(uint32_t opcode, T_reg ws, T_reg wt,
T_reg& wd) { // NOLINT(runtime/references)
void Msa3RFInstrHelper(uint32_t opcode, T_reg ws, T_reg wt, T_reg* wd) {
const T_int all_ones = static_cast<T_int>(-1);
const T_fp s_element = *reinterpret_cast<T_fp*>(&ws);
const T_fp t_element = *reinterpret_cast<T_fp*>(&wt);
switch (opcode) {
case FCUN: {
if (std::isnan(s_element) || std::isnan(t_element)) {
wd = all_ones;
*wd = all_ones;
} else {
wd = 0;
*wd = 0;
}
} break;
case FCEQ: {
if (s_element != t_element || std::isnan(s_element) ||
std::isnan(t_element)) {
wd = 0;
*wd = 0;
} else {
wd = all_ones;
*wd = all_ones;
}
} break;
case FCUEQ: {
if (s_element == t_element || std::isnan(s_element) ||
std::isnan(t_element)) {
wd = all_ones;
*wd = all_ones;
} else {
wd = 0;
*wd = 0;
}
} break;
case FCLT: {
if (s_element >= t_element || std::isnan(s_element) ||
std::isnan(t_element)) {
wd = 0;
*wd = 0;
} else {
wd = all_ones;
*wd = all_ones;
}
} break;
case FCULT: {
if (s_element < t_element || std::isnan(s_element) ||
std::isnan(t_element)) {
wd = all_ones;
*wd = all_ones;
} else {
wd = 0;
*wd = 0;
}
} break;
case FCLE: {
if (s_element > t_element || std::isnan(s_element) ||
std::isnan(t_element)) {
wd = 0;
*wd = 0;
} else {
wd = all_ones;
*wd = all_ones;
}
} break;
case FCULE: {
if (s_element <= t_element || std::isnan(s_element) ||
std::isnan(t_element)) {
wd = all_ones;
*wd = all_ones;
} else {
wd = 0;
*wd = 0;
}
} break;
case FCOR: {
if (std::isnan(s_element) || std::isnan(t_element)) {
wd = 0;
*wd = 0;
} else {
wd = all_ones;
*wd = all_ones;
}
} break;
case FCUNE: {
if (s_element != t_element || std::isnan(s_element) ||
std::isnan(t_element)) {
wd = all_ones;
*wd = all_ones;
} else {
wd = 0;
*wd = 0;
}
} break;
case FCNE: {
if (s_element == t_element || std::isnan(s_element) ||
std::isnan(t_element)) {
wd = 0;
*wd = 0;
} else {
wd = all_ones;
*wd = all_ones;
}
} break;
case FADD:
wd = bit_cast<T_int>(s_element + t_element);
*wd = bit_cast<T_int>(s_element + t_element);
break;
case FSUB:
wd = bit_cast<T_int>(s_element - t_element);
*wd = bit_cast<T_int>(s_element - t_element);
break;
case FMUL:
wd = bit_cast<T_int>(s_element * t_element);
*wd = bit_cast<T_int>(s_element * t_element);
break;
case FDIV: {
if (t_element == 0) {
wd = bit_cast<T_int>(std::numeric_limits<T_fp>::quiet_NaN());
*wd = bit_cast<T_int>(std::numeric_limits<T_fp>::quiet_NaN());
} else {
wd = bit_cast<T_int>(s_element / t_element);
*wd = bit_cast<T_int>(s_element / t_element);
}
} break;
case FMADD:
wd = bit_cast<T_int>(
std::fma(s_element, t_element, *reinterpret_cast<T_fp*>(&wd)));
*wd = bit_cast<T_int>(
std::fma(s_element, t_element, *reinterpret_cast<T_fp*>(wd)));
break;
case FMSUB:
wd = bit_cast<T_int>(
std::fma(s_element, -t_element, *reinterpret_cast<T_fp*>(&wd)));
*wd = bit_cast<T_int>(
std::fma(s_element, -t_element, *reinterpret_cast<T_fp*>(wd)));
break;
case FEXP2:
wd = bit_cast<T_int>(std::ldexp(s_element, static_cast<int>(wt)));
*wd = bit_cast<T_int>(std::ldexp(s_element, static_cast<int>(wt)));
break;
case FMIN:
wd = bit_cast<T_int>(std::min(s_element, t_element));
*wd = bit_cast<T_int>(std::min(s_element, t_element));
break;
case FMAX:
wd = bit_cast<T_int>(std::max(s_element, t_element));
*wd = bit_cast<T_int>(std::max(s_element, t_element));
break;
case FMIN_A: {
wd = bit_cast<T_int>(
*wd = bit_cast<T_int>(
std::fabs(s_element) < std::fabs(t_element) ? s_element : t_element);
} break;
case FMAX_A: {
wd = bit_cast<T_int>(
*wd = bit_cast<T_int>(
std::fabs(s_element) > std::fabs(t_element) ? s_element : t_element);
} break;
case FSOR:
......@@ -5416,8 +5414,7 @@ void Msa3RFInstrHelper(uint32_t opcode, T_reg ws, T_reg wt,
}
template <typename T_int, typename T_int_dbl, typename T_reg>
void Msa3RFInstrHelper2(uint32_t opcode, T_reg ws, T_reg wt,
T_reg& wd) { // NOLINT(runtime/references)
void Msa3RFInstrHelper2(uint32_t opcode, T_reg ws, T_reg wt, T_reg* wd) {
// using T_uint = typename std::make_unsigned<T_int>::type;
using T_uint_dbl = typename std::make_unsigned<T_int_dbl>::type;
const T_int max_int = std::numeric_limits<T_int>::max();
......@@ -5435,16 +5432,16 @@ void Msa3RFInstrHelper2(uint32_t opcode, T_reg ws, T_reg wt,
if (product == min_fix_dbl) {
product = max_fix_dbl;
}
wd = static_cast<T_int>(product >> shift);
*wd = static_cast<T_int>(product >> shift);
} break;
case MADD_Q: {
result = (product + (static_cast<T_int_dbl>(wd) << shift)) >> shift;
wd = static_cast<T_int>(
result = (product + (static_cast<T_int_dbl>(*wd) << shift)) >> shift;
*wd = static_cast<T_int>(
result > max_int ? max_int : result < min_int ? min_int : result);
} break;
case MSUB_Q: {
result = (-product + (static_cast<T_int_dbl>(wd) << shift)) >> shift;
wd = static_cast<T_int>(
result = (-product + (static_cast<T_int_dbl>(*wd) << shift)) >> shift;
*wd = static_cast<T_int>(
result > max_int ? max_int : result < min_int ? min_int : result);
} break;
case MULR_Q: {
......@@ -5452,23 +5449,23 @@ void Msa3RFInstrHelper2(uint32_t opcode, T_reg ws, T_reg wt,
bit_cast<T_uint_dbl>(std::numeric_limits<T_int_dbl>::min()) >> 1U;
const T_int_dbl max_fix_dbl = std::numeric_limits<T_int_dbl>::max() >> 1U;
if (product == min_fix_dbl) {
wd = static_cast<T_int>(max_fix_dbl >> shift);
*wd = static_cast<T_int>(max_fix_dbl >> shift);
break;
}
wd = static_cast<T_int>((product + (1 << (shift - 1))) >> shift);
*wd = static_cast<T_int>((product + (1 << (shift - 1))) >> shift);
} break;
case MADDR_Q: {
result = (product + (static_cast<T_int_dbl>(wd) << shift) +
result = (product + (static_cast<T_int_dbl>(*wd) << shift) +
(1 << (shift - 1))) >>
shift;
wd = static_cast<T_int>(
*wd = static_cast<T_int>(
result > max_int ? max_int : result < min_int ? min_int : result);
} break;
case MSUBR_Q: {
result = (-product + (static_cast<T_int_dbl>(wd) << shift) +
result = (-product + (static_cast<T_int_dbl>(*wd) << shift) +
(1 << (shift - 1))) >>
shift;
wd = static_cast<T_int>(
*wd = static_cast<T_int>(
result > max_int ? max_int : result < min_int ? min_int : result);
} break;
default:
......@@ -5591,19 +5588,19 @@ void Simulator::DecodeTypeMsa3RF() {
#undef PACK_FLOAT16
#undef FEXDO_DF
case FTQ:
#define FTQ_DF(source, dst, fp_type, int_type) \
element = bit_cast<fp_type>(source) * \
(1U << (sizeof(int_type) * kBitsPerByte - 1)); \
if (element > std::numeric_limits<int_type>::max()) { \
dst = std::numeric_limits<int_type>::max(); \
} else if (element < std::numeric_limits<int_type>::min()) { \
dst = std::numeric_limits<int_type>::min(); \
} else if (std::isnan(element)) { \
dst = 0; \
} else { \
int_type fixed_point; \
round_according_to_msacsr(element, element, fixed_point); \
dst = fixed_point; \
#define FTQ_DF(source, dst, fp_type, int_type) \
element = bit_cast<fp_type>(source) * \
(1U << (sizeof(int_type) * kBitsPerByte - 1)); \
if (element > std::numeric_limits<int_type>::max()) { \
dst = std::numeric_limits<int_type>::max(); \
} else if (element < std::numeric_limits<int_type>::min()) { \
dst = std::numeric_limits<int_type>::min(); \
} else if (std::isnan(element)) { \
dst = 0; \
} else { \
int_type fixed_point; \
round_according_to_msacsr(element, &element, &fixed_point); \
dst = fixed_point; \
}
switch (DecodeMsaDataFormat()) {
......@@ -5626,13 +5623,13 @@ void Simulator::DecodeTypeMsa3RF() {
}
break;
#undef FTQ_DF
#define MSA_3RF_DF(T1, T2, Lanes, ws, wt, wd) \
for (int i = 0; i < Lanes; i++) { \
Msa3RFInstrHelper<T1, T2>(opcode, ws, wt, wd); \
#define MSA_3RF_DF(T1, T2, Lanes, ws, wt, wd) \
for (int i = 0; i < Lanes; i++) { \
Msa3RFInstrHelper<T1, T2>(opcode, ws, wt, &(wd)); \
}
#define MSA_3RF_DF2(T1, T2, Lanes, ws, wt, wd) \
for (int i = 0; i < Lanes; i++) { \
Msa3RFInstrHelper2<T1, T2>(opcode, ws, wt, wd); \
#define MSA_3RF_DF2(T1, T2, Lanes, ws, wt, wd) \
for (int i = 0; i < Lanes; i++) { \
Msa3RFInstrHelper2<T1, T2>(opcode, ws, wt, &(wd)); \
}
case MADD_Q:
case MSUB_Q:
......@@ -5862,8 +5859,7 @@ static inline bool isSnan(double fp) { return !QUIET_BIT_D(fp); }
#undef QUIET_BIT_D
template <typename T_int, typename T_fp, typename T_src, typename T_dst>
T_int Msa2RFInstrHelper(uint32_t opcode, T_src src,
T_dst& dst, // NOLINT(runtime/references)
T_int Msa2RFInstrHelper(uint32_t opcode, T_src src, T_dst* dst,
Simulator* sim) {
using T_uint = typename std::make_unsigned<T_int>::type;
switch (opcode) {
......@@ -5882,37 +5878,37 @@ T_int Msa2RFInstrHelper(uint32_t opcode, T_src src,
switch (std::fpclassify(element)) {
case FP_INFINITE:
if (std::signbit(element)) {
dst = NEG_INFINITY_BIT;
*dst = NEG_INFINITY_BIT;
} else {
dst = POS_INFINITY_BIT;
*dst = POS_INFINITY_BIT;
}
break;
case FP_NAN:
if (isSnan(element)) {
dst = SNAN_BIT;
*dst = SNAN_BIT;
} else {
dst = QNAN_BIT;
*dst = QNAN_BIT;
}
break;
case FP_NORMAL:
if (std::signbit(element)) {
dst = NEG_NORMAL_BIT;
*dst = NEG_NORMAL_BIT;
} else {
dst = POS_NORMAL_BIT;
*dst = POS_NORMAL_BIT;
}
break;
case FP_SUBNORMAL:
if (std::signbit(element)) {
dst = NEG_SUBNORMAL_BIT;
*dst = NEG_SUBNORMAL_BIT;
} else {
dst = POS_SUBNORMAL_BIT;
*dst = POS_SUBNORMAL_BIT;
}
break;
case FP_ZERO:
if (std::signbit(element)) {
dst = NEG_ZERO_BIT;
*dst = NEG_ZERO_BIT;
} else {
dst = POS_ZERO_BIT;
*dst = POS_ZERO_BIT;
}
break;
default:
......@@ -5936,11 +5932,11 @@ T_int Msa2RFInstrHelper(uint32_t opcode, T_src src,
const T_int max_int = std::numeric_limits<T_int>::max();
const T_int min_int = std::numeric_limits<T_int>::min();
if (std::isnan(element)) {
dst = 0;
*dst = 0;
} else if (element >= max_int || element <= min_int) {
dst = element >= max_int ? max_int : min_int;
*dst = element >= max_int ? max_int : min_int;
} else {
dst = static_cast<T_int>(std::trunc(element));
*dst = static_cast<T_int>(std::trunc(element));
}
break;
}
......@@ -5948,49 +5944,49 @@ T_int Msa2RFInstrHelper(uint32_t opcode, T_src src,
T_fp element = bit_cast<T_fp>(src);
const T_uint max_int = std::numeric_limits<T_uint>::max();
if (std::isnan(element)) {
dst = 0;
*dst = 0;
} else if (element >= max_int || element <= 0) {
dst = element >= max_int ? max_int : 0;
*dst = element >= max_int ? max_int : 0;
} else {
dst = static_cast<T_uint>(std::trunc(element));
*dst = static_cast<T_uint>(std::trunc(element));
}
break;
}
case FSQRT: {
T_fp element = bit_cast<T_fp>(src);
if (element < 0 || std::isnan(element)) {
dst = bit_cast<T_int>(std::numeric_limits<T_fp>::quiet_NaN());
*dst = bit_cast<T_int>(std::numeric_limits<T_fp>::quiet_NaN());
} else {
dst = bit_cast<T_int>(std::sqrt(element));
*dst = bit_cast<T_int>(std::sqrt(element));
}
break;
}
case FRSQRT: {
T_fp element = bit_cast<T_fp>(src);
if (element < 0 || std::isnan(element)) {
dst = bit_cast<T_int>(std::numeric_limits<T_fp>::quiet_NaN());
*dst = bit_cast<T_int>(std::numeric_limits<T_fp>::quiet_NaN());
} else {
dst = bit_cast<T_int>(1 / std::sqrt(element));
*dst = bit_cast<T_int>(1 / std::sqrt(element));
}
break;
}
case FRCP: {
T_fp element = bit_cast<T_fp>(src);
if (std::isnan(element)) {
dst = bit_cast<T_int>(std::numeric_limits<T_fp>::quiet_NaN());
*dst = bit_cast<T_int>(std::numeric_limits<T_fp>::quiet_NaN());
} else {
dst = bit_cast<T_int>(1 / element);
*dst = bit_cast<T_int>(1 / element);
}
break;
}
case FRINT: {
T_fp element = bit_cast<T_fp>(src);
if (std::isnan(element)) {
dst = bit_cast<T_int>(std::numeric_limits<T_fp>::quiet_NaN());
*dst = bit_cast<T_int>(std::numeric_limits<T_fp>::quiet_NaN());
} else {
T_int dummy;
sim->round_according_to_msacsr<T_fp, T_int>(element, element, dummy);
dst = bit_cast<T_int>(element);
sim->round_according_to_msacsr<T_fp, T_int>(element, &element, &dummy);
*dst = bit_cast<T_int>(element);
}
break;
}
......@@ -5999,19 +5995,19 @@ T_int Msa2RFInstrHelper(uint32_t opcode, T_src src,
switch (std::fpclassify(element)) {
case FP_NORMAL:
case FP_SUBNORMAL:
dst = bit_cast<T_int>(std::logb(element));
*dst = bit_cast<T_int>(std::logb(element));
break;
case FP_ZERO:
dst = bit_cast<T_int>(-std::numeric_limits<T_fp>::infinity());
*dst = bit_cast<T_int>(-std::numeric_limits<T_fp>::infinity());
break;
case FP_NAN:
dst = bit_cast<T_int>(std::numeric_limits<T_fp>::quiet_NaN());
*dst = bit_cast<T_int>(std::numeric_limits<T_fp>::quiet_NaN());
break;
case FP_INFINITE:
if (element < 0) {
dst = bit_cast<T_int>(std::numeric_limits<T_fp>::quiet_NaN());
*dst = bit_cast<T_int>(std::numeric_limits<T_fp>::quiet_NaN());
} else {
dst = bit_cast<T_int>(std::numeric_limits<T_fp>::infinity());
*dst = bit_cast<T_int>(std::numeric_limits<T_fp>::infinity());
}
break;
default:
......@@ -6024,11 +6020,11 @@ T_int Msa2RFInstrHelper(uint32_t opcode, T_src src,
const T_int max_int = std::numeric_limits<T_int>::max();
const T_int min_int = std::numeric_limits<T_int>::min();
if (std::isnan(element)) {
dst = 0;
*dst = 0;
} else if (element < min_int || element > max_int) {
dst = element > max_int ? max_int : min_int;
*dst = element > max_int ? max_int : min_int;
} else {
sim->round_according_to_msacsr<T_fp, T_int>(element, element, dst);
sim->round_according_to_msacsr<T_fp, T_int>(element, &element, dst);
}
break;
}
......@@ -6036,22 +6032,22 @@ T_int Msa2RFInstrHelper(uint32_t opcode, T_src src,
T_fp element = bit_cast<T_fp>(src);
const T_uint max_uint = std::numeric_limits<T_uint>::max();
if (std::isnan(element)) {
dst = 0;
*dst = 0;
} else if (element < 0 || element > max_uint) {
dst = element > max_uint ? max_uint : 0;
*dst = element > max_uint ? max_uint : 0;
} else {
T_uint res;
sim->round_according_to_msacsr<T_fp, T_uint>(element, element, res);
dst = *reinterpret_cast<T_int*>(&res);
sim->round_according_to_msacsr<T_fp, T_uint>(element, &element, &res);
*dst = *reinterpret_cast<T_int*>(&res);
}
break;
}
case FFINT_S:
dst = bit_cast<T_int>(static_cast<T_fp>(src));
*dst = bit_cast<T_int>(static_cast<T_fp>(src));
break;
case FFINT_U:
using uT_src = typename std::make_unsigned<T_src>::type;
dst = bit_cast<T_int>(static_cast<T_fp>(bit_cast<uT_src>(src)));
*dst = bit_cast<T_int>(static_cast<T_fp>(bit_cast<uT_src>(src)));
break;
default:
UNREACHABLE();
......@@ -6161,12 +6157,12 @@ void Simulator::DecodeTypeMsa2RF() {
switch (DecodeMsaDataFormat()) {
case MSA_WORD:
for (int i = 0; i < kMSALanesWord; i++) {
Msa2RFInstrHelper<int32_t, float>(opcode, ws.w[i], wd.w[i], this);
Msa2RFInstrHelper<int32_t, float>(opcode, ws.w[i], &wd.w[i], this);
}
break;
case MSA_DWORD:
for (int i = 0; i < kMSALanesDword; i++) {
Msa2RFInstrHelper<int64_t, double>(opcode, ws.d[i], wd.d[i], this);
Msa2RFInstrHelper<int64_t, double>(opcode, ws.d[i], &wd.d[i], this);
}
break;
default:
......
......@@ -258,26 +258,16 @@ class Simulator : public SimulatorBase {
bool set_fcsr_round_error(float original, float rounded);
bool set_fcsr_round64_error(double original, double rounded);
bool set_fcsr_round64_error(float original, float rounded);
void round_according_to_fcsr(
double toRound, double& rounded, // NOLINT(runtime/references)
int32_t& rounded_int, // NOLINT(runtime/references)
double fs);
void round_according_to_fcsr(
float toRound, float& rounded, // NOLINT(runtime/references)
int32_t& rounded_int, // NOLINT(runtime/references)
float fs);
void round_according_to_fcsr(double toRound, double* rounded,
int32_t* rounded_int, double fs);
void round_according_to_fcsr(float toRound, float* rounded,
int32_t* rounded_int, float fs);
template <typename Tfp, typename Tint>
void round_according_to_msacsr(
Tfp toRound, Tfp& rounded, // NOLINT(runtime/references)
Tint& rounded_int); // NOLINT(runtime/references)
void round64_according_to_fcsr(
double toRound, double& rounded, // NOLINT(runtime/references)
int64_t& rounded_int, // NOLINT(runtime/references)
double fs);
void round64_according_to_fcsr(
float toRound, float& rounded, // NOLINT(runtime/references)
int64_t& rounded_int, // NOLINT(runtime/references)
float fs);
void round_according_to_msacsr(Tfp toRound, Tfp* rounded, Tint* rounded_int);
void round64_according_to_fcsr(double toRound, double* rounded,
int64_t* rounded_int, double fs);
void round64_according_to_fcsr(float toRound, float* rounded,
int64_t* rounded_int, float fs);
// Special case of set_register and get_register to access the raw PC value.
void set_pc(int32_t value);
int32_t get_pc() const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment