/*
* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package test.com.sun.max.unsafe;
import com.sun.max.program.*;
import com.sun.max.unsafe.*;
public class AddressTest extends WordTestCase {
public AddressTest(String name) {
super(name);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(AddressTest.class);
}
public void test_toString() {
String s = addressLow.toString();
assertEquals(s, "@" + Integer.toHexString(low));
s = address0.toString();
assertEquals(s, "@0");
s = addressMax.toString();
switch (wordWidth()) {
case BITS_64:
assertEquals(s, "@ffffffffffffffff");
break;
case BITS_32:
assertEquals(s, "@ffffffff");
break;
default:
throw ProgramError.unknownCase();
}
}
public void test_compareTo() {
assertTrue(addressMedium.compareTo(address0) > 0);
assertTrue(addressMedium.compareTo(addressMedium) == 0);
assertTrue(addressMedium.compareTo(addressHigh) < 0);
assertTrue(address0.compareTo(addressHigh) < 0);
assertTrue(addressMax.compareTo(address0) > 0);
assertTrue(addressMax.compareTo(addressHigh) > 0);
assertTrue(addressMax.compareTo(addressMax) == 0);
switch (wordWidth()) {
case BITS_64:
assertTrue(addressMax32.compareTo(addressMax) < 0);
break;
case BITS_32:
assertTrue(addressMax32.compareTo(addressMax) == 0);
break;
default:
throw ProgramError.unknownCase();
}
}
public void testLessThan() {
assertTrue(addressLow.lessThan(Integer.MAX_VALUE));
assertFalse(addressMax.lessThan(Integer.MAX_VALUE));
assertTrue(address0.lessThan(1));
assertFalse(address0.lessThan(0));
assertFalse(addressLow.lessThan(low));
assertTrue(addressLow.lessThan(low + 1));
assertTrue(address0.lessThan(-1));
assertTrue(address0.lessThan(-low));
switch (wordWidth()) {
case BITS_64:
assertFalse(addressHigh.lessThan(Integer.MAX_VALUE));
assertTrue(addressMax32.compareTo(addressHigh) < 0);
break;
case BITS_32:
assertTrue(addressHigh.lessThan(Integer.MAX_VALUE));
assertTrue(addressMax32.compareTo(addressHigh) > 0);
break;
default:
throw ProgramError.unknownCase();
}
}
public void testEquals() {
assertTrue(address0.equals(0));
assertTrue(address1.equals(1));
assertTrue(addressLow.equals(low));
switch (wordWidth()) {
case BITS_64:
assertFalse(addressHigh.equals((int) high));
break;
case BITS_32:
assertTrue(addressHigh.equals((int) high));
break;
default:
throw ProgramError.unknownCase();
}
assertFalse(addressLow.equals(-1));
assertFalse(addressLow.equals(-low));
addressMax.toString();
assertTrue(addressMax.equals(Address.fromLong(-1L)));
}
public void test_plus_Address() {
assertTrue(addressMedium.plus(addressLow).toInt() == medium + low);
assertTrue(address0.plus(address0).equals(address0));
assertTrue(addressMax.plus(address1).toLong() == 0L);
final long result = addressHigh.plus(addressLow).toLong();
switch (wordWidth()) {
case BITS_64:
assertTrue(result == high + low);
assertFalse(result == ((int) high + low));
break;
case BITS_32:
assertFalse(result == high + low);
assertTrue(result == ((int) high + low));
break;
default:
throw ProgramError.unknownCase();
}
}
public void test_plus_Offset() {
assertTrue(address0.plus(offset1).equals(address1));
assertTrue(address1.plus(offset1.negate()).equals(address0));
assertTrue(addressMedium.plus(Offset.fromInt(low)).toInt() == medium + low);
assertTrue(addressMedium.plus(Offset.fromInt(-low)).toInt() == medium - low);
assertTrue(address0.plus(Offset.zero()).equals(address0));
assertTrue(addressMax.plus(offset1).toLong() == 0L);
assertTrue(address0.plus(offset1.negate()).equals(addressMax));
long result = addressHigh.plus(offsetLow).toLong();
switch (wordWidth()) {
case BITS_64:
assertTrue(result == high + low);
assertFalse(result == ((int) high + low));
break;
case BITS_32:
assertFalse(result == high + low);
assertTrue(result == ((int) high + low));
break;
default:
throw ProgramError.unknownCase();
}
assertTrue(addressLow.plus(offsetHigh).equals(Address.fromLong(result)));
result = addressLow.plus(offsetHigh.negate()).toLong();
final long difference = low - high;
final long differenceLowBits = difference & 0xffffffffL;
switch (wordWidth()) {
case BITS_64:
assertTrue(result == low - high);
assertFalse(result == differenceLowBits);
break;
case BITS_32:
assertFalse(result == low - high);
assertTrue(result == differenceLowBits);
break;
default:
throw ProgramError.unknownCase();
}
}
public void test_plus_int() {
assertTrue(address0.plus(1).equals(address1));
assertTrue(address1.plus(-1).equals(address0));
assertTrue(addressMedium.plus(low).toInt() == medium + low);
assertTrue(addressMedium.plus(-low).toInt() == medium - low);
assertTrue(address0.plus(0).equals(address0));
assertTrue(addressMax.plus(1).toLong() == 0L);
assertTrue(address0.plus(-1).equals(addressMax));
final long result = addressHigh.plus(low).toLong();
switch (wordWidth()) {
case BITS_64:
assertTrue(result == high + low);
assertFalse(result == ((int) high + low));
break;
case BITS_32:
assertFalse(result == high + low);
assertTrue(result == ((int) high + low));
break;
default:
throw ProgramError.unknownCase();
}
assertTrue(addressLow.plus((int) high).equals(Address.fromInt(low + (int) high)));
}
public void test_minus_Address() {
assertTrue(address1.minus(address1).equals(address0));
assertTrue(address0.minus(address1).equals(addressMax));
assertTrue(addressMedium.minus(addressLow).toInt() == medium - low);
}
public void test_minus_Offset() {
assertTrue(address1.minus(offset1).equals(address0));
assertTrue(addressMedium.minus(offsetLow).toInt() == medium - low);
assertTrue(address0.minus(offset1).equals(addressMax));
switch (wordWidth()) {
case BITS_64: {
assertTrue(addressLow.minus(offsetMedium).equals(offsetLow.minus(offsetMedium)));
break;
}
case BITS_32: {
final long v = ((long) low - (long) medium) & LOW_32_BITS_MASK;
assertTrue(addressLow.minus(offsetMedium).toLong() == v);
break;
}
default: {
throw ProgramError.unknownCase();
}
}
}
public void test_minus_int() {
assertTrue(address1.minus(1).equals(address0));
assertTrue(addressMedium.minus(low).toInt() == medium - low);
assertTrue(addressMedium.minus(low).equals(offsetLow.negate().plus(offsetMedium)));
assertTrue(address0.minus(1).equals(addressMax));
}
public void test_dividedBy() {
try {
addressLow.dividedBy(0);
fail();
} catch (ArithmeticException arithmeticException) {
}
try {
addressLow.dividedBy(-1);
} catch (ArithmeticException arithmeticException) {
}
assertTrue(addressLow.dividedBy(4).toInt() == low / 4);
assertTrue(address0.dividedBy(42).toInt() == 0);
}
public void test_remainder() {
try {
addressLow.remainder(0);
fail();
} catch (ArithmeticException arithmeticException) {
}
try {
addressLow.remainder(-1);
} catch (ArithmeticException arithmeticException) {
}
for (int i = 0; i < 10; i++) {
assertTrue(Address.fromInt(i).remainder(4) == i % 4);
}
assertTrue(address0.remainder(42) == 0);
}
public void test_isRoundedBy() {
try {
addressLow.isRoundedBy(0);
fail();
} catch (ArithmeticException arithmeticException) {
}
try {
addressLow.isRoundedBy(-1);
} catch (ArithmeticException arithmeticException) {
}
for (int i = 0; i < 10; i++) {
assertTrue(Address.fromInt(i).isRoundedBy(4) == (i % 4 == 0));
}
assertTrue(address0.isRoundedBy(42));
}
private int roundedUpBy(int base, int number) {
final int rest = number % base;
if (rest == 0) {
return number;
}
return number + base - rest;
}
public void test_roundedUpBy() {
try {
addressLow.roundedUpBy(0);
fail();
} catch (ArithmeticException arithmeticException) {
}
try {
addressLow.roundedUpBy(-1);
} catch (ArithmeticException arithmeticException) {
}
for (int i = 0; i < 20; i++) {
assertTrue(Address.fromInt(i).roundedUpBy(8).toInt() == roundedUpBy(8, i));
}
assertTrue(address0.roundedUpBy(12).equals(address0));
}
public void test_roundedDownBy() {
try {
addressLow.roundedDownBy(0);
fail();
} catch (ArithmeticException arithmeticException) {
}
try {
addressLow.roundedDownBy(-1);
} catch (ArithmeticException arithmeticException) {
}
for (int i = 0; i < 20; i++) {
assertTrue(Address.fromInt(i).roundedDownBy(8).toInt() == (i & ~7));
}
assertTrue(address0.roundedDownBy(12).equals(address0));
}
public void test_align() {
final int n = Word.size();
assertTrue(Address.zero().wordAligned().toInt() == 0);
assertTrue(Address.fromInt(1).wordAligned().toInt() == n);
assertTrue(Address.fromInt(n).wordAligned().toInt() == n);
assertTrue(Address.fromInt(n - 1).wordAligned().toInt() == n);
assertTrue(Address.fromInt(n / 2).wordAligned().toInt() == n);
assertTrue(Address.fromInt(n + 1).wordAligned().toInt() == n + n);
assertTrue(Address.fromInt(n + (n / 2)).wordAligned().toInt() == n + n);
assertTrue(Address.fromInt(n + n).wordAligned().toInt() == n + n);
assertTrue(Address.fromInt(n + n - 1).wordAligned().toInt() == n + n);
assertTrue(Address.fromInt(2003 * n).wordAligned().toInt() == 2003 * n);
assertTrue(Address.fromInt(2003 * n - 1).wordAligned().toInt() == 2003 * n);
assertTrue(Address.fromInt(2003 * n + 1).wordAligned().toInt() == 2003 * n + n);
}
public void test_aligned() {
final int n = Word.size();
assertTrue(Address.zero().isWordAligned());
assertFalse(Address.fromInt(1).isWordAligned());
assertFalse(Address.fromInt(n - (n / 2)).isWordAligned());
assertFalse(Address.fromInt(n - 1).isWordAligned());
assertTrue(Address.fromInt(n).isWordAligned());
assertFalse(Address.fromInt(n + 1).isWordAligned());
assertFalse(Address.fromInt(n + (n / 2)).isWordAligned());
assertFalse(Address.fromInt(n + n - 1).isWordAligned());
assertTrue(Address.fromInt(n + n).isWordAligned());
assertFalse(Address.fromInt(n + n + 1).isWordAligned());
assertFalse(Address.fromInt(2003 * n - 1).isWordAligned());
assertTrue(Address.fromInt(2003 * n).isWordAligned());
assertFalse(Address.fromInt(2003 * n + 1).isWordAligned());
}
public void test_times_Address() {
assertTrue(address0.times(addressHigh).equals(address0));
assertTrue(address0.times(addressLow).toInt() == 0);
assertTrue(address1.times(address1).toInt() == 1);
assertTrue(addressTiny.times(addressTiny).toLong() == (long) tiny * (long) tiny);
assertTrue(address1.times(addressHigh).equals(addressHigh));
assertTrue(address1.times(addressLow).toInt() == addressLow.toInt());
switch (wordWidth()) {
case BITS_64:
assertTrue(addressLow.times(addressLow).toLong() == (long) low * (long) low);
assertTrue(addressMax.times(addressMax).equals(address1));
addressHigh.toLong();
addressHigh.times(addressHigh).toLong();
addressMax.toLong();
addressMax.dividedBy(2).toLong();
assertTrue(addressHigh.times(addressHigh).lessThan(addressMax.dividedBy(2)));
assertTrue(addressHigh.times(addressHigh).greaterThan(addressHigh));
break;
case BITS_32:
assertTrue(addressLow.times(addressLow).toLong() < (long) low * (long) low);
break;
default:
throw ProgramError.unknownCase();
}
}
}