Add SIGNEXTEND op code

This commit is contained in:
nicksavers 2014-11-06 00:05:57 +01:00
parent 88e044cbbe
commit 5aeade32e2
3 changed files with 105 additions and 1 deletions

View File

@ -278,7 +278,7 @@ public class DataWord implements Comparable<DataWord> {
return true; return true;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return java.util.Arrays.hashCode(data); return java.util.Arrays.hashCode(data);
@ -293,4 +293,13 @@ public class DataWord implements Comparable<DataWord> {
// Convert result into -1, 0 or 1 as is the convention // Convert result into -1, 0 or 1 as is the convention
return (int) Math.signum(result); return (int) Math.signum(result);
} }
public void signExtend(byte k) {
if (k > 31)
throw new IndexOutOfBoundsException();
byte mask = this.sValue().testBit((k * 8) + 7) ? (byte) 0xff : 0;
for (int i = 31; i > k; i--) {
this.data[31 - i] = mask;
}
}
} }

View File

@ -280,6 +280,19 @@ public class VM {
program.stackPush(word1); program.stackPush(word1);
program.step(); program.step();
} break; } break;
case SIGNEXTEND: {
DataWord word1 = program.stackPop();
BigInteger k = word1.value();
if (k.compareTo(_32_) < 0) {
DataWord word2 = program.stackPop();
if (logger.isInfoEnabled())
hint = word1 + " " + word2.value();
word2.signExtend(k.byteValue());
program.stackPush(word2);
}
program.step();
} break;
case NOT:{ case NOT:{
DataWord word1 = program.stackPop(); DataWord word1 = program.stackPop();
word1.bnot(); word1.bnot();

View File

@ -134,6 +134,88 @@ public class DataWordTest {
System.out.println(result2); System.out.println(result2);
} }
@Test
public void testSignExtend1() {
DataWord x = new DataWord(Hex.decode("f2"));
byte k = 0;
String expected = "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2";
x.signExtend(k);
System.out.println(x.toString());
assertEquals(expected, x.toString());
}
@Test
public void testSignExtend2() {
DataWord x = new DataWord(Hex.decode("f2"));
byte k = 1;
String expected = "00000000000000000000000000000000000000000000000000000000000000f2";
x.signExtend(k);
System.out.println(x.toString());
assertEquals(expected, x.toString());
}
@Test
public void testSignExtend3() {
byte k = 1;
DataWord x = new DataWord(Hex.decode("0f00ab"));
String expected = "00000000000000000000000000000000000000000000000000000000000000ab";
x.signExtend(k);
System.out.println(x.toString());
assertEquals(expected, x.toString());
}
@Test
public void testSignExtend4() {
byte k = 1;
DataWord x = new DataWord(Hex.decode("ffff"));
String expected = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
x.signExtend(k);
System.out.println(x.toString());
assertEquals(expected, x.toString());
}
@Test
public void testSignExtend5() {
byte k = 3;
DataWord x = new DataWord(Hex.decode("ffffffff"));
String expected = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
x.signExtend(k);
System.out.println(x.toString());
assertEquals(expected, x.toString());
}
@Test
public void testSignExtend6() {
byte k = 3;
DataWord x = new DataWord(Hex.decode("ab02345678"));
String expected = "0000000000000000000000000000000000000000000000000000000002345678";
x.signExtend(k);
System.out.println(x.toString());
assertEquals(expected, x.toString());
}
@Test
public void testSignExtend7() {
byte k = 3;
DataWord x = new DataWord(Hex.decode("ab82345678"));
String expected = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff82345678";
x.signExtend(k);
System.out.println(x.toString());
assertEquals(expected, x.toString());
}
public static BigInteger pow(BigInteger x, BigInteger y) { public static BigInteger pow(BigInteger x, BigInteger y) {
if (y.compareTo(BigInteger.ZERO) < 0) if (y.compareTo(BigInteger.ZERO) < 0)