summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGoran Jakovljevic <Goran.Jakovljevic@imgtec.com>2017-04-07 15:07:17 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-04-07 15:07:17 +0000
commitb83977e901b80f3ef94472bb9fe8c01ef2c07ba6 (patch)
tree5630ff3c123c9ab3f2d861fc3461560e33047aa5
parent01e5ab10b16453c4d0fcc4ee9060e601a6fd3ff9 (diff)
parent672082ab6edf7c12a1d7b1d9303aa0aa4fcce089 (diff)
Merge "MIPS64: Fix Math.ceil/floor intrinsics"
am: 672082ab6e Change-Id: I6ae90222a66dd6efcf35a254dc033eca0c48f23c
-rw-r--r--compiler/optimizing/intrinsics_mips64.cc16
1 files changed, 11 insertions, 5 deletions
diff --git a/compiler/optimizing/intrinsics_mips64.cc b/compiler/optimizing/intrinsics_mips64.cc
index 6098767aae9..c2518a78613 100644
--- a/compiler/optimizing/intrinsics_mips64.cc
+++ b/compiler/optimizing/intrinsics_mips64.cc
@@ -834,15 +834,15 @@ static void GenRoundingMode(LocationSummary* locations,
__ Bnezc(AT, &done);
// Long outLong = floor/ceil(in);
- // if outLong == Long.MAX_VALUE {
+ // if (outLong == Long.MAX_VALUE) || (outLong == Long.MIN_VALUE) {
// // floor()/ceil() has almost certainly returned a value
// // which can't be successfully represented as a signed
// // 64-bit number. Java expects that the input value will
// // be returned in these cases.
// // There is also a small probability that floor(in)/ceil(in)
// // correctly truncates/rounds up the input value to
- // // Long.MAX_VALUE. In that case, this exception handling
- // // code still does the correct thing.
+ // // Long.MAX_VALUE or Long.MIN_VALUE. In these cases, this
+ // // exception handling code still does the correct thing.
// return in;
// }
if (mode == kFloor) {
@@ -852,8 +852,14 @@ static void GenRoundingMode(LocationSummary* locations,
}
__ Dmfc1(AT, out);
__ MovD(out, in);
- __ LoadConst64(TMP, kPrimLongMax);
- __ Beqc(AT, TMP, &done);
+ __ Daddiu(TMP, AT, 1);
+ __ Dati(TMP, 0x8000); // TMP = AT + 0x8000 0000 0000 0001
+ // or AT - 0x7FFF FFFF FFFF FFFF.
+ // IOW, TMP = 1 if AT = Long.MIN_VALUE
+ // or TMP = 0 if AT = Long.MAX_VALUE.
+ __ Dsrl(TMP, TMP, 1); // TMP = 0 if AT = Long.MIN_VALUE
+ // or AT = Long.MAX_VALUE.
+ __ Beqzc(TMP, &done);
// double out = outLong;
// return out;