// Copyright (c) 2011, 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.
// Dart test for testing bitwise operations.
// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation --enable-inlining-annotations

import "package:expect/expect.dart";

const neverInline = "NeverInline";

void main() {
  for (int i = 0; i < 4; i++) {
    test();
  }
}

void test() {
  Expect.equals(3, (3 & 7));
  Expect.equals(7, (3 | 7));
  Expect.equals(4, (3 ^ 7));
  Expect.equals(25, (100 >> 2));
  Expect.equals(400, (100 << 2));
  Expect.equals(-25, (-100 >> 2));
  Expect.equals(-101, ~100);
  Expect.equals(0x10000000000000000, 1 << 64);
  Expect.equals(-0x10000000000000000, -1 << 64);
  Expect.equals(0x40000000, 0x04000000 << 4);
  Expect.equals(0x4000000000000000, 0x0400000000000000 << 4);
  Expect.equals(0, ~ -1);
  Expect.equals(-1, ~0);

  Expect.equals(0, 1 >> 160);
  Expect.equals(-1, -1 >> 160);

  Expect.equals(
      0x100000000000000001, 0x100000000000000001 & 0x100000100F00000001);
  Expect.equals(0x1, 0x1 & 0x100000100F00000001);
  Expect.equals(0x1, 0x100000100F00000001 & 0x1);

  Expect.equals(
      0x100000100F00000001, 0x100000000000000001 | 0x100000100F00000001);
  Expect.equals(0x100000100F00000011, 0x11 | 0x100000100F00000001);
  Expect.equals(0x100000100F00000011, 0x100000100F00000001 | 0x11);

  Expect.equals(
      0x0F000F00000000000000, 0x0F00F00000000000001 ^ 0xFF00000000000000001);
  Expect.equals(0x31, 0xF00F00000000000001 ^ 0xF00F00000000000030);
  Expect.equals(0xF00F00000000000031, 0xF00F00000000000001 ^ 0x30);
  Expect.equals(0xF00F00000000000031, 0x30 ^ 0xF00F00000000000001);

  Expect.equals(0xF0000000000000000F, 0xF0000000000000000F7 >> 4);
  Expect.equals(15, 0xF00000000 >> 32);
  Expect.equals(1030792151040, 16492674416655 >> 4);

  Expect.equals(0xF0000000000000000F0, 0xF0000000000000000F << 4);
  Expect.equals(0xF00000000, 15 << 32);

  testNegativeValueShifts();
  testPositiveValueShifts();
  testNoMaskingOfShiftCount();
  testNegativeCountShifts();
  for (int i = 0; i < 20; i++) {
    testCornerCasesRightShifts();
    testRightShift64Bit();
    testLeftShift64Bit();
    testLeftShift64BitWithOverflow1();
    testLeftShift64BitWithOverflow2();
    testLeftShift64BitWithOverflow3();
  }

  // Test precedence.
  testPrecedence(4, 5, 3, 1);
  testPrecedence(3, 4, 5, 9);
  testPrecedence(0x5c71, 0x6b92, 0x7654, 0x7d28);

  // Test more special cases.
  testRightShift65();
}

void testCornerCasesRightShifts() {
  var v32 = 0xFF000000;
  var v64 = 0xFF00000000000000;
  Expect.equals(0x3, v32 >> 0x1E);
  Expect.equals(0x1, v32 >> 0x1F);
  Expect.equals(0x0, v32 >> 0x20);
  Expect.equals(0x3, v64 >> 0x3E);
  Expect.equals(0x1, v64 >> 0x3F);
  Expect.equals(0x0, v64 >> 0x40);
}

void testRightShift64Bit() {
  var t = 0x1ffffffff;
  Expect.equals(0xffffffff, t >> 1);
}

void testLeftShift64Bit() {
  var t = 0xffffffff;
  Expect.equals(0xffffffff, t << 0);
  Expect.equals(0x1fffffffe, t << 1);
  Expect.equals(0x7fffffff80000000, t << 31);
  Expect.equals(0x10000000000000000, 2*(t+1) << 31); //# 01: compile-time error
  Expect.equals(0x20000000000000000, 4*(t+1) << 31); //# 02: compile-time error
  Expect.equals(0x8000000000000000, (t + 1) << 31);
}

void testLeftShift64BitWithOverflow1() {
  var t = 0xffffffff;
  Expect.equals(0x10000000000000000, 2*(t+1) << 31); //# 03: compile-time error
}

void testLeftShift64BitWithOverflow2() {
  var t = 0xffffffff;
  Expect.equals(0x20000000000000000, 4*(t+1) << 31); //# 04: compile-time error
}

void testLeftShift64BitWithOverflow3() {
  var t = 0xffffffff;
  Expect.equals(0x8000000000000000, (t + 1) << 31);
}

void testNegativeCountShifts() {
  bool throwOnLeft(a, b) {
    try {
      var x = a << b;
      return false;
    } catch (e) {
      return true;
    }
  }

  bool throwOnRight(a, b) {
    try {
      var x = a >> b;
      return false;
    } catch (e) {
      return true;
    }
  }

  Expect.isTrue(throwOnLeft(12, -3));
  Expect.isTrue(throwOnRight(12, -3));
  for (int i = 0; i < 20; i++) {
    Expect.isFalse(throwOnLeft(12, 3));
    Expect.isFalse(throwOnRight(12, 3));
  }
}

void testNegativeValueShifts() {
  for (int value = 0; value > -100; value--) {
    for (int i = 0; i < 300; i++) {
      int b = (value << i) >> i;
      Expect.equals(value, b);
    }
  }
}

void testPositiveValueShifts() {
  for (int value = 0; value < 100; value++) {
    for (int i = 0; i < 300; i++) {
      int b = (value << i) >> i;
      Expect.equals(value, b);
    }
  }
}

void testNoMaskingOfShiftCount() {
  // Shifts which would behave differently if shift count was masked into a
  // range.
  Expect.equals(0, 0 >> 256);
  Expect.equals(0, 1 >> 256);
  Expect.equals(0, 2 >> 256);
  Expect.equals(0, shiftRight(0, 256));
  Expect.equals(0, shiftRight(1, 256));
  Expect.equals(0, shiftRight(2, 256));

  for (int shift = 1; shift <= 256; shift++) {
    Expect.equals(0, shiftRight(1, shift));
    Expect.equals(-1, shiftRight(-1, shift));
    Expect.equals(true, shiftLeft(1, shift) > shiftLeft(1, shift - 1));
  }
}

int shiftLeft(int a, int b) {
  return a << b;
}

int shiftRight(int a, int b) {
  return a >> b;
}

void testPrecedence(int a, int b, int c, int d) {
  // & binds stronger than ^, which binds stronger than |.
  int result = a & b ^ c | d & b ^ c;
  Expect.equals(((a & b) ^ c) | ((d & b) ^ c), result); //     &^|
  Expect.notEquals((a & (b ^ c)) | (d & (b ^ c)), result); //  ^&|
  Expect.notEquals((a & b) ^ (c | (d & b)) ^ c, result); //    &|^
  Expect.notEquals((a & b) ^ ((c | d) & b) ^ c, result); //    |&^
  Expect.notEquals(a & (b ^ (c | d)) & (b ^ c), result); //    |^&
  Expect.notEquals(a & ((b ^ c) | d) & (b ^ c), result); //    ^|&
  // Binds stronger than relational operators.
  Expect.equals((a & b) < (c & d), a & b < c & d);
  // Binds weaker than shift operators.
  Expect.equals((a & (b << c)) ^ d, a & b << c ^ d);
  Expect.notEquals((a & b) << (c ^ d), a & b << c ^ d);
}

@neverInline
rightShift65Noinline(a) => a >> 65;

testRightShift65() {
  var a = 0x5f22334455667788;
  var b = -0x5f22334455667788;

  for (var i = 0; i < 20; ++i) {
    Expect.equals(0, rightShift65Noinline(a));
    Expect.equals(-1, rightShift65Noinline(b));
  }
}
