diff options
author | Serguei Katkov <serguei.i.katkov@intel.com> | 2015-04-08 13:26:09 +0600 |
---|---|---|
committer | Serguei Katkov <serguei.i.katkov@intel.com> | 2015-04-10 14:50:43 +0600 |
commit | 55501ce0db57bccfa23b0226faffc964203701f9 (patch) | |
tree | b9abd5dcbfd1ec5aff448e4a5d0ce051b27f0466 | |
parent | 1576be32be4a99a1cffdaaf209a3cd67e8b2f88a (diff) | |
download | art-55501ce0db57bccfa23b0226faffc964203701f9.zip art-55501ce0db57bccfa23b0226faffc964203701f9.tar.gz art-55501ce0db57bccfa23b0226faffc964203701f9.tar.bz2 |
Optimizing x86: Fix VisitArraySet for FP value
Instruction generator expects to see FP value in XMM register,
so update location builder to follow this.
Change-Id: Idca4bb5cdb59249c77fcc6f76cdfcaba47222b3d
Signed-off-by: Serguei Katkov <serguei.i.katkov@intel.com>
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 8 | ||||
-rw-r--r-- | test/407-arrays/src/Main.java | 28 |
2 files changed, 31 insertions, 5 deletions
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 92b62e2..70d02d1 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -3388,7 +3388,13 @@ void LocationsBuilderX86::VisitArraySet(HArraySet* instruction) { // Ensure the value is in a byte register. locations->SetInAt(2, Location::ByteRegisterOrConstant(EAX, instruction->InputAt(2))); } else { - locations->SetInAt(2, Location::RegisterOrConstant(instruction->InputAt(2))); + bool is_fp_type = (value_type == Primitive::kPrimFloat) + || (value_type == Primitive::kPrimDouble); + if (is_fp_type) { + locations->SetInAt(2, Location::RequiresFpuRegister()); + } else { + locations->SetInAt(2, Location::RegisterOrConstant(instruction->InputAt(2))); + } } // Temporary registers for the write barrier. if (needs_write_barrier) { diff --git a/test/407-arrays/src/Main.java b/test/407-arrays/src/Main.java index d5c5604..4b833be 100644 --- a/test/407-arrays/src/Main.java +++ b/test/407-arrays/src/Main.java @@ -19,9 +19,9 @@ public class Main extends TestCase { public static void main(String[] args) { $opt$testReads(new boolean[1], new byte[1], new char[1], new short[1], - new int[1], new Object[1], new long[1], 0); + new int[1], new Object[1], new long[1], new float[1], new double[1], 0); $opt$testWrites(new boolean[2], new byte[2], new char[2], new short[2], - new int[2], new Object[2], new long[2], 1); + new int[2], new Object[2], new long[2], new float[2], new double[2], 1); ensureThrows(new boolean[2], 2); ensureThrows(new boolean[2], 4); ensureThrows(new boolean[2], -1); @@ -30,7 +30,8 @@ public class Main extends TestCase { } static void $opt$testReads(boolean[] bools, byte[] bytes, char[] chars, short[] shorts, - int[] ints, Object[] objects, long[] longs, int index) { + int[] ints, Object[] objects, long[] longs, float[] floats, + double[] doubles, int index) { assertEquals(false, bools[0]); assertEquals(false, bools[index]); @@ -51,10 +52,17 @@ public class Main extends TestCase { assertEquals(0, longs[0]); assertEquals(0, longs[index]); + + assertEquals(0, floats[0]); + assertEquals(0, floats[index]); + + assertEquals(0, doubles[0]); + assertEquals(0, doubles[index]); } static void $opt$testWrites(boolean[] bools, byte[] bytes, char[] chars, short[] shorts, - int[] ints, Object[] objects, long[] longs, int index) { + int[] ints, Object[] objects, long[] longs, float[] floats, + double doubles[], int index) { bools[0] = true; assertEquals(true, bools[0]); bools[index] = true; @@ -99,6 +107,18 @@ public class Main extends TestCase { // on 32bits. So we call out a long helper to ensure this method gets // optimized. $opt$testLongWrites(longs, index); + + float f = 1.0F; + floats[0] = f / (1 | 0); + assertEquals(f, floats[0]); + floats[index] = f / (1 | 0); + assertEquals(f, floats[index]); + + double d = 1.0F; + doubles[0] = d / (1 | 0); + assertEquals(d, doubles[0]); + doubles[index] = d / (1 | 0); + assertEquals(d, doubles[index]); } public static void $opt$testLongWrites(long[] longs, int index) { |