/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. * * Alternatively, this file is licensed to You under the MIT License: * http://opensource.org/licenses/MIT . */ package gnu.testlet.vm; import gnu.testlet.Testlet; import gnu.testlet.TestHarness; class TestArithmetic implements Testlet { public int getExpectedPass() { return 276; } public int getExpectedFail() { return 0; } public int getExpectedKnownFail() { return 2; } TestHarness th; private static int int_3 = -3; private static int int1 = 1; private static int int3 = 3; private static int int5 = 5; private static int int33 = 33; private static int int65 = 65; private static long long_3 = -3; private static long long_1 = -1; private static long long0 = 0; private static long long2 = 2; private static long long10000000000 = 10000000000L; private static long long0x0110000000000011 = 0x0110000000000011L; private static long long0x1010000000000101 = 0x1010000000000101L; private static long long0xBEEFBEEFCAFEBABE = 0xBEEFBEEFCAFEBABEL; public void test(TestHarness th) { this.th = th; itest(); ltest(); ftest(); dtest(); nanTestFloat(); nanTestDouble(); } private void itest() { int a = int3; th.check(a + 1, 4); th.check(a - 1, 2); th.check(a * 3, 9); th.check(a / 2, 1); th.check(a % 2, 1); th.check(-a, -3); th.check(++a, 4); a = int_3; th.check(a + 1, -2); th.check(a - 1, -4); th.check(a * 3, -9); th.check(a / 2, -1); th.check(a % 2, -1); th.check(-a, 3); th.check(++a, -2); a = int3; // 0x00000011 int b = int5; // 0x00000101 th.check(a & b, 1); th.check(a | b, 7); th.check(a ^ b, 6); a = int_3; // 0xfffffffd; th.check(a << 1, -6); th.check(a >> 1, -2); th.check(a >>> 1, 2147483646); // funny Java shift cases a = int1; th.check(a << 32, 1); th.check((a << 16) << 16, 0); th.check(a << 33, 2); th.check(a << -1, -2147483648); th.check(a << -32, 1); th.check(a << -33, -2147483648); th.check(1 << int33, 2); th.check(a >> 32, 1); th.check((a >> 16) >> 16, 0); th.check(a >> 33, 0); th.check(a >> -1, 0); th.check(a >> -32, 1); th.check(a >> 33, 0); th.check(-4 >> int33, -2); th.check(a >>> 32, 1); th.check((a >>> 16) >>> 16, 0); th.check(a >>> 33, 0); th.check(a >>> -1, 0); th.check(a >>> -32, 1); th.check(a >>> -33, 0); th.check(-4 >>> int33, 2147483646); // IA32 bit test patterns th.check(((1 << int1) & int3) != 0); th.check(((1 << int33) & int3) != 0); th.check((int3 & (1 << int1)) != 0); th.check((int3 & (1 << int33)) != 0); th.check(((int3 >> int1) & 1) == 1); th.check(((int3 >> int33) & 1) == 1); th.check(((int3 >>> int1) & 1) == 1); th.check(((int3 >>> int33) & 1) == 1); // Rotate tests th.check((int5 << 1)|(int5 >>> -1), 10); // Rotate left by 1 th.check((int5 >>> -1)|(int5 << 1), 10); // Rotate left by 1 th.check((int5 << -1)|(int5 >>> 1), -2147483646); // Rotate right by 1 th.check((int5 >>> 1)|(int5 << -1), -2147483646); // Rotate right by 1 th.check((int5 << int1)|(int5 >>> -int1), 10); // Rotate left by 1 th.check((int5 >>> -int1)|(int5 << int1), 10); // Rotate left by 1 th.check((int5 << -int1)|(int5 >>> int1), -2147483646); // Rotate right by 1 th.check((int5 >>> int1)|(int5 << -int1), -2147483646); // Rotate right by 1 } private void ltest() { long a = long10000000000; long b = long2; th.check(a + b, 10000000002L); th.check(a - b, 9999999998L); th.check(a * b, 20000000000L); th.check(a / b, 5000000000L); th.check(a % b, 0); th.check(-b, -2); th.check(-a, -10000000000L); a = long_3; th.check(a + 2, -1); th.check(a - 2, -5); th.check(a * 3, -9); th.check(a / 2, -1); th.check(a % 2, -1); th.check(-a, 3); a = long0x0110000000000011; b = long0x1010000000000101; th.check(a & b, 4503599627370497L); th.check(a | b, 1229482698272145681L); th.check(a ^ b, 1224979098644775184L); // bit patterns that can be optimized for certain operators if converting // long operators into int operators long long0x00000000FFFFFFFF = 0x00000000FFFFFFFFL; long long0xFFFFFFFF00000000 = 0xFFFFFFFF00000000L; long long0x00000001FFFFFFFF = 0x00000001FFFFFFFFL; long long0xFFFFFFFF00000001 = 0xFFFFFFFF00000001L; long long0x0000000100000000 = 0x0000000100000000L; long long0x0000000100000001 = 0x0000000100000001L; a = long_1; th.check(a * long0x00000000FFFFFFFF, -4294967295L); th.check(a * long0xFFFFFFFF00000000, 4294967296L); th.check(a * long0x00000001FFFFFFFF, -8589934591L); th.check(a * long0xFFFFFFFF00000001, 4294967295L); th.check(a * long0x0000000100000000, -4294967296L); th.check(a * long0x0000000100000001, -4294967297L); th.check(a & long0x00000000FFFFFFFF, 4294967295L); th.check(a & long0xFFFFFFFF00000000, -4294967296L); th.check(a & long0x00000001FFFFFFFF, 8589934591L); th.check(a & long0xFFFFFFFF00000001, -4294967295L); th.check(a & long0x0000000100000000, 4294967296L); th.check(a & long0x0000000100000001, 4294967297L); a = long0; th.check(a | long0x00000000FFFFFFFF, 4294967295L); th.check(a | long0xFFFFFFFF00000000, -4294967296L); th.check(a | long0x00000001FFFFFFFF, 8589934591L); th.check(a | long0xFFFFFFFF00000001, -4294967295L); th.check(a | long0x0000000100000001, 4294967297L); th.check(a ^ long0x00000000FFFFFFFF, 4294967295L); th.check(a ^ long0xFFFFFFFF00000000, -4294967296L); th.check(a ^ long0x00000001FFFFFFFF, 8589934591L); th.check(a ^ long0xFFFFFFFF00000001, -4294967295L); th.check(a ^ long0x0000000100000001, 4294967297L); a = long0xBEEFBEEFCAFEBABE; th.check(a << 1, 9070106573795063164L); th.check(a << 2, -306530926119425288L); th.check(a << 3, -613061852238850576L); th.check(a << 4, -1226123704477701152L); th.check(a << 8, -1171235197933666816L); th.check(a << 16, -4688305491665879040L); th.check(a << 32, -3819410108757049344L); th.check(a << 33, -7638820217514098688L); th.check(a << 34, 3169103638681354240L); th.check(a << 35, 6338207277362708480L); th.check(a << 36, -5770329518984134656L); th.check(a << 40, -91551935198396416L); th.check(a << 48, -4990551337079930880L); th.check(a << 56, -4755801206503243776L); th.check(a << 63, 0L); th.check(a << 64, -4688318749957244226L); th.check(a << 65, 9070106573795063164L); th.check(a << int65, 9070106573795063164L); th.check(a >> 1, -2344159374978622113L); th.check(a >> 2, -1172079687489311057L); th.check(a >> 3, -586039843744655529L); th.check(a >> 4, -293019921872327765L); th.check(a >> 8, -18313745117020486L); th.check(a >> 16, -71538066863362L); th.check(a >> 32, -1091584273L); th.check(a >> 33, -545792137L); th.check(a >> 34, -272896069L); th.check(a >> 35, -136448035L); th.check(a >> 36, -68224018L); th.check(a >> 40, -4264002L); th.check(a >> 48, -16657L); th.check(a >> 56, -66L); th.check(a >> 63, -1L); th.check(a >> 64, -4688318749957244226L); th.check(a >> 65, -2344159374978622113L); th.check(a >> int65, -2344159374978622113L); th.check(a >>> 1, 6879212661876153695L); th.check(a >>> 2, 3439606330938076847L); th.check(a >>> 3, 1719803165469038423L); th.check(a >>> 4, 859901582734519211L); th.check(a >>> 8, 53743848920907450L); th.check(a >>> 16, 209936909847294L); th.check(a >>> 32, 3203383023L); th.check(a >>> 33, 1601691511L); th.check(a >>> 34, 800845755L); th.check(a >>> 35, 400422877L); th.check(a >>> 36, 200211438L); th.check(a >>> 40, 12513214L); th.check(a >>> 48, 48879L); th.check(a >>> 56, 190L); th.check(a >>> 63, 1L); th.check(a >>> 64, -4688318749957244226L); th.check(a >>> 65, 6879212661876153695L); th.check(a >>> int65, 6879212661876153695L); } private static float float0 = 0.0f; private static float float0_9 = 0.9f; private static float float1 = 1.0f; private static float float1_5 = 1.5f; private static float float2 = 2.0f; private static float float_maxint = (float)Integer.MAX_VALUE; private static float float_minint = (float)Integer.MIN_VALUE; private static double double0 = 0.0f; private static double double1 = 1.0f; private static double double2 = 2.0f; private static double double_maxint = (double)Integer.MAX_VALUE; private static double double_minint = (double)Integer.MIN_VALUE; private static float float_maxlong = (float)Long.MAX_VALUE; private static float float_minlong = (float)Long.MIN_VALUE; private static double double_maxlong = (double)Long.MAX_VALUE; private static double double_minlong = (double)Long.MIN_VALUE; private void checkFloatToInt(float val1, int val2) { th.check((int)val1, val2); } private void checkIntToFloat(int val1, float val2) { th.check((float)val1, val2); } private void checkIntToFloatRel(int val1, float val2) { th.check(Math.abs((float)val1 - val2) / val2 < 1E-9); } private void checkDoubleToInt(double val1, int val2) { th.check((int)val1, val2); } private void checkIntToDouble(int val1, double val2) { th.check((double)val1, val2); } private void checkFloatToLong(float val1, long val2) { th.check((long)val1, val2); } private void checkLongToFloat(long val1, float val2) { th.check((float)val1, val2); } private void todoFloatToLong(float val1, long val2) { th.todo((long)val1, val2); } private void checkDoubleToLong(double val1, long val2) { th.check((long)val1, val2); } private void checkLongToDouble(long val1, double val2) { th.check((double)val1, val2); } private void ftest() { // f2i, d2i, f2l and d2l tests checkFloatToInt(float0, 0); checkFloatToInt(float1, 1); checkDoubleToInt(double0, 0); checkDoubleToInt(double1, 1); checkFloatToInt(Float.NaN, 0); checkFloatToInt(-Float.NaN, 0); checkDoubleToInt(Double.NaN, 0); checkDoubleToInt(-Double.NaN, 0); checkFloatToInt(Float.POSITIVE_INFINITY, 2147483647); checkFloatToInt(Float.NEGATIVE_INFINITY, -2147483648); checkFloatToInt(float_maxint, 2147483647); checkFloatToInt(float_minint, -2147483648); checkDoubleToInt(double_maxint, 2147483647); checkDoubleToInt(double_minint, -2147483648); checkIntToFloat(0, float0); checkIntToFloat(1, float1); checkIntToDouble(0, double0); checkIntToDouble(1, double1); checkIntToFloatRel(2147483647, (float)2.14748365E9); checkIntToFloat(-2147483648, (float)-2.14748365E9); checkIntToFloatRel(2147483647, float_maxint); checkIntToFloat(-2147483648, float_minint); checkIntToDouble(2147483647, double_maxint); checkIntToDouble(-2147483648, double_minint); checkFloatToLong(float0, 0L); checkFloatToLong(float1, 1L); checkDoubleToLong(double0, 0L); checkDoubleToLong(double1, 1L); checkFloatToLong(Float.NaN, 0L); checkFloatToLong(-Float.NaN, 0L); checkDoubleToLong(Double.NaN, 0L); checkDoubleToLong(-Double.NaN, 0L); todoFloatToLong(Float.POSITIVE_INFINITY, 9223372036854775807L); todoFloatToLong(Float.NEGATIVE_INFINITY, -9223372036854775808L); checkFloatToLong(float_maxlong, 9223372036854775807L); checkFloatToLong(float_minlong, -9223372036854775808L); checkDoubleToLong(double_maxlong, 9223372036854775807L); checkDoubleToLong(double_minlong, -9223372036854775808L); checkLongToFloat(0L, float0); checkLongToFloat(1L, float1); checkLongToDouble(0L, double0); checkLongToDouble(1L, double1); checkLongToFloat(9223372036854775807L, (float)9.223372E18); checkLongToFloat(-9223372036854775808L, (float)-9.223372E18); checkLongToFloat(9223372036854775807L, float_maxlong); checkLongToFloat(-9223372036854775808L, float_minlong); checkLongToDouble(9223372036854775807L, double_maxlong); checkLongToDouble(-9223372036854775808L, double_minlong); float a = float1; float b = float2; th.check(Integer.toHexString(Float.floatToIntBits(a + b)), Integer.toHexString(Float.floatToIntBits(3.0F))); // fadd th.check(Integer.toHexString(Float.floatToIntBits(a - b)), Integer.toHexString(Float.floatToIntBits(-1.0F))); // fsub th.check(Integer.toHexString(Float.floatToIntBits(a * b)), Integer.toHexString(Float.floatToIntBits(2.0F))); // fmul th.check(Integer.toHexString(Float.floatToIntBits(a / b)), Integer.toHexString(Float.floatToIntBits(0.5F))); // fdiv th.check(Integer.toHexString(Float.floatToIntBits(-a)), Integer.toHexString(Float.floatToIntBits(-1.0F))); // fneg a = float1_5; b = float0_9; th.check(Integer.toHexString(Float.floatToIntBits(a % b)), Integer.toHexString(Float.floatToIntBits(0.6F))); // frem th.check(String.valueOf(float0/float0), "NaN"); th.check(String.valueOf(Float.NaN + Float.NaN), "NaN"); th.check(String.valueOf(Float.NaN + float2), "NaN"); th.check(String.valueOf(Float.NaN * float2), "NaN"); th.check(String.valueOf((float0 / 0.0) * Float.POSITIVE_INFINITY), "NaN"); th.check(String.valueOf((float1 / 0.0) * 0.0), "NaN"); th.check(String.valueOf((float1 / 0.0) - (float1 / 0.0)), "NaN"); th.check(String.valueOf((float1 / 0.0) / (float1 / 0.0)), "NaN"); th.check(String.valueOf((-float1 / 0.0) * 0.0), "NaN"); th.check(String.valueOf((-float1 / 0.0) - (-float1 / 0.0)), "NaN"); th.check(!(Float.NaN > float1)); th.check(!(Float.NaN < float1)); th.check(Float.NaN != float1); th.check(Float.NaN != -float1); th.check(!(Float.NaN > Float.POSITIVE_INFINITY)); th.check(!(Float.NaN < Float.POSITIVE_INFINITY)); th.check(Float.POSITIVE_INFINITY == Float.POSITIVE_INFINITY); th.check(-Float.POSITIVE_INFINITY == Float.NEGATIVE_INFINITY); th.check(Float.NEGATIVE_INFINITY < float1); th.check((-float1/0.0) == (-float1/0.0)); th.check(float1/0.0, Float.POSITIVE_INFINITY); th.check((float1/0.0) + 2.0, Float.POSITIVE_INFINITY); th.check((float1/0.0) * 0.5, Float.POSITIVE_INFINITY); th.check((float1/0.0) + (float1/0.0), Float.POSITIVE_INFINITY); th.check((float1/0.0) * (float1/0.0), Float.POSITIVE_INFINITY); th.check(Math.abs(-float1/0.0), Float.POSITIVE_INFINITY); th.check(-float1/0.0, Float.NEGATIVE_INFINITY); th.check((-float1/0.0) + 2.0, Float.NEGATIVE_INFINITY); th.check((-float1/0.0) * 0.5, Float.NEGATIVE_INFINITY); th.check((int)(float1/0.0), 2147483647); th.check((int)(-float1/0.0), -2147483648); } private void dtest() { double a = 1; double b = 2; th.check(Double.doubleToLongBits(a + b), Double.doubleToLongBits(3.0D)); // dadd th.check(Double.doubleToLongBits(a - b), Double.doubleToLongBits(-1.0D)); // dsub th.check(Double.doubleToLongBits(a * b), Double.doubleToLongBits(2.0D)); // dmul th.check(Double.doubleToLongBits(a / b), Double.doubleToLongBits(0.5D)); // ddiv th.check(Double.doubleToLongBits(-a), Double.doubleToLongBits(-1.0D)); // dneg a = 1.5; b = 0.9; th.check(Double.doubleToLongBits(a % b), Double.doubleToLongBits(0.6D)); // drem th.check(String.valueOf(double0/double0), "NaN"); th.check(String.valueOf(Double.NaN + Double.NaN), "NaN"); th.check(String.valueOf(Double.NaN + double2), "NaN"); th.check(String.valueOf(Double.NaN * double2), "NaN"); th.check(String.valueOf((double0 / 0.0) * Double.POSITIVE_INFINITY), "NaN"); th.check(String.valueOf((double1 / 0.0) * 0.0), "NaN"); th.check(String.valueOf((double1 / 0.0) - (double1 / 0.0)), "NaN"); th.check(String.valueOf((double1 / 0.0) / (double1 / 0.0)), "NaN"); th.check(String.valueOf((-double1 / 0.0) * 0.0), "NaN"); th.check(String.valueOf((-double1 / 0.0) - (-double1 / 0.0)), "NaN"); th.check(!(Double.NaN > double1)); th.check(!(Double.NaN < double1)); th.check(Double.NaN != double1); th.check(Double.NaN != -double1); th.check(!(Double.NaN > Double.POSITIVE_INFINITY)); th.check(!(Double.NaN < Double.POSITIVE_INFINITY)); th.check(Double.POSITIVE_INFINITY == Double.POSITIVE_INFINITY); th.check(-Double.POSITIVE_INFINITY == Double.NEGATIVE_INFINITY); th.check(Double.NEGATIVE_INFINITY < double1); th.check((-double1/0.0) == (-double1/0.0)); th.check(double1/0.0, Double.POSITIVE_INFINITY); th.check((double1/0.0) + 2.0, Double.POSITIVE_INFINITY); th.check((double1/0.0) * 0.5, Double.POSITIVE_INFINITY); th.check((double1/0.0) + (double1/0.0), Double.POSITIVE_INFINITY); th.check((double1/0.0) * (double1/0.0), Double.POSITIVE_INFINITY); th.check(Math.abs(-double1/0.0), Double.POSITIVE_INFINITY); th.check(-double1/0.0, Double.NEGATIVE_INFINITY); th.check((-double1/0.0) + 2.0, Double.NEGATIVE_INFINITY); th.check((-double1/0.0) * 0.5, Double.NEGATIVE_INFINITY); th.check((int)(double1/0.0), 2147483647); th.check((int)(-double1/0.0), -2147483648); th.check((int)Double.NaN, 0); } private void nanTestFloat() { float zero = float0; float NaN = zero / zero; th.check(!(NaN < NaN)); th.check(NaN != NaN); th.check(!(NaN > NaN)); } private void nanTestDouble() { double zero = 0; double NaN = zero / zero; th.check(!(NaN < NaN)); th.check(NaN != NaN); th.check(!(NaN > NaN)); } }