From 8b80f7174e8a780af938fbabd7e0ccfdd5ba4eeb Mon Sep 17 00:00:00 2001 From: buzbee Date: Wed, 16 Mar 2016 14:39:50 -0700 Subject: [PATCH] ART: Mterp arm64 2-operand double rem fix An instruction ordering bug caused 2-operand double-precision rem operations to be performed incorrectly on the arm64 fast interpreter. Also, fixes the existing omnibus-opcodes smoke test to better catch 2-operand float and double operation problems (the problem was masked in the existing test). Bug: 27604215 (cherry picked from commit 908c0b28517c2d21f9ddd231e91cdd2c339aeb16) Change-Id: I1856d914a0cb76c6034d0c0e021525b095e33452 --- .../interpreter/mterp/arm64/op_rem_double_2addr.S | 2 +- runtime/interpreter/mterp/out/mterp_arm64.S | 2 +- test/003-omnibus-opcodes/src/FloatMath.java | 50 +++++++++++++++++++--- 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/runtime/interpreter/mterp/arm64/op_rem_double_2addr.S b/runtime/interpreter/mterp/arm64/op_rem_double_2addr.S index db18aa7ee..9868f4123 100644 --- a/runtime/interpreter/mterp/arm64/op_rem_double_2addr.S +++ b/runtime/interpreter/mterp/arm64/op_rem_double_2addr.S @@ -3,9 +3,9 @@ ubfx w2, wINST, #8, #4 // w2<- A GET_VREG_WIDE d1, w1 // d1<- vB GET_VREG_WIDE d0, w2 // d0<- vA - FETCH_ADVANCE_INST 1 // advance rPC, load rINST bl fmod ubfx w2, wINST, #8, #4 // w2<- A (need to reload - killed across call) + FETCH_ADVANCE_INST 1 // advance rPC, load rINST GET_INST_OPCODE ip // extract opcode from rINST SET_VREG_WIDE d0, w2 // vAA<- result GOTO_OPCODE ip // jump to next instruction diff --git a/runtime/interpreter/mterp/out/mterp_arm64.S b/runtime/interpreter/mterp/out/mterp_arm64.S index cdb27e89e..6ae59d857 100644 --- a/runtime/interpreter/mterp/out/mterp_arm64.S +++ b/runtime/interpreter/mterp/out/mterp_arm64.S @@ -5984,9 +5984,9 @@ artMterpAsmInstructionStart = .L_op_nop ubfx w2, wINST, #8, #4 // w2<- A GET_VREG_WIDE d1, w1 // d1<- vB GET_VREG_WIDE d0, w2 // d0<- vA - FETCH_ADVANCE_INST 1 // advance rPC, load rINST bl fmod ubfx w2, wINST, #8, #4 // w2<- A (need to reload - killed across call) + FETCH_ADVANCE_INST 1 // advance rPC, load rINST GET_INST_OPCODE ip // extract opcode from rINST SET_VREG_WIDE d0, w2 // vAA<- result GOTO_OPCODE ip // jump to next instruction diff --git a/test/003-omnibus-opcodes/src/FloatMath.java b/test/003-omnibus-opcodes/src/FloatMath.java index 96befe9cd..fcdb4fe30 100644 --- a/test/003-omnibus-opcodes/src/FloatMath.java +++ b/test/003-omnibus-opcodes/src/FloatMath.java @@ -135,7 +135,8 @@ public class FloatMath { static float[] floatOperTest(float x, float y) { System.out.println("FloatMath.floatOperTest"); - float[] results = new float[9]; + float[] results = new float[10]; + float tmp; /* this seems to generate "op-float" instructions */ results[0] = x + y; @@ -145,7 +146,21 @@ public class FloatMath { results[4] = x % -y; /* this seems to generate "op-float/2addr" instructions */ - results[8] = x + (((((x + y) - y) * y) / y) % y); + tmp = x; + tmp += y; + results[5] = tmp; + tmp = x; + tmp -= y; + results[6] = tmp; + tmp = x; + tmp *= y; + results[7] = tmp; + tmp = x; + tmp /= y; + results[8] = tmp; + tmp = x; + tmp %= -y; + results[9] = tmp; return results; } @@ -155,7 +170,11 @@ public class FloatMath { Main.assertTrue(results[2] > -210000.01f && results[2] < -209999.99f); Main.assertTrue(results[3] > -23333.34f && results[3] < -23333.32f); Main.assertTrue(results[4] > 0.999f && results[4] < 1.001f); - Main.assertTrue(results[8] > 70000.99f && results[8] < 70001.01f); + Main.assertTrue(results[5] > 69996.99f && results[5] < 69997.01f); + Main.assertTrue(results[6] > 70002.99f && results[6] < 70003.01f); + Main.assertTrue(results[7] > -210000.01f && results[7] < -209999.99f); + Main.assertTrue(results[8] > -23333.34f && results[8] < -23333.32f); + Main.assertTrue(results[9] > 0.999f && results[9] < 1.001f); } /* @@ -165,7 +184,8 @@ public class FloatMath { static double[] doubleOperTest(double x, double y) { System.out.println("FloatMath.doubleOperTest"); - double[] results = new double[9]; + double[] results = new double[10]; + double tmp; /* this seems to generate "op-double" instructions */ results[0] = x + y; @@ -175,7 +195,21 @@ public class FloatMath { results[4] = x % -y; /* this seems to generate "op-double/2addr" instructions */ - results[8] = x + (((((x + y) - y) * y) / y) % y); + tmp = x; + tmp += y; + results[5] = tmp; + tmp = x; + tmp -= y; + results[6] = tmp; + tmp = x; + tmp *= y; + results[7] = tmp; + tmp = x; + tmp /= y; + results[8] = tmp; + tmp = x; + tmp %= -y; + results[9] = tmp; return results; } @@ -185,7 +219,11 @@ public class FloatMath { Main.assertTrue(results[2] > -210000.01 && results[2] < -209999.99); Main.assertTrue(results[3] > -23333.34 && results[3] < -23333.32); Main.assertTrue(results[4] > 0.999 && results[4] < 1.001); - Main.assertTrue(results[8] > 70000.99 && results[8] < 70001.01); + Main.assertTrue(results[5] > 69996.99 && results[5] < 69997.01); + Main.assertTrue(results[6] > 70002.99 && results[6] < 70003.01); + Main.assertTrue(results[7] > -210000.01 && results[7] < -209999.99); + Main.assertTrue(results[8] > -23333.34 && results[8] < -23333.32); + Main.assertTrue(results[9] > 0.999 && results[9] < 1.001); } /* -- 2.11.0