Skip to content

Commit

Permalink
[v3i/simd]: Implement load_lane instructions (#130 from haoyu-zc/v3i-…
Browse files Browse the repository at this point in the history
…loadlane-pr)
  • Loading branch information
titzer authored Nov 6, 2023
2 parents d20040e + bda1720 commit 34ab694
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/engine/Value.v3
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ component Values {
def v_w_8(v: Value) -> u8 { return u8.view(Value.I64.!(v).val); }
def v_w_16(v: Value) -> u16 { return u16.view(Value.I64.!(v).val); }
def v_w_32(v: Value) -> u32 { return u32.view(Value.I64.!(v).val); }
def v_w_64(v: Value) -> u64 { return u64.view(Value.I64.!(v).val); }
def v_v128(v: Value) -> (u64, u64) {
var b = Value.V128.!(v);
return (b.low, b.high);
Expand Down
23 changes: 23 additions & 0 deletions src/engine/v3/V3Interpreter.v3
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,10 @@ component V3Interpreter {
if (t != TrapReason.NONE) trap(t);
}
V128_LOAD => doLoad(16, DataReaders.read_range_u128, Value.V128);
V128_LOAD_64_LANE => doLoadLane(8, DataReaders.read_range_u64, Value.I64, Values.v_w_64);
V128_LOAD_32_LANE => doLoadLane(4, DataReaders.read_range_u32, Value.I32, Values.v_u);
V128_LOAD_16_LANE => doLoadLane(2, DataReaders.read_range_u32_u16, Value.I32, Values.v_u_16);
V128_LOAD_8_LANE => doLoadLane(1, DataReaders.read_range_u32_u8, Value.I32, Values.v_u_8);
V128_STORE => doStore(16, DataWriters.write_range_u128, Values.v_v128);
V128_CONST => {
var low = codeptr.read_u64();
Expand Down Expand Up @@ -1048,6 +1052,25 @@ component V3Interpreter {
if (t.reason != TrapReason.NONE) trap(t.reason);
else push(box(read(t.result)));
}
def doLoadLane<T, R>(size: byte, read: Range<byte> -> T, box: T -> Value, unbox: Value -> R) {
var v = Values.v_v128(pop());
doLoad(size, read, box);
var val = u64.!(unbox(pop()));
var idx = codeptr.read1();
var low = v.0, high = v.1;
// Calculate number of lanes in low/high : (bytes(v128) / size) / 2
def half_lanes = (16 / size) >> 1;
if (idx < half_lanes) { // Update a lane in low
var shift = byte.view(idx * size * 8);
val <<= shift;
low |= val;
} else { // Update a lane in high
var shift = byte.view((idx - half_lanes) * size * 8);
val <<= shift;
high |= val;
}
push(Value.V128(low, high));
}
def doStore<T>(size: byte, write: (Range<byte>, T) -> void, unbox: Value -> T) {
var memarg = codeptr.read_MemArg();
var memory = frame.func.instance.memories[memarg.memory_index];
Expand Down

0 comments on commit 34ab694

Please sign in to comment.