Enables more SIMD tests for ARM.

R=regis@google.com

Review URL: https://codereview.chromium.org//19779006

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@25219 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 59b75a3..8d95969 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -3071,13 +3071,47 @@
 
 
 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 2;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_in(1, Location::RequiresFpuRegister());
+  summary->set_out(Location::RequiresFpuRegister());
+  return summary;
 }
 
 
 void Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  QRegister left = locs()->in(0).fpu_reg();
+  QRegister right = locs()->in(1).fpu_reg();
+  QRegister result = locs()->out().fpu_reg();
+
+  switch (op_kind()) {
+    case MethodRecognizer::kFloat32x4Equal:
+      __ vceqqs(result, left, right);
+      break;
+    case MethodRecognizer::kFloat32x4NotEqual:
+      __ vceqqs(result, left, right);
+      // Invert the result.
+      __ veorq(QTMP, QTMP, QTMP);  // QTMP <- 0.
+      __ vornq(result, QTMP, result);  // result <- ~result.
+      break;
+    case MethodRecognizer::kFloat32x4GreaterThan:
+      __ vcgtqs(result, left, right);
+      break;
+    case MethodRecognizer::kFloat32x4GreaterThanOrEqual:
+      __ vcgeqs(result, left, right);
+      break;
+    case MethodRecognizer::kFloat32x4LessThan:
+      __ vcgtqs(result, right, left);
+      break;
+    case MethodRecognizer::kFloat32x4LessThanOrEqual:
+      __ vcgeqs(result, right, left);
+      break;
+
+    default: UNREACHABLE();
+  }
 }
 
 
@@ -3137,13 +3171,49 @@
 
 
 LocationSummary* Float32x4WithInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 2;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_in(1, Location::RequiresFpuRegister());
+  summary->set_out(Location::RequiresFpuRegister());
+  return summary;
 }
 
 
 void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  QRegister replacement = locs()->in(0).fpu_reg();
+  QRegister value = locs()->in(1).fpu_reg();
+  QRegister result = locs()->out().fpu_reg();
+
+  DRegister dresult0 = EvenDRegisterOf(result);
+  DRegister dresult1 = OddDRegisterOf(result);
+  SRegister sresult0 = EvenSRegisterOf(dresult0);
+  SRegister sresult1 = OddSRegisterOf(dresult0);
+  SRegister sresult2 = EvenSRegisterOf(dresult1);
+  SRegister sresult3 = OddSRegisterOf(dresult1);
+
+  __ vcvtsd(STMP, EvenDRegisterOf(replacement));
+  if (result != value) {
+    __ vmovq(result, value);
+  }
+
+  switch (op_kind()) {
+    case MethodRecognizer::kFloat32x4WithX:
+      __ vmovs(sresult0, STMP);
+      break;
+    case MethodRecognizer::kFloat32x4WithY:
+      __ vmovs(sresult1, STMP);
+      break;
+    case MethodRecognizer::kFloat32x4WithZ:
+      __ vmovs(sresult2, STMP);
+      break;
+    case MethodRecognizer::kFloat32x4WithW:
+      __ vmovs(sresult3, STMP);
+      break;
+    default: UNREACHABLE();
+  }
 }
 
 
@@ -3170,15 +3240,49 @@
 
 
 LocationSummary* Uint32x4GetFlagInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_out(Location::RequiresRegister());
+  return summary;
 }
 
 
 void Uint32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  QRegister value = locs()->in(0).fpu_reg();
+  Register result = locs()->out().reg();
+
+  DRegister dvalue0 = EvenDRegisterOf(value);
+  DRegister dvalue1 = OddDRegisterOf(value);
+  SRegister svalue0 = EvenSRegisterOf(dvalue0);
+  SRegister svalue1 = OddSRegisterOf(dvalue0);
+  SRegister svalue2 = EvenSRegisterOf(dvalue1);
+  SRegister svalue3 = OddSRegisterOf(dvalue1);
+
+  switch (op_kind()) {
+    case MethodRecognizer::kUint32x4GetFlagX:
+      __ vmovrs(result, svalue0);
+      break;
+    case MethodRecognizer::kUint32x4GetFlagY:
+      __ vmovrs(result, svalue1);
+      break;
+    case MethodRecognizer::kUint32x4GetFlagZ:
+      __ vmovrs(result, svalue2);
+      break;
+    case MethodRecognizer::kUint32x4GetFlagW:
+      __ vmovrs(result, svalue3);
+      break;
+    default: UNREACHABLE();
+  }
+
+  __ tst(result, ShifterOperand(result));
+  __ LoadObject(result, Bool::True(), NE);
+  __ LoadObject(result, Bool::False(), EQ);
 }
 
+
 LocationSummary* Uint32x4SelectInstr::MakeLocationSummary() const {
   UNIMPLEMENTED();
   return NULL;
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 2200310..9b5952c 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -108,8 +108,6 @@
 
 
 [ $arch == arm || $arch == simarm ]
-typed_data/float32x4_unbox_regress_test: Crash # Unimplemented
-typed_data/float32x4_list_test: Crash # Unimplemented
 typed_data/float32x4_test: Crash # Unimplemented
 
 [ $arch == mips ]
diff --git a/tests/lib/typed_data/float32x4_list_test.dart b/tests/lib/typed_data/float32x4_list_test.dart
index 79ffdbc..0de9492 100644
--- a/tests/lib/typed_data/float32x4_list_test.dart
+++ b/tests/lib/typed_data/float32x4_list_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--deoptimization_counter_threshold=1000
+// VMOptions=--deoptimization_counter_threshold=1000 --optimization-counter-threshold=10
 
 // Library tag to be able to run in html test framework.
 library float32x4_list_test;
@@ -40,49 +40,49 @@
 testLoadStoreDeoptDriver() {
   Float32x4List list = new Float32x4List(4);
   Float32x4 value = new Float32x4(1.0, 2.0, 3.0, 4.0);
-  for (int i = 0; i < 3000; i++) {
+  for (int i = 0; i < 20; i++) {
     testLoadStoreDeopt(list, 0, value);
   }
   try {
     // Invalid index.
     testLoadStoreDeopt(list, 5, value);
   } catch (_) {}
-  for (int i = 0; i < 3000; i++) {
+  for (int i = 0; i < 20; i++) {
     testLoadStoreDeopt(list, 0, value);
   }
   try {
     // null list.
     testLoadStoreDeopt(null, 0, value);
   } catch (_) {}
-  for (int i = 0; i < 3000; i++) {
+  for (int i = 0; i < 20; i++) {
     testLoadStoreDeopt(list, 0, value);
   }
   try {
     // null value.
     testLoadStoreDeopt(list, 0, null);
   } catch (_) {}
-  for (int i = 0; i < 3000; i++) {
+  for (int i = 0; i < 20; i++) {
     testLoadStoreDeopt(list, 0, value);
   }
   try {
     // non-smi index.
     testLoadStoreDeopt(list, 3.14159, value);
   } catch (_) {}
-  for (int i = 0; i < 3000; i++) {
+  for (int i = 0; i < 20; i++) {
     testLoadStoreDeopt(list, 0, value);
   }
   try {
     // non-Float32x4 value.
     testLoadStoreDeopt(list, 0, 4.toDouble());
   } catch (_) {}
-  for (int i = 0; i < 3000; i++) {
+  for (int i = 0; i < 20; i++) {
     testLoadStoreDeopt(list, 0, value);
   }
   try {
     // non-Float32x4List list.
     testLoadStoreDeopt([new Float32x4(2.0, 3.0, 4.0, 5.0)], 0, value);
   } catch (_) {}
-  for (int i = 0; i < 3000; i++) {
+  for (int i = 0; i < 20; i++) {
     testLoadStoreDeopt(list, 0, value);
   }
 }
@@ -112,7 +112,7 @@
   var list;
 
   list = new Float32x4List(8);
-  for (int i = 0; i < 3000; i++) {
+  for (int i = 0; i < 20; i++) {
     testLoadStore(list);
   }
 
@@ -121,13 +121,13 @@
     floatList[i] = i.toDouble();
   }
   list = new Float32x4List.view(floatList);
-  for (int i = 0; i < 3000; i++) {
+  for (int i = 0; i < 20; i++) {
     testView(list);
   }
-  for (int i = 0; i < 3000; i++) {
+  for (int i = 0; i < 20; i++) {
     testLoadStore(list);
   }
-  for (int i = 0; i < 3000; i++) {
+  for (int i = 0; i < 20; i++) {
     testListZero();
   }
   testLoadStoreDeoptDriver();
diff --git a/tests/lib/typed_data/float32x4_unbox_regress_test.dart b/tests/lib/typed_data/float32x4_unbox_regress_test.dart
index c20a6ea..e179f95 100644
--- a/tests/lib/typed_data/float32x4_unbox_regress_test.dart
+++ b/tests/lib/typed_data/float32x4_unbox_regress_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--deoptimization_counter_threshold=1000
+// VMOptions=--deoptimization_counter_threshold=1000 --optimization-counter-threshold=10
 
 // Library tag to be able to run in html test framework.
 library float32x4_unbox_regress_test;
@@ -18,7 +18,7 @@
   var value = new Float32x4(1.0, 2.0, 3.0, 4.0);
   var smi = 12;
   list = new Float32x4List(8);
-  for (int i = 0; i < 3000; i++) {
+  for (int i = 0; i < 20; i++) {
     testListStore(list, 0, value);
   }
 
@@ -41,7 +41,7 @@
   var a = new Float32x4(1.0, 2.0, 3.0, 4.0);
   var b = new Float32x4(2.0, 3.0, 4.0, 5.0);
   var smi = 12;
-  for (int i = 0; i < 3000; i++) {
+  for (int i = 0; i < 20; i++) {
     testAdd(a, b);
   }
 
@@ -59,7 +59,7 @@
 void testGetDeopt() {
   var a = new Float32x4(1.0, 2.0, 3.0, 4.0);
   var smi = 12;
-  for (int i = 0; i < 3000; i++) {
+  for (int i = 0; i < 20; i++) {
     testGet(a);
   }
 
@@ -68,7 +68,7 @@
   } catch (_) {
   }
 
-  for (int i = 0; i < 3000; i++) {
+  for (int i = 0; i < 20; i++) {
     testGet(a);
   }
 }
@@ -86,7 +86,7 @@
   var b = new Float32x4(1.0, 2.1, 3.1, 4.0);
   var smi = 12;
 
-  for (int i = 0; i < 2000; i++) {
+  for (int i = 0; i < 20; i++) {
     testComparison(a, b);
   }
 
@@ -95,7 +95,7 @@
   } catch (_) {
   }
 
-  for (int i = 0; i < 2000; i++) {
+  for (int i = 0; i < 20; i++) {
     testComparison(a, b);
   }
 
@@ -104,7 +104,7 @@
   } catch (_) {
   }
 
-  for (int i = 0; i < 2000; i++) {
+  for (int i = 0; i < 20; i++) {
     testComparison(a, b);
   }
 }