aboutsummaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorLuuk de Gram <luuk@degram.dev>2023-05-21 15:16:48 +0200
committerLuuk de Gram <luuk@degram.dev>2023-05-31 18:04:31 +0200
commit00dedabc41322bc2b4978ddc39ee17b72193f194 (patch)
tree7efb90f93aca22dd4b1a7dbdd1f0c1e3e0b6c85c /src/arch
parentcd1417dbdf098634641e87dba4c3be2806d76250 (diff)
downloadzig-00dedabc41322bc2b4978ddc39ee17b72193f194.tar.gz
zig-00dedabc41322bc2b4978ddc39ee17b72193f194.zip
wasm: `memcpy` support elem abi-size > 1
Previously it was incorrectly assumed that all memcopy's generated by the `memcpy` AIR instruction had an element size of 1 byte. However, this would result in miscompilations for pointer's to arrays where the element size of the array was larger than 1 byte. We now corectly calculate this size.
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/wasm/CodeGen.zig16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig
index bdbe9640c2..7872d89e9b 100644
--- a/src/arch/wasm/CodeGen.zig
+++ b/src/arch/wasm/CodeGen.zig
@@ -5295,11 +5295,23 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const dst = try func.resolveInst(bin_op.lhs);
const dst_ty = func.air.typeOf(bin_op.lhs);
+ const ptr_elem_ty = dst_ty.childType();
const src = try func.resolveInst(bin_op.rhs);
const src_ty = func.air.typeOf(bin_op.rhs);
const len = switch (dst_ty.ptrSize()) {
- .Slice => try func.sliceLen(dst),
- .One => @as(WValue, .{ .imm32 = @intCast(u32, dst_ty.childType().arrayLen()) }),
+ .Slice => blk: {
+ const slice_len = try func.sliceLen(dst);
+ if (ptr_elem_ty.abiSize(func.target) != 1) {
+ try func.emitWValue(slice_len);
+ try func.emitWValue(.{ .imm32 = @intCast(u32, ptr_elem_ty.abiSize(func.target)) });
+ try func.addTag(.i32_mul);
+ try func.addLabel(.local_set, slice_len.local.value);
+ }
+ break :blk slice_len;
+ },
+ .One => @as(WValue, .{
+ .imm32 = @intCast(u32, ptr_elem_ty.arrayLen() * ptr_elem_ty.childType().abiSize(func.target)),
+ }),
.C, .Many => unreachable,
};
const dst_ptr = try func.sliceOrArrayPtr(dst, dst_ty);