Skip to content

Commit

Permalink
Initial simd parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
andreaTP committed Oct 12, 2024
1 parent f9ed8c6 commit 31deb74
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 1 deletion.
54 changes: 54 additions & 0 deletions wasm/src/main/java/com/dylibso/chicory/wasm/Validator.java
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,60 @@ public void validateFunction(int funcIdx, FunctionBody body, FunctionType functi
getElement(index);
break;
}
case V128_LOAD:
{
popVal(ValueType.I32);
pushVal(ValueType.V128);
break;
}
case V128_CONST:
{
pushVal(ValueType.V128);
break;
}
case I8x16_ALL_TRUE:
case I8x16_EXTRACT_LANE_S:
{
popVal(ValueType.V128);
pushVal(ValueType.I32);
break;
}
case I8x16_EQ:
case I8x16_SUB:
case I8x16_ADD:
case I8x16_SWIZZLE:
case F32x4_MUL:
case F32x4_MIN:
{
popVal(ValueType.V128);
popVal(ValueType.V128);
pushVal(ValueType.V128);
break;
}
case F32x4_ABS:
case I32x4_TRUNC_SAT_F32X4_S:
case F32x4_CONVERT_I32x4_U:
case V128_NOT:
{
popVal(ValueType.V128);
pushVal(ValueType.V128);
break;
}
case V128_BITSELECT:
{
popVal(ValueType.V128);
popVal(ValueType.V128);
popVal(ValueType.V128);
pushVal(ValueType.V128);
break;
}
case I8x16_SHL:
{
popVal(ValueType.I32);
popVal(ValueType.V128);
pushVal(ValueType.V128);
break;
}
default:
throw new IllegalArgumentException(
"Missing type validation opcode handling for " + op.opcode());
Expand Down
19 changes: 18 additions & 1 deletion wasm/src/main/java/com/dylibso/chicory/wasm/types/OpCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,24 @@ public enum OpCode {
TABLE_COPY(0xFC0E, List.of(VARUINT, VARUINT)),
TABLE_GROW(0xFC0F, List.of(VARUINT)),
TABLE_SIZE(0xFC10, List.of(VARUINT)),
TABLE_FILL(0xFC11, List.of(VARUINT));
TABLE_FILL(0xFC11, List.of(VARUINT)),
V128_LOAD(0xFD00, List.of(VARUINT, VARUINT)),
I8x16_SWIZZLE(0xFD0E),
V128_CONST(0xFD0C, List.of(VEC_VARUINT)),
I8x16_EXTRACT_LANE_S(0xFD15, List.of(VARUINT)),
I8x16_EQ(0xFD23),
V128_NOT(0xFD4D),
V128_BITSELECT(0xFD52),
I8x16_SHL(0xFD6B),
I8x16_ADD(0xFD6E),
I8x16_SUB(0xFD71),
F32x4_MUL(0xFDE6),
F32x4_ABS(0xFDE0),
F32x4_MIN(0xFDE8),
I32x4_TRUNC_SAT_F32X4_S(0xFDF8),
F32x4_CONVERT_I32x4_U(0xFDFB),
I8x16_ALL_TRUE(0xFD63),
;

private static final int OP_CODES_SIZE = 0xFF00;

Expand Down
75 changes: 75 additions & 0 deletions wasm/src/main/java/com/dylibso/chicory/wasm/types/Value.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,79 @@ public Value(ValueType type, long value) {
data = value;
}

@SuppressWarnings("checkstyle:modifiedcontrolvariable")
public static byte[] vecTo8(long[] values) {
var result = new byte[values.length * 8];
var valueIdx = 0;
for (int i = 0; i < result.length; i++) {
var v = values[valueIdx++];
result[i] = (byte) (v & 0xFFL);
result[++i] = (byte) ((v >> 8) & 0xFFL);
result[++i] = (byte) ((v >> 16) & 0xFFL);
result[++i] = (byte) ((v >> 24) & 0xFFL);
result[++i] = (byte) ((v >> 32) & 0xFFL);
result[++i] = (byte) ((v >> 40) & 0xFFL);
result[++i] = (byte) ((v >> 48) & 0xFFL);
result[++i] = (byte) ((v >> 56) & 0xFFL);
}
return result;
}

@SuppressWarnings("checkstyle:modifiedcontrolvariable")
public static long[] bytesToVec(byte[] bytes) {
var result = new long[bytes.length / 8];
var valueIdx = 0;
for (int i = 0; i < bytes.length; i++) {
result[valueIdx++] =
Byte.toUnsignedLong(bytes[i]) + (Byte.toUnsignedLong(bytes[++i]) << 8L)
| (Byte.toUnsignedLong(bytes[++i]) << 16L)
| (Byte.toUnsignedLong(bytes[++i]) << 24L)
| (Byte.toUnsignedLong(bytes[++i]) << 32L)
| (Byte.toUnsignedLong(bytes[++i]) << 40L)
| (Byte.toUnsignedLong(bytes[++i]) << 48L)
| (Byte.toUnsignedLong(bytes[++i]) << 56L);
}
return result;
}

@SuppressWarnings("checkstyle:modifiedcontrolvariable")
public static int[] vecTo16(long[] values) {
var result = new int[values.length * 4];
var valueIdx = 0;
for (int i = 0; i < result.length; i++) {
var v = values[valueIdx++];
result[i] = (int) (v & 0xFFFFL);
result[++i] = (int) ((v >> 16) & 0xFFFFL);
result[++i] = (int) ((v >> 32) & 0xFFFFL);
result[++i] = (int) ((v >> 48) & 0xFFFFL);
}
return result;
}

@SuppressWarnings("checkstyle:modifiedcontrolvariable")
public static long[] vecTo32(long[] values) {
var result = new long[values.length * 2];
var valueIdx = 0;
for (int i = 0; i < result.length; i++) {
var v = values[valueIdx++];
result[i] = (v & 0xFFFFFFFFL);
result[++i] = ((v >> 32) & 0xFFFFFFFFL);
}
return result;
}

@SuppressWarnings("checkstyle:modifiedcontrolvariable")
public static float[] vecToF32(long[] values) {
var result = new float[values.length * 2];
var valueIdx = 0;
for (int i = 0; i < result.length; i++) {
var v = values[valueIdx++];
result[i] = Float.intBitsToFloat((int) (v & 0xFFFFFFFFL));
result[++i] = Float.intBitsToFloat((int) ((v >> 32) & 0xFFFFFFFFL));
}
return result;
}

/**
* Create a zeroed value for the particular type.
*
Expand Down Expand Up @@ -135,6 +208,8 @@ public String toString() {
return longToFloat(data) + "@f32";
case F64:
return longToDouble(data) + "@f64";
case V128:
return data + "@v128";
case FuncRef:
return "func[" + (int) data + "]";
case ExternRef:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,15 @@ public boolean isReference() {
}
}

public boolean isVec() {
switch (this) {
case V128:
return true;
default:
return false;
}
}

/**
* @return {@code true} if the given type ID is a valid value type ID, or {@code false} if it is not
*/
Expand Down
7 changes: 7 additions & 0 deletions wasm/src/test/java/com/dylibso/chicory/wasm/ParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -221,4 +221,11 @@ public void shouldParseNamesSection() throws IOException {
assertEquals(".rodata", nameSec.nameOfData(0));
}
}

@Test
public void shouldParseSIMD() throws IOException {
try (InputStream is = getClass().getResourceAsStream("/wasm/simd_load.0.wasm")) {
Parser.parse(is);
}
}
}
53 changes: 53 additions & 0 deletions wasm/src/test/java/com/dylibso/chicory/wasm/types/ValueTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,57 @@ public void toStringContract() {
var i32FortyTwo = Value.i32(42);
assertNotNull(i32FortyTwo.toString());
}

@Test
public void shouldConvertToArrays() {
long x = 506097522914230528L;
var result = Value.vecTo8(new long[] {x});

assertEquals(8, result.length);
assertEquals(0, result[0]);
assertEquals(1, result[1]);
assertEquals(2, result[2]);
assertEquals(3, result[3]);
assertEquals(4, result[4]);
assertEquals(5, result[5]);
assertEquals(6, result[6]);
assertEquals(7, result[7]);
}

@Test
public void shouldConvertToArraysHL() {
long xLow = 506097522914230528L;
long xHigh = 1084818905618843912L;
var result = Value.vecTo8(new long[] {xLow, xHigh});

assertEquals(16, result.length);
assertEquals(0, result[0]);
assertEquals(1, result[1]);
assertEquals(2, result[2]);
assertEquals(3, result[3]);
assertEquals(4, result[4]);
assertEquals(5, result[5]);
assertEquals(6, result[6]);
assertEquals(7, result[7]);
assertEquals(8, result[8]);
assertEquals(9, result[9]);
assertEquals(10, result[10]);
assertEquals(11, result[11]);
assertEquals(12, result[12]);
assertEquals(13, result[13]);
assertEquals(14, result[14]);
assertEquals(15, result[15]);
}

@Test
public void shouldConvertBackFromBytes() {
var value = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
var result = Value.bytesToVec(value);
long xLow = 506097522914230528L;
long xHigh = 1084818905618843912L;

assertEquals(2, result.length);
assertEquals(xLow, result[0]);
assertEquals(xHigh, result[1]);
}
}
Binary file added wasm/src/test/resources/wasm/simd_load.0.wasm
Binary file not shown.

0 comments on commit 31deb74

Please sign in to comment.