OSDN Git Service

Do not use STMP, it conflicts with the calling convention.
authorNicolas Geoffray <ngeoffray@google.com>
Fri, 16 Jan 2015 11:14:27 +0000 (11:14 +0000)
committerNicolas Geoffray <ngeoffray@google.com>
Mon, 19 Jan 2015 09:10:12 +0000 (09:10 +0000)
Hard-float calling convention uses S14 and D7 for argument passing,
so we cannot use them.

Change-Id: I77a2d8c875677640204baebc24355051aa4175fd

compiler/optimizing/code_generator_arm.cc
test/440-stmp/expected.txt [new file with mode: 0644]
test/440-stmp/info.txt [new file with mode: 0644]
test/440-stmp/src/Main.java [new file with mode: 0644]

index 5b2db13..7ece4b2 100644 (file)
@@ -49,9 +49,6 @@ static constexpr SRegister kRuntimeParameterFpuRegisters[] = { S0, S1, S2, S3 };
 static constexpr size_t kRuntimeParameterFpuRegistersLength =
     arraysize(kRuntimeParameterFpuRegisters);
 
-static constexpr DRegister DTMP = D7;
-static constexpr SRegister STMP = S14;
-
 class InvokeRuntimeCallingConvention : public CallingConvention<Register, SRegister> {
  public:
   InvokeRuntimeCallingConvention()
@@ -475,11 +472,6 @@ void CodeGeneratorARM::SetupBlockedRegisters() const {
   blocked_core_registers_[R10] = true;
   blocked_core_registers_[R11] = true;
 
-  // Don't allocate our temporary double register.
-  blocked_fpu_registers_[STMP] = true;
-  blocked_fpu_registers_[STMP + 1] = true;
-  DCHECK_EQ(FromLowSToD(STMP), DTMP);
-
   blocked_fpu_registers_[S16] = true;
   blocked_fpu_registers_[S17] = true;
   blocked_fpu_registers_[S18] = true;
@@ -3374,9 +3366,9 @@ void ParallelMoveResolverARM::EmitSwap(size_t index) {
   } else if (source.IsStackSlot() && destination.IsStackSlot()) {
     Exchange(source.GetStackIndex(), destination.GetStackIndex());
   } else if (source.IsFpuRegister() && destination.IsFpuRegister()) {
-    __ vmovs(STMP, source.AsFpuRegister<SRegister>());
+    __ vmovrs(IP, source.AsFpuRegister<SRegister>());
     __ vmovs(source.AsFpuRegister<SRegister>(), destination.AsFpuRegister<SRegister>());
-    __ vmovs(destination.AsFpuRegister<SRegister>(), STMP);
+    __ vmovsr(destination.AsFpuRegister<SRegister>(), IP);
   } else if (source.IsFpuRegister() || destination.IsFpuRegister()) {
     SRegister reg = source.IsFpuRegister() ? source.AsFpuRegister<SRegister>()
                                            : destination.AsFpuRegister<SRegister>();
@@ -3384,13 +3376,10 @@ void ParallelMoveResolverARM::EmitSwap(size_t index) {
         ? destination.GetStackIndex()
         : source.GetStackIndex();
 
-    __ vmovs(STMP, reg);
-    __ LoadSFromOffset(reg, SP, mem);
-    __ StoreSToOffset(STMP, SP, mem);
+    __ vmovrs(IP, reg);
+    __ LoadFromOffset(kLoadWord, IP, SP, mem);
+    __ StoreToOffset(kStoreWord, IP, SP, mem);
   } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) {
-    // TODO: We could use DTMP and ask for a pair scratch register (float or core).
-    // This would save four instructions if two scratch registers are available, and
-    // two instructions if not.
     Exchange(source.GetStackIndex(), destination.GetStackIndex());
     Exchange(source.GetHighStackIndex(kArmWordSize), destination.GetHighStackIndex(kArmWordSize));
   } else {
diff --git a/test/440-stmp/expected.txt b/test/440-stmp/expected.txt
new file mode 100644 (file)
index 0000000..e995b05
--- /dev/null
@@ -0,0 +1 @@
+-118.0
diff --git a/test/440-stmp/info.txt b/test/440-stmp/info.txt
new file mode 100644 (file)
index 0000000..c4a7bf1
--- /dev/null
@@ -0,0 +1,3 @@
+Regression test for optimizing, that used to consider
+a S/D register a temp, while it conflicted with the
+hard-float calling convention.
diff --git a/test/440-stmp/src/Main.java b/test/440-stmp/src/Main.java
new file mode 100644 (file)
index 0000000..2dd10f8
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class Main {
+  public static void main(String[] args) {
+    new Main().bar();
+  }
+
+  public void bar() {
+    // Use up all available D registers on ARM.
+    baz(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o);
+  }
+
+  public static void baz(float a, float b, float c, float d, float e, float f, float g,
+                         float h, float i, float j, float k, float l, float m, float n, float o) {
+    System.out.println(a - b - c - d - e - f - g - h - i - j - k - l - m - n - o);
+  }
+
+  float a = 1.0f;
+  float b = 2.0f;
+  float c = 3.0f;
+  float d = 4.0f;
+  float e = 5.0f;
+  float f = 6.0f;
+  float g = 7.0f;
+  float h = 8.0f;
+  float i = 9.0f;
+  float j = 10.0f;
+  float k = 11.0f;
+  float l = 12.0f;
+  float m = 13.0f;
+  float n = 14.0f;
+  float o = 15.0f;
+}