Skip to content

Commit

Permalink
SIMD spec tests (splat_0 and splat_1) succeed
Browse files Browse the repository at this point in the history
  • Loading branch information
jay-tux committed Oct 8, 2024
1 parent ce287be commit 4f4dc5e
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 89 deletions.
3 changes: 3 additions & 0 deletions src/Debug/debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,9 @@ void Debugger::dumpLocals(Module *m) const {
snprintf(_value_str, 255, R"("type":"F64","value":%.7f)",
v->value.f64);
break;
case V128:
snprintf(_value_str, 255, R"("type":"V128","value":"%016lx%016lx")",
v->value.simd.i64x2[0], v->value.simd.i64x2[1]);
default:
snprintf(_value_str, 255,
R"("type":"%02x","value":"%)" PRIx64 "\"",
Expand Down
14 changes: 10 additions & 4 deletions src/Utils/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@ uint64_t read_LEB_(uint8_t **pos, uint32_t maxbits, bool sign) {
FATAL("Unsigned LEB at byte %p overflow", (void *)startpos);
}
}

if (sign && (shift < maxbits) && (byte & 0x40u)) {
// Sign extend by highest bits set 1 except last shift bits
result |= UINT64_MAX << shift;
const auto old = result;
result |= (~0ul) << shift;
}
return result;
}
Expand Down Expand Up @@ -92,26 +94,30 @@ StackValue *readWasmArgs(Type function, uint8_t *data) {

switch (args[i].value_type) {
case I32: {
args[i].value.int32 = read_LEB_signed(&data, 32);
args[i].value.uint32 = read_LEB_signed(&data, 32);
break;
}
case F32: {
memcpy(&args[i].value.f32, data,
sizeof(float)); // todo read ieee 754
printf("Received F32 %f (%02x%02x%02x%02x)", args[i].value.f32, data[0], data[1], data[2], data[3]);
data += sizeof(float);
break;
}
case I64: {
args[i].value.int64 = read_LEB_signed(&data, 64);
args[i].value.uint64 = read_LEB_signed(&data, 64);
break;
}
case F64: {
memcpy(&args[i].value.f64, data, sizeof(double));
printf("Received F64 %lf (%02x%02x%02x%02x%02x%02x%02x%02x)",
args[i].value.f64, data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7]);
data += sizeof(double);
break;
}
case V128: {
memcpy(&args[i].value.simd, data, 16 * sizeof(decltype(args[i].value.simd)));
memcpy(&args[i].value.simd, data, sizeof(decltype(args[i].value.simd)));
data += sizeof(decltype(args[i].value.simd));
break;
}
Expand Down
Binary file modified tests/latch/latch-0.3.0.tgz
Binary file not shown.
8 changes: 4 additions & 4 deletions tests/latch/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

107 changes: 59 additions & 48 deletions tests/latch/src/util/spec.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,54 @@ interface Cursor {
value: number;
}

// 8b -> 16 elems; pad 2
// 16b -> 8 elems, pad 4
// 32b -> 4 elems, pad 8
// 64b -> 2 elems, pad 16
// -> 128 / b elems; pad b / 4
function float32HexStr(x: number): string {
const ab = new ArrayBuffer(4);
const fb = new Float32Array(ab);
fb[0] = x;
const ui8 = new Uint8Array(ab);
let res = '';
for (let i = 3; i >= 0; i--) {
res += ui8[i].toString(16).padStart(2, '0');
}
return res;
}

function float64HexStr(x: number): string {
const ab = new ArrayBuffer(8);
const fb = new Float64Array(ab);
fb[0] = x;
const ui8 = new Uint8Array(ab);
let res = '';
for (let i = 7; i >= 0; i--) {
res += ui8[i].toString(16).padStart(2, '0');
}
return res;
}

function parseWasmFloat32(str: string) {
const strBuf = str.replace(/_/gi, ''); // remove those damned underscores

const flt = parseHexFloat(strBuf);
const res = float32HexStr(flt);
return res;
}

function parseWasmFloat64(str: string): string|undefined {
const strBuf = str.replace(/_/gi, ''); // remove those damned underscores

// just use hexFloat - it works for 64-bit floats
const flt = parseHexFloat(strBuf);
const res = float64HexStr(flt);
return res;
}

function parseV128(type: string, args: string[]): string | undefined {
const int_lambda = (bit_width: number, mask: bigint): string|undefined => {
const elems = 128 / bit_width;
const pad_len = bit_width / 4;

if(args.length !== elems) return undefined;
return args
const res = args
.map(str => str.replace(/_/gi, '')) // WASM allows _ in numbers, TS doesn't like those
.map(str => {
let start_idx = 0;
Expand All @@ -29,46 +64,24 @@ function parseV128(type: string, args: string[]): string | undefined {
.map(num => num & mask) // ensure correct bit width
.map(num => num.toString(16).padStart(pad_len, '0')) // convert to hex
.reduce((acc, val) => acc + val, ''); // concat
return res;
};

const float_lambda = (bit_width: number, mask: bigint, flt2bigint: (flt: number, ab: ArrayBuffer) => bigint): string|undefined => {
const elems = 128 / bit_width;
const pad_len = bit_width / 4;

if(args.length !== elems) return undefined;
return args
.map(str => str.replace(/_/gi, '')) // WASM allows _ in numbers, TS doesn't like those
.map(str => parseFloat(str)) // parse to float ~ might not accept all floats
.map(flt => {
const buf = new ArrayBuffer(bit_width / 8);
return flt2bigint(flt, buf) & mask;
})
.map(num => num.toString(16).padStart(pad_len, '0')) // convert to hex
.reduce((acc, str) => acc + str, ''); // concat
};

const flt32_lambda = (flt: number, ab: ArrayBuffer) => {
const fltBuffer = new Float32Array(ab);
fltBuffer[0] = flt;
const intBuffer = new Int32Array(ab);
return BigInt(intBuffer[0]);
};

const flt64_lambda = (flt: number, ab: ArrayBuffer) => {
const fltBuffer = new Float64Array(ab);
fltBuffer[0] = flt;
const intBuffer = new BigInt64Array(ab);
return intBuffer[0];
};
const float_lambda = (elem_count: number, parser: (s: string) => string|undefined): string|undefined => {
if(args.length !== elem_count) return undefined;
const parsed = args.map(str => parser(str));
if(parsed.some(str => str === undefined)) return undefined;
return parsed.reduce((acc, val) => acc + (val as string), '');
}

switch(type) {
case 'i8x16': return int_lambda(8, 0x00000000000000ffn);
case 'i16x8': return int_lambda(16, 0x000000000000ffffn);
case 'i32x4': return int_lambda(32, 0x00000000ffffffffn);
case 'i64x2': return int_lambda(64, 0xffffffffffffffffn);

case 'f32x4': return float_lambda(32, 0x00000000ffffffffn, flt32_lambda);
case 'f64x2': return float_lambda(64, 0xffffffffffffffffn, flt64_lambda);
case 'f32x4': return float_lambda(4, parseWasmFloat32);
case 'f64x2': return float_lambda(2, parseWasmFloat64);

default: return undefined;
}
Expand Down Expand Up @@ -118,11 +131,10 @@ export function parseArguments(input: string, index: Cursor): WASM.Value[] {

delta = consume(input, cursor, /^[^.)]*/d);
const type: WASM.Type = WASM.typing.get(input.slice(cursor + delta - 3, cursor + delta)) ?? WASM.Type.i64;
// console.log(`arg #${args.length}.type: ${input.slice(cursor + delta - 3, cursor + delta)}`);

cursor += delta + consume(input, cursor + delta, /^[^)]*const /d);
delta = consume(input, cursor, /^[^)]*/d);
let maybe: number | undefined;
let maybe: number | bigint | undefined;
if (type === WASM.Type.f32 || type === WASM.Type.f64) {
maybe = parseHexFloat(input.slice(cursor, cursor + delta));
} else {
Expand Down Expand Up @@ -179,6 +191,10 @@ function parseHexFloat(input: string): number {
return Infinity;
}

if (input.includes('e')) {
return parseFloat(input);
}

const radix: number = input.includes('0x') ? 16 : 10;
let base: string = input, mantissa, exponent = 0;

Expand All @@ -200,16 +216,11 @@ function parseHexFloat(input: string): number {
return mantissa * Math.pow(2, exponent);
}

function parseInteger(hex: string, bytes: number = 4): number {
if (!hex.includes('0x')) {
return parseInt(hex);
}
const mask = parseInt('0x80' + '00'.repeat(bytes - 1), 16);
let integer = parseInt(hex, 16);
if (integer >= mask) {
integer = integer - mask * 2;
function parseInteger(hex: string, bytes: number = 4): bigint {
if(hex.startsWith('-')) {
return BigInt(-1) * BigInt(hex.slice(1));
}
return integer;
return BigInt(hex);
}

export function find(regex: RegExp, input: string) {
Expand Down
35 changes: 2 additions & 33 deletions tutorials/wat/main/simd.wat
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,8 @@
(memory 1)

(func $run (type $void->void)
(v128.store (i32.const 0) (v128.const i16x8 -1 2 -3 4 -5 6 -7 8))

(v128.load (i32.const 0))
i16x8.extract_lane_s 0
call $print.int

(v128.load (i32.const 0))
i16x8.extract_lane_s 1
call $print.int

(v128.load (i32.const 0))
i16x8.extract_lane_s 2
call $print.int

(v128.load (i32.const 0))
i16x8.extract_lane_s 3
call $print.int

(v128.load (i32.const 0))
i16x8.extract_lane_s 4
call $print.int

(v128.load (i32.const 0))
i16x8.extract_lane_s 5
call $print.int

(v128.load (i32.const 0))
i16x8.extract_lane_s 6
call $print.int

(v128.load (i32.const 0))
i16x8.extract_lane_s 7
call $print.int
(i64x2.splat (i64.const -9223372036854775808))
drop
)

(export "main" (func $run))
Expand Down

0 comments on commit 4f4dc5e

Please sign in to comment.