blob: 47d3b0b9f07e8d9f133a1433481cdcf0d1222419 [file] [log] [blame]
// Copyright (c) 2019, 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 = 2.9
// VMOptions=--deterministic
// VMOptions=--deterministic --use_slow_path
// Unit tests on DIV and MOV operations by various constants.
import "package:expect/expect.dart";
int kMin = 0x8000000000000000;
int kMax = 0x7fffffffffffffff;
// The basic DIV operation.
int divme(int x, int c) {
return x ~/ c;
}
// The basic MOD operation.
int modme(int x, int c) {
return x % c;
}
//
// Test several "hidden" DIV constants.
//
@pragma("vm:never-inline")
int div0(int x) {
return divme(x, 0);
}
@pragma("vm:never-inline")
int div1(int x) {
return divme(x, 1);
}
@pragma("vm:never-inline")
int divm1(int x) {
return divme(x, -1);
}
@pragma("vm:never-inline")
int div2(int x) {
return divme(x, 2);
}
@pragma("vm:never-inline")
int divm2(int x) {
return divme(x, -2);
}
@pragma("vm:never-inline")
int div37(int x) {
return divme(x, 37);
}
@pragma("vm:never-inline")
int div131(int x) {
return divme(x, 131);
}
@pragma("vm:never-inline")
int divm333(int x) {
return divme(x, -333);
}
@pragma("vm:never-inline")
int divmin(int x) {
return divme(x, kMin);
}
@pragma("vm:never-inline")
int divmax(int x) {
return divme(x, kMax);
}
//
// Test several "hidden" MOD constants.
//
@pragma("vm:never-inline")
int mod0(int x) {
return modme(x, 0);
}
@pragma("vm:never-inline")
int mod1(int x) {
return modme(x, 1);
}
@pragma("vm:never-inline")
int modm1(int x) {
return modme(x, -1);
}
@pragma("vm:never-inline")
int mod2(int x) {
return modme(x, 2);
}
@pragma("vm:never-inline")
int modm2(int x) {
return modme(x, -2);
}
@pragma("vm:never-inline")
int mod37(int x) {
return modme(x, 37);
}
@pragma("vm:never-inline")
int mod131(int x) {
return modme(x, 131);
}
@pragma("vm:never-inline")
int modm333(int x) {
return modme(x, -333);
}
@pragma("vm:never-inline")
int modmin(int x) {
return modme(x, kMin);
}
@pragma("vm:never-inline")
int modmax(int x) {
return modme(x, kMax);
}
main() {
// Exceptional case DIV.
for (int i = -1; i <= 1; i++) {
bool threw = false;
try {
div0(i);
} on UnsupportedError catch (e) {
threw = true;
}
Expect.isTrue(threw);
}
// Exceptional case MOD.
for (int i = -1; i <= 1; i++) {
bool threw = false;
try {
mod0(i);
} on UnsupportedError catch (e) {
threw = true;
}
Expect.isTrue(threw);
}
// DIV by +/- 1.
Expect.equals(kMin, div1(kMin));
Expect.equals(kMin, divm1(kMin));
for (int i = -999; i <= 999; i++) {
Expect.equals(i, div1(i));
Expect.equals(-i, divm1(i));
}
Expect.equals(kMax, div1(kMax));
Expect.equals(-kMax, divm1(kMax));
// MOD by +/- 1.
Expect.equals(0, mod1(kMin));
Expect.equals(0, modm1(kMin));
for (int i = -999; i <= 999; i++) {
Expect.equals(0, mod1(i));
Expect.equals(0, modm1(i));
}
Expect.equals(0, mod1(kMax));
Expect.equals(0, modm1(kMax));
// DIV by +/- 2.
Expect.equals(-4611686018427387904, div2(kMin));
Expect.equals(-4611686018427387903, div2(kMin + 1));
Expect.equals(-4611686018427387903, div2(kMin + 2));
Expect.equals(4611686018427387904, divm2(kMin));
Expect.equals(4611686018427387903, divm2(kMin + 1));
Expect.equals(4611686018427387903, divm2(kMin + 2));
for (int i = -999; i <= 999; i++) {
int e = (i + ((i < 0) ? 1 : 0)) >> 1;
Expect.equals(e, div2(i));
Expect.equals(-e, divm2(i));
}
Expect.equals(4611686018427387903, div2(kMax));
Expect.equals(4611686018427387903, div2(kMax - 1));
Expect.equals(4611686018427387902, div2(kMax - 2));
Expect.equals(-4611686018427387903, divm2(kMax));
Expect.equals(-4611686018427387903, divm2(kMax - 1));
Expect.equals(-4611686018427387902, divm2(kMax - 2));
// MOD by +/- 2.
Expect.equals(0, mod2(kMin));
Expect.equals(1, mod2(kMin + 1));
Expect.equals(0, mod2(kMin + 2));
Expect.equals(0, modm2(kMin));
Expect.equals(1, modm2(kMin + 1));
Expect.equals(0, modm2(kMin + 2));
for (int i = -999; i <= 999; i++) {
Expect.equals(i & 1, mod2(i));
Expect.equals(i & 1, modm2(i));
}
Expect.equals(1, mod2(kMax));
Expect.equals(0, mod2(kMax - 1));
Expect.equals(1, mod2(kMax - 2));
Expect.equals(1, modm2(kMax));
Expect.equals(0, modm2(kMax - 1));
Expect.equals(1, modm2(kMax - 2));
// DIV/MOD by 37.
Expect.equals(-249280325320399346, div37(kMin));
Expect.equals(31, mod37(kMin));
for (int i = -999; i <= 999; i++) {
Expect.equals(i, div37(37 * i));
Expect.equals(i, div37(37 * i + ((i >= 0) ? 36 : -36)));
Expect.equals(0, mod37(37 * i));
Expect.equals(1, mod37(37 * i + 1));
Expect.equals(36, mod37(37 * i + 36));
}
for (int i = 1; i < 37; i++) {
Expect.equals(0, div37(i));
Expect.equals(i, mod37(i));
Expect.equals(0, div37(-i));
Expect.equals(37 - i, mod37(-i));
}
Expect.equals(249280325320399346, div37(kMax));
Expect.equals(5, mod37(kMax));
// DIV/MOD by 131.
Expect.equals(-70407420128662410, div131(kMin));
Expect.equals(33, mod131(kMin));
for (int i = -999; i <= 999; i++) {
Expect.equals(i, div131(131 * i));
Expect.equals(i, div131(131 * i + ((i >= 0) ? 130 : -130)));
Expect.equals(0, mod131(131 * i));
Expect.equals(1, mod131(131 * i + 1));
Expect.equals(130, mod131(131 * i + 130));
}
for (int i = 1; i < 131; i++) {
Expect.equals(0, div131(i));
Expect.equals(i, mod131(i));
Expect.equals(0, div131(-i));
Expect.equals(131 - i, mod131(-i));
}
Expect.equals(70407420128662410, div131(kMax));
Expect.equals(97, mod131(kMax));
// DIV/MOD by -333.
Expect.equals(27697813924488816, divm333(kMin));
Expect.equals(253, modm333(kMin));
for (int i = -999; i <= 999; i++) {
Expect.equals(i, divm333(-333 * i));
Expect.equals(i, divm333(-333 * i + ((i < 0) ? 130 : -130)));
Expect.equals(0, modm333(-333 * i));
Expect.equals(1, modm333(-333 * i + 1));
Expect.equals(130, modm333(-333 * i + 130));
}
Expect.equals(-27697813924488816, divm333(kMax));
Expect.equals(79, modm333(kMax));
// DIV/MOD by Min.
Expect.equals(1, divmin(kMin));
Expect.equals(0, modmin(kMin));
for (int i = -999; i <= 999; i++) {
Expect.equals(0, divmin(i));
Expect.equals(i >= 0 ? i : 1 + kMax + i, modmin(i));
}
Expect.equals(0, divmin(kMax));
Expect.equals(kMax, modmin(kMax));
// DIV/MOD by Max.
Expect.equals(-1, divmax(kMin));
Expect.equals(kMax - 1, modmax(kMin));
for (int i = -999; i <= 999; i++) {
Expect.equals(0, divmax(i));
Expect.equals(i >= 0 ? i : kMax + i, modmax(i));
}
Expect.equals(1, divmax(kMax));
Expect.equals(0, modmax(kMax));
// Exceptional null value MOD.
bool threwDiv = false;
try {
div2(null);
} on NoSuchMethodError catch (e) {
threwDiv = true;
}
Expect.isTrue(threwDiv);
// Exceptional null value MOD.
bool threwMod = false;
try {
mod2(null);
} on NoSuchMethodError catch (e) {
threwMod = true;
}
Expect.isTrue(threwMod);
}