// 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=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation

// Library tag to be able to run in html test framework.
library float32x4_unbox_regress_test;

import 'dart:typed_data';
import 'package:expect/expect.dart';

testListStore(array, index, value) {
  array[index] = value;
}

void testListStoreDeopt() {
  var list;
  var value = new Float32x4(1.0, 2.0, 3.0, 4.0);
  var smi = 12;
  list = new Float32x4List(8);
  for (int i = 0; i < 20; i++) {
    testListStore(list, 0, value);
  }

  try {
    // Without a proper check for SMI in the Float32x4 unbox instruction
    // this might trigger a crash.
    testListStore(list, 0, smi);
  } catch (_) { }
}

testAdd(a, b) {
  var c = a + b;
  Expect.equals(3.0, c.x);
  Expect.equals(5.0, c.y);
  Expect.equals(7.0, c.z);
  Expect.equals(9.0, c.w);
}

void testAddDeopt() {
  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 < 20; i++) {
    testAdd(a, b);
  }

  try {
    testAdd(a, smi);
  } catch (_) {}
}


testGet(a) {
  var c = a.x + a.y + a.z + a.w;
  Expect.equals(10.0, c);
}

void testGetDeopt() {
  var a = new Float32x4(1.0, 2.0, 3.0, 4.0);
  var smi = 12;
  for (int i = 0; i < 20; i++) {
    testGet(a);
  }

  try {
    testGet(12);
  } catch (_) {
  }

  for (int i = 0; i < 20; i++) {
    testGet(a);
  }
}

void testComparison(a, b) {
  Int32x4 r = a.equal(b);
  Expect.equals(true, r.flagX);
  Expect.equals(false, r.flagY);
  Expect.equals(false, r.flagZ);
  Expect.equals(true, r.flagW);
}

void testComparisonDeopt() {
  var a = new Float32x4(1.0, 2.0, 3.0, 4.0);
  var b = new Float32x4(1.0, 2.1, 3.1, 4.0);
  var smi = 12;

  for (int i = 0; i < 20; i++) {
    testComparison(a, b);
  }

  try {
    testComparison(a, smi);
  } catch (_) {
  }

  for (int i = 0; i < 20; i++) {
    testComparison(a, b);
  }

  try {
    testComparison(smi, a);
  } catch (_) {
  }

  for (int i = 0; i < 20; i++) {
    testComparison(a, b);
  }
}

main() {
  testListStoreDeopt();
  testAddDeopt();
  testGetDeopt();
  testComparisonDeopt();
}
