Martin@582: /** Martin@582: * Back 2 Browser Bytecode Translator Martin@582: * Copyright (C) 2012 Jaroslav Tulach Martin@582: * Martin@582: * This program is free software: you can redistribute it and/or modify Martin@582: * it under the terms of the GNU General Public License as published by Martin@582: * the Free Software Foundation, version 2 of the License. Martin@582: * Martin@582: * This program is distributed in the hope that it will be useful, Martin@582: * but WITHOUT ANY WARRANTY; without even the implied warranty of Martin@582: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Martin@582: * GNU General Public License for more details. Martin@582: * Martin@582: * You should have received a copy of the GNU General Public License Martin@582: * along with this program. Look for COPYING file in the top folder. Martin@582: * If not, see http://opensource.org/licenses/GPL-2.0. Martin@582: */ Martin@582: package org.apidesign.bck2brwsr.tck; Martin@582: Martin@582: import org.apidesign.bck2brwsr.vmtest.Compare; Martin@582: import org.apidesign.bck2brwsr.vmtest.VMTest; Martin@582: import org.testng.annotations.Factory; Martin@582: Martin@582: /** Martin@582: * Martin@582: * @author Jaroslav Tulach Martin@582: */ Martin@582: public class LongArithmeticTest { lubomir@778: Martin@582: private static long add(long x, long y) { Martin@582: return (x + y); Martin@582: } lubomir@778: Martin@582: private static long sub(long x, long y) { Martin@582: return (x - y); Martin@582: } lubomir@778: Martin@582: private static long mul(long x, long y) { Martin@582: return (x * y); Martin@582: } lubomir@778: Martin@582: private static long div(long x, long y) { Martin@582: return (x / y); Martin@582: } lubomir@778: Martin@582: private static long mod(long x, long y) { Martin@582: return (x % y); Martin@582: } lubomir@778: Martin@698: private static long neg(long x) { Martin@699: return (-x); Martin@699: } lubomir@778: Martin@699: private static long shl(long x, int b) { Martin@699: return (x << b); Martin@699: } lubomir@778: Martin@699: private static long shr(long x, int b) { Martin@699: return (x >> b); Martin@699: } lubomir@778: Martin@699: private static long ushr(long x, int b) { Martin@699: return (x >>> b); Martin@699: } lubomir@778: Martin@699: private static long and(long x, long y) { Martin@699: return (x & y); Martin@699: } lubomir@778: Martin@699: private static long or(long x, long y) { Martin@699: return (x | y); Martin@699: } lubomir@778: Martin@699: private static long xor(long x, long y) { Martin@699: return (x ^ y); Martin@699: } lubomir@778: lubomir@778: private static float fadd(float x, float y) { lubomir@778: return x + y; lubomir@778: } lubomir@778: lubomir@778: private static double dadd(double x, double y) { lubomir@778: return x + y; lubomir@778: } lubomir@778: Martin@699: public static int compare(long x, long y, int zero) { Martin@699: final int xyResult = compareL(x, y, zero); Martin@699: final int yxResult = compareL(y, x, zero); Martin@699: Martin@699: return ((xyResult + yxResult) == 0) ? xyResult : -2; Martin@699: } Martin@699: Martin@699: private static int compareL(long x, long y, int zero) { Martin@699: int result = -2; Martin@699: int trueCount = 0; Martin@699: Martin@699: x += zero; Martin@699: if (x == y) { Martin@699: result = 0; Martin@699: ++trueCount; Martin@699: } Martin@699: Martin@699: x += zero; Martin@699: if (x < y) { Martin@699: result = -1; Martin@699: ++trueCount; Martin@699: } Martin@699: Martin@699: x += zero; Martin@699: if (x > y) { Martin@699: result = 1; Martin@699: ++trueCount; Martin@699: } Martin@699: Martin@699: return (trueCount == 1) ? result : -2; Martin@698: } jaroslav@1663: jaroslav@1663: @Compare public int parameterSlotCount() { jaroslav@1663: long argCounts = 281479271874563L; jaroslav@1663: int x = unpack(argCounts, 2); jaroslav@1663: return x; jaroslav@1663: } jaroslav@1663: private static char unpack(long packed, int word) { // word==0 => return a, ==3 => return d jaroslav@1663: assert(word <= 3); jaroslav@1663: final long val = packed >> ((3-word) * 16); jaroslav@1663: return (char)val; jaroslav@1663: } Martin@582: @Compare public long conversion() { Martin@582: return Long.MAX_VALUE; Martin@582: } lubomir@778: Martin@698: @Compare public long negate1() { Martin@698: return neg(0x00fa37d7763e0ca1l); Martin@698: } lubomir@778: Martin@698: @Compare public long negate2() { Martin@698: return neg(0x80fa37d7763e0ca1l); Martin@698: } Martin@698: Martin@698: @Compare public long negate3() { Martin@698: return neg(0xfffffffffffffeddl); Martin@698: } Martin@698: Martin@582: @Compare public long addOverflow() { Martin@582: return add(Long.MAX_VALUE, 1l); Martin@582: } Martin@698: Martin@582: @Compare public long subUnderflow() { Martin@582: return sub(Long.MIN_VALUE, 1l); Martin@582: } Martin@698: Martin@582: @Compare public long addMaxLongAndMaxLong() { Martin@582: return add(Long.MAX_VALUE, Long.MAX_VALUE); Martin@582: } lubomir@778: Martin@582: @Compare public long subMinLongAndMinLong() { Martin@582: return sub(Long.MIN_VALUE, Long.MIN_VALUE); Martin@582: } lubomir@778: Martin@698: @Compare public long subMinLongAndMaxLong() { Martin@698: return sub(Long.MIN_VALUE, Long.MAX_VALUE); Martin@698: } Martin@698: Martin@582: @Compare public long multiplyMaxLong() { Martin@582: return mul(Long.MAX_VALUE, 2l); Martin@582: } lubomir@778: Martin@582: @Compare public long multiplyMaxLongAndMaxLong() { Martin@582: return mul(Long.MAX_VALUE, Long.MAX_VALUE); Martin@582: } lubomir@778: Martin@582: @Compare public long multiplyMinLong() { Martin@582: return mul(Long.MIN_VALUE, 2l); Martin@582: } lubomir@778: Martin@582: @Compare public long multiplyMinLongAndMinLong() { Martin@582: return mul(Long.MIN_VALUE, Long.MIN_VALUE); Martin@582: } lubomir@778: Martin@582: @Compare public long multiplyPrecision() { Martin@698: return mul(0x00fa37d7763e0ca1l, 0xa7b3432fff00123el); Martin@582: } lubomir@778: Martin@698: @Compare public long divideSmallPositiveNumbers() { Martin@698: return div(0xabcdef, 0x123); Martin@582: } Martin@698: Martin@698: @Compare public long divideSmallNegativeNumbers() { Martin@698: return div(-0xabcdef, -0x123); Martin@582: } Martin@698: Martin@698: @Compare public long divideSmallMixedNumbers() { Martin@698: return div(0xabcdef, -0x123); Martin@698: } Martin@698: Martin@698: @Compare public long dividePositiveNumbersOneDigitDenom() { Martin@698: return div(0xabcdef0102ffffl, 0x654); Martin@698: } Martin@698: Martin@698: @Compare public long divideNegativeNumbersOneDigitDenom() { Martin@698: return div(-0xabcdef0102ffffl, -0x654); Martin@698: } Martin@698: Martin@698: @Compare public long divideMixedNumbersOneDigitDenom() { Martin@698: return div(-0xabcdef0102ffffl, 0x654); Martin@698: } Martin@698: Martin@698: @Compare public long dividePositiveNumbersMultiDigitDenom() { Martin@698: return div(0x7ffefc003322aabbl, 0x89ab1000l); Martin@698: } Martin@698: Martin@698: @Compare public long divideNegativeNumbersMultiDigitDenom() { Martin@698: return div(-0x7ffefc003322aabbl, -0x123489ab1001l); Martin@698: } Martin@698: Martin@698: @Compare public long divideMixedNumbersMultiDigitDenom() { Martin@698: return div(0x7ffefc003322aabbl, -0x38f49b0b7574e36l); Martin@698: } Martin@698: Martin@698: @Compare public long divideWithOverflow() { Martin@698: return div(0x8000fffe0000l, 0x8000ffffl); Martin@698: } Martin@698: Martin@698: @Compare public long divideWithCorrection() { Martin@698: return div(0x7fff800000000000l, 0x800000000001l); Martin@698: } Martin@698: Martin@698: @Compare public long moduloSmallPositiveNumbers() { Martin@698: return mod(0xabcdef, 0x123); Martin@698: } Martin@698: Martin@698: @Compare public long moduloSmallNegativeNumbers() { Martin@698: return mod(-0xabcdef, -0x123); Martin@698: } Martin@698: Martin@698: @Compare public long moduloSmallMixedNumbers() { Martin@698: return mod(0xabcdef, -0x123); Martin@698: } Martin@698: Martin@698: @Compare public long moduloPositiveNumbersOneDigitDenom() { Martin@698: return mod(0xabcdef0102ffffl, 0x654); Martin@698: } Martin@698: Martin@698: @Compare public long moduloNegativeNumbersOneDigitDenom() { Martin@698: return mod(-0xabcdef0102ffffl, -0x654); Martin@698: } Martin@698: Martin@698: @Compare public long moduloMixedNumbersOneDigitDenom() { Martin@698: return mod(-0xabcdef0102ffffl, 0x654); Martin@698: } Martin@698: Martin@698: @Compare public long moduloPositiveNumbersMultiDigitDenom() { Martin@698: return mod(0x7ffefc003322aabbl, 0x89ab1000l); Martin@698: } Martin@698: Martin@698: @Compare public long moduloNegativeNumbersMultiDigitDenom() { Martin@698: return mod(-0x7ffefc003322aabbl, -0x123489ab1001l); Martin@698: } Martin@698: Martin@698: @Compare public long moduloMixedNumbersMultiDigitDenom() { Martin@698: return mod(0x7ffefc003322aabbl, -0x38f49b0b7574e36l); Martin@698: } Martin@698: Martin@698: @Compare public long moduloWithOverflow() { Martin@698: return mod(0x8000fffe0000l, 0x8000ffffl); Martin@698: } Martin@698: Martin@698: @Compare public long moduloWithCorrection() { Martin@698: return mod(0x7fff800000000000l, 0x800000000001l); Martin@698: } lubomir@737: lubomir@778: @Compare public long conversionFromFloatPositive() { lubomir@778: return (long) fadd(2, 0.6f); lubomir@778: } lubomir@778: lubomir@778: @Compare public long conversionFromFloatNegative() { lubomir@778: return (long) fadd(-2, -0.6f); lubomir@778: } lubomir@778: lubomir@778: @Compare public long conversionFromDoublePositive() { lubomir@778: return (long) dadd(0x20ffff0000L, 0.6); lubomir@778: } lubomir@778: lubomir@778: @Compare public long conversionFromDoubleNegative() { lubomir@778: return (long) dadd(-0x20ffff0000L, -0.6); lubomir@778: } lubomir@778: lubomir@737: @Compare public boolean divByZeroThrowsArithmeticException() { lubomir@737: try { lubomir@737: div(1, 0); lubomir@737: return false; lubomir@737: } catch (final ArithmeticException e) { lubomir@737: return true; lubomir@737: } lubomir@737: } lubomir@737: lubomir@737: @Compare public boolean modByZeroThrowsArithmeticException() { lubomir@737: try { lubomir@737: mod(1, 0); lubomir@737: return false; lubomir@737: } catch (final ArithmeticException e) { lubomir@737: return true; lubomir@737: } lubomir@737: } lubomir@737: Martin@699: @Compare public long shiftL1() { Martin@699: return shl(0x00fa37d7763e0ca1l, 5); Martin@699: } lubomir@778: Martin@699: @Compare public long shiftL2() { Martin@699: return shl(0x00fa37d7763e0ca1l, 32); Martin@699: } lubomir@778: Martin@699: @Compare public long shiftL3() { Martin@699: return shl(0x00fa37d7763e0ca1l, 45); Martin@699: } Martin@1352: Martin@1352: @Compare public long shiftL4() { Martin@1352: return shl(0x00fa37d7763e0ca1l, 0); Martin@1352: } Martin@1352: Martin@1352: @Compare public long shiftL5() { Martin@1352: return shl(0x00fa37d7763e0ca1l, 70); Martin@1352: } lubomir@778: Martin@699: @Compare public long shiftR1() { Martin@699: return shr(0x00fa37d7763e0ca1l, 5); Martin@699: } lubomir@778: Martin@699: @Compare public long shiftR2() { Martin@699: return shr(0x00fa37d7763e0ca1l, 32); Martin@699: } lubomir@778: Martin@699: @Compare public long shiftR3() { Martin@699: return shr(0x00fa37d7763e0ca1l, 45); Martin@699: } Martin@1352: Martin@1352: @Compare public long shiftR4() { Martin@1352: return shr(0x00fa37d7763e0ca1l, 0); Martin@1352: } Martin@1352: Martin@1352: @Compare public long shiftR5() { Martin@1352: return shr(0x00fa37d7763e0ca1l, 70); Martin@1352: } lubomir@778: Martin@699: @Compare public long uShiftR1() { Martin@699: return ushr(0x00fa37d7763e0ca1l, 5); Martin@699: } lubomir@778: Martin@699: @Compare public long uShiftR2() { Martin@699: return ushr(0x00fa37d7763e0ca1l, 45); Martin@699: } Martin@1352: Martin@1352: @Compare public long uShiftR3() { Martin@1352: return ushr(0x00fa37d7763e0ca1l, 0); Martin@1352: } Martin@1352: Martin@1352: @Compare public long uShiftR4() { Martin@1352: return ushr(0x00fa37d7763e0ca1l, 70); Martin@1352: } lubomir@778: Martin@1352: @Compare public long uShiftR5() { Martin@699: return ushr(0xf0fa37d7763e0ca1l, 5); Martin@699: } lubomir@778: Martin@1352: @Compare public long uShiftR6() { Martin@699: return ushr(0xf0fa37d7763e0ca1l, 45); Martin@699: } Martin@1352: Martin@1352: @Compare public long uShiftR7() { Martin@1352: return ushr(0xf0fa37d7763e0ca1l, 0); Martin@1352: } Martin@1352: Martin@1352: @Compare public long uShiftR8() { Martin@1352: return ushr(0xf0fa37d7763e0ca1l, 70); Martin@1352: } lubomir@778: Martin@699: @Compare public long and1() { Martin@699: return and(0x00fa37d7763e0ca1l, 0xa7b3432fff00123el); Martin@699: } lubomir@778: Martin@699: @Compare public long or1() { Martin@699: return or(0x00fa37d7763e0ca1l, 0xa7b3432fff00123el); Martin@699: } lubomir@778: Martin@699: @Compare public long xor1() { Martin@699: return xor(0x00fa37d7763e0ca1l, 0xa7b3432fff00123el); Martin@699: } lubomir@778: Martin@699: @Compare public long xor2() { Martin@699: return xor(0x00fa37d7763e0ca1l, 0x00000000ff00123el); Martin@699: } lubomir@778: Martin@699: @Compare public long xor3() { Martin@699: return xor(0x00000000763e0ca1l, 0x00000000ff00123el); Martin@699: } lubomir@778: Martin@699: @Compare public int compareSameNumbers() { Martin@699: return compare(0x0000000000000000l, 0x0000000000000000l, 0); Martin@699: } Martin@699: Martin@699: @Compare public int comparePositiveNumbers() { Martin@699: return compare(0x0000000000200000l, 0x0000000010000000l, 0); Martin@699: } Martin@699: Martin@699: @Compare public int compareNegativeNumbers() { Martin@699: return compare(0xffffffffffffffffl, 0xffffffff00000000l, 0); Martin@699: } Martin@699: Martin@699: @Compare public int compareMixedNumbers() { Martin@699: return compare(0x8000000000000000l, 0x7fffffffffffffffl, 0); Martin@699: } Martin@699: Martin@582: @Factory Martin@582: public static Object[] create() { Martin@582: return VMTest.create(LongArithmeticTest.class); Martin@582: } Martin@582: }