authorgravatar for 19855629+SuperAuguste@users.noreply.github.comAuguste Rame <19855629+SuperAuguste@users.noreply.github.com> 2023-04-07 20:35:15-04:00
committergravatar for 19855629+SuperAuguste@users.noreply.github.comAuguste Rame <19855629+SuperAuguste@users.noreply.github.com> 2023-04-07 20:35:15-04:00
log1e310d335078c441c8b37bc220715aab938538e0
tree7d131f4563f1fe2f677caee745799fd69e986fd3
parentd5511b35a9a2db91643405ec255ced6dce208387
signaturelock-open Commit is signed but in an unrecognized format.

Finish shuffle, fix arrayElemVal for vectors


2 files changed, 66 insertions(+), 18 deletions(-)

src/arch/wasm/CodeGen.zig+63-17
......@@ -4518,11 +4518,27 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
45184518 const elem_ty = array_ty.childType();
45194519 const elem_size = elem_ty.abiSize(func.target);
45204520
4521 try func.lowerToStack(array);
4522 try func.emitWValue(index);
4523 try func.addImm32(@bitCast(i32, @intCast(u32, elem_size)));
4524 try func.addTag(.i32_mul);
4525 try func.addTag(.i32_add);
4521 if (isByRef(array_ty, func.target)) {
4522 try func.lowerToStack(array);
4523 try func.emitWValue(index);
4524 try func.addImm32(@bitCast(i32, @intCast(u32, elem_size)));
4525 try func.addTag(.i32_mul);
4526 try func.addTag(.i32_add);
4527 } else {
4528 std.debug.assert(array_ty.zigTypeTag() == .Vector);
4529
4530 // TODO: Check if index is constant; if so, use a lane extract
4531
4532 var stack_vec = try func.allocStack(array_ty);
4533 try func.store(stack_vec, array, array_ty, 0);
4534
4535 // Is a non-unrolled vector (v128)
4536 try func.lowerToStack(stack_vec);
4537 try func.emitWValue(index);
4538 try func.addImm32(@bitCast(i32, @intCast(u32, elem_size)));
4539 try func.addTag(.i32_mul);
4540 try func.addTag(.i32_add);
4541 }
45264542
45274543 const elem_result = val: {
45284544 var result = try func.allocLocal(Type.usize);
......@@ -4687,23 +4703,53 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
46874703 }
46884704
46894705 const module = func.bin_file.base.options.module.?;
4690 const result = try func.allocStack(inst_ty);
4706 // TODO: One of them could be by ref; handle in loop
4707 if (isByRef(func.air.typeOf(extra.a), func.target) or isByRef(inst_ty, func.target)) {
4708 const result = try func.allocStack(inst_ty);
46914709
4692 for (0..mask_len) |index| {
4693 var buf: Value.ElemValueBuffer = undefined;
4694 const value = mask.elemValueBuffer(module, index, &buf).toSignedInt(func.target);
4710 for (0..mask_len) |index| {
4711 var buf: Value.ElemValueBuffer = undefined;
4712 const value = mask.elemValueBuffer(module, index, &buf).toSignedInt(func.target);
46954713
4696 try func.emitWValue(result);
4714 try func.emitWValue(result);
46974715
4698 const loaded = if (value >= 0)
4699 try func.load(a, child_ty, @intCast(u32, @intCast(i64, elem_size) * value))
4700 else
4701 try func.load(b, child_ty, @intCast(u32, @intCast(i64, elem_size) * ~value));
4716 const loaded = if (value >= 0)
4717 try func.load(a, child_ty, @intCast(u32, @intCast(i64, elem_size) * value))
4718 else
4719 try func.load(b, child_ty, @intCast(u32, @intCast(i64, elem_size) * ~value));
47024720
4703 try func.store(.stack, loaded, child_ty, result.stack_offset.value + @intCast(u32, elem_size) * @intCast(u32, index));
4704 }
4721 try func.store(.stack, loaded, child_ty, result.stack_offset.value + @intCast(u32, elem_size) * @intCast(u32, index));
4722 }
4723
4724 return func.finishAir(inst, result, &.{ extra.a, extra.b });
4725 } else {
4726 var operands = [_]u32{
4727 std.wasm.simdOpcode(.i8x16_shuffle),
4728 } ++ [1]u32{undefined} ** 4;
4729
4730 var lanes = std.mem.asBytes(operands[1..]);
4731 for (0..mask_len) |index| {
4732 var buf: Value.ElemValueBuffer = undefined;
4733 const mask_elem = mask.elemValueBuffer(module, index, &buf).toSignedInt(func.target);
4734 const base_index = if (mask_elem >= 0)
4735 @intCast(u8, @intCast(i64, elem_size) * mask_elem)
4736 else
4737 16 + @intCast(u8, @intCast(i64, elem_size) * ~mask_elem);
4738
4739 for (0..elem_size) |byte_offset| {
4740 lanes[index * elem_size + byte_offset] = base_index + @intCast(u8, byte_offset);
4741 }
4742 }
4743
4744 try func.emitWValue(a);
4745 try func.emitWValue(b);
4746
4747 const extra_index = @intCast(u32, func.mir_extra.items.len);
4748 try func.mir_extra.appendSlice(func.gpa, &operands);
4749 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
47054750
4706 return func.finishAir(inst, result, &.{ extra.a, extra.b });
4751 return func.finishAir(inst, try WValue.toLocal(.stack, func, inst_ty), &.{ extra.a, extra.b });
4752 }
47074753}
47084754
47094755fn airReduce(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
src/arch/wasm/Emit.zig+3-1
......@@ -486,7 +486,9 @@ fn emitSimd(emit: *Emit, inst: Mir.Inst.Index) !void {
486486 const mem_arg = emit.mir.extraData(Mir.MemArg, extra_index + 1).data;
487487 try encodeMemArg(mem_arg, writer);
488488 },
489 .v128_const => {
489 .v128_const,
490 .i8x16_shuffle,
491 => {
490492 const simd_value = emit.mir.extra[extra_index + 1 ..][0..4];
491493 try writer.writeAll(std.mem.asBytes(simd_value));
492494 },