Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Unified Diff: src/arm/simulator-arm.cc

Issue 222403002: ARM: Avoid VMSR instruction when converting to clamped uint8 (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/arm/simulator-arm.cc
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc
index 8f7c1e8bb2b740e7884c6ae52c6b867681c9e125..1f64d2bfa9f7e33eadd6940dce456e8bb9b40817 100644
--- a/src/arm/simulator-arm.cc
+++ b/src/arm/simulator-arm.cc
@@ -2885,6 +2885,7 @@ void Simulator::DecodeType7(Instruction* instr) {
// vcvt: Dd = Sm
// vcvt: Sd = Dm
// vcvt.f64.s32 Dd, Dd, #<fbits>
+// vcvt.u32.f64 Dd, Dd, #<fbits>
// Dd = vabs(Dm)
// Dd = vneg(Dm)
// Dd = vadd(Dn, Dm)
@@ -2933,13 +2934,10 @@ void Simulator::DecodeTypeVFP(Instruction* instr) {
DecodeVCVTBetweenDoubleAndSingle(instr);
} else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) {
DecodeVCVTBetweenFloatingPointAndInteger(instr);
- } else if ((instr->Opc2Value() == 0xA) && (instr->Opc3Value() == 0x3) &&
- (instr->Bit(8) == 1)) {
- // vcvt.f64.s32 Dd, Dd, #<fbits>
- int fraction_bits = 32 - ((instr->Bit(5) << 4) | instr->Bits(3, 0));
- int fixed_value = get_sinteger_from_s_register(vd * 2);
- double divide = 1 << fraction_bits;
- set_d_register_from_double(vd, fixed_value / divide);
+ } else if ((instr->Opc2Value() & 0x2) && (instr->Opc2Value() & 0x8) &&
+ (instr->Opc3Value() == 0x3) &&
+ (instr->Bit(5) || instr->Bits(3, 0))) {
+ DecodeVCVTBetweenFloatingPointAndFixedPoint(instr);
} else if (((instr->Opc2Value() >> 1) == 0x6) &&
(instr->Opc3Value() & 0x1)) {
DecodeVCVTBetweenFloatingPointAndInteger(instr);
@@ -3348,6 +3346,78 @@ void Simulator::DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr) {
}
+void Simulator::DecodeVCVTBetweenFloatingPointAndFixedPoint(
+ Instruction* instr) {
+ ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
+ ASSERT((instr->Opc2Value() & 0x2) && (instr->Opc2Value() & 0x8));
+ ASSERT(instr->Opc3Value() == 0x3);
+ ASSERT(instr->Bit(5) || instr->Bits(3, 0));
+
+ bool to_integer = (instr->Bit(18) == 1);
+ bool unsigned_integer = (instr->Bit(16) == 1);
+
+ VFPRegPrecision f_precision = (instr->SzValue() == 1) ? kDoublePrecision
+ : kSinglePrecision;
+ int fd = instr->VFPDRegValue(f_precision);
+ int sd = instr->VFPDRegValue(kSinglePrecision);
+
+ int sx = instr->Bit(7);
+ int fraction_bits = (sx ? 32 : 16) -
+ ((instr->Bits(3, 0) << 1) | instr->Bit(5));
+ double mult = 1 << fraction_bits;
+
+ if (to_integer) {
+ bool double_precision = (f_precision == kDoublePrecision);
+ double val = double_precision ? get_double_from_d_register(fd)
+ : get_float_from_s_register(fd);
+
+ // First check if the value overflows the integer range without
+ // multiplication.
+ inv_op_vfp_flag_ = get_inv_op_vfp_flag(RZ, val, unsigned_integer);
+
+ if (!inv_op_vfp_flag_) {
+ // The original value did not overflow the integer range, so we can
+ // safely multiply it without fear of double overflow.
+ val *= mult;
+ // ARM specifies rounding towards zero for float to fixed conversion.
+ inv_op_vfp_flag_ = get_inv_op_vfp_flag(RZ, val, unsigned_integer);
+ }
+
+ int temp = unsigned_integer ? static_cast<uint32_t>(val)
+ : static_cast<int32_t>(val);
+ if (inv_op_vfp_flag_) {
+ temp = VFPConversionSaturate(val, unsigned_integer);
+ }
+
+ // FIXME: inexact_vfp_flag_ does not model ARM behavior exactly if
+ // inv_op_vfp_flag_ is set.
+ double abs_diff =
+ unsigned_integer ? std::fabs(val - static_cast<uint32_t>(temp))
+ : std::fabs(val - temp);
+ inexact_vfp_flag_ = (abs_diff != 0);
+
+ set_s_register_from_sinteger(sd, temp);
+
+ } else {
+ int val = get_sinteger_from_s_register(sd);
+ if (f_precision == kDoublePrecision) {
+ if (unsigned_integer) {
+ set_d_register_from_double(fd, static_cast<uint32_t>(val) / mult);
+ } else {
+ set_d_register_from_double(fd, val / mult);
+ }
+ } else {
+ if (unsigned_integer) {
+ set_s_register_from_float(
+ fd, static_cast<float>(static_cast<uint32_t>(val) / mult));
+ } else {
+ set_s_register_from_float(fd, static_cast<float>(val / mult));
+ }
+ }
+ }
+}
+
+
// void Simulator::DecodeType6CoprocessorIns(Instruction* instr)
// Decode Type 6 coprocessor instructions.
// Dm = vmov(Rt, Rt2)

Powered by Google App Engine
This is Rietveld 408576698