authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-04-21 20:57:34-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-04-25 11:23:40-07:00
log76e340cbfa9cad9a69c5917cb0931861313b56a8
treef04cdba3a4d8632a31fc4aede30000ada2876361
parent92186b8c137d14917dc058f228be351f658c1e7e

wasm backend: implement new memcpy/memset and ptrtoint semantics


1 files changed, 47 insertions(+), 20 deletions(-)

src/arch/wasm/CodeGen.zig+47-20
...@@ -4148,9 +4148,7 @@ fn airSliceLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4148,9 +4148,7 @@ fn airSliceLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4148 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4148 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
41494149
4150 const operand = try func.resolveInst(ty_op.operand);4150 const operand = try func.resolveInst(ty_op.operand);
4151 const len = try func.load(operand, Type.usize, func.ptrSize());4151 func.finishAir(inst, try func.sliceLen(operand), &.{ty_op.operand});
4152 const result = try len.toLocal(func, Type.usize);
4153 func.finishAir(inst, result, &.{ty_op.operand});
4154}4152}
41554153
4156fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4154fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
...@@ -4208,9 +4206,17 @@ fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4208,9 +4206,17 @@ fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4208fn airSlicePtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4206fn airSlicePtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4209 const ty_op = func.air.instructions.items(.data)[inst].ty_op;4207 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
4210 const operand = try func.resolveInst(ty_op.operand);4208 const operand = try func.resolveInst(ty_op.operand);
4209 func.finishAir(inst, try func.slicePtr(operand), &.{ty_op.operand});
4210}
4211
4212fn slicePtr(func: *CodeGen, operand: WValue) InnerError!WValue {
4211 const ptr = try func.load(operand, Type.usize, 0);4213 const ptr = try func.load(operand, Type.usize, 0);
4212 const result = try ptr.toLocal(func, Type.usize);4214 return ptr.toLocal(func, Type.usize);
4213 func.finishAir(inst, result, &.{ty_op.operand});4215}
4216
4217fn sliceLen(func: *CodeGen, operand: WValue) InnerError!WValue {
4218 const len = try func.load(operand, Type.usize, func.ptrSize());
4219 return len.toLocal(func, Type.usize);
4214}4220}
42154221
4216fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4222fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
...@@ -4274,8 +4280,10 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4274,8 +4280,10 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4274fn airPtrToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4280fn airPtrToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4275 const un_op = func.air.instructions.items(.data)[inst].un_op;4281 const un_op = func.air.instructions.items(.data)[inst].un_op;
4276 const operand = try func.resolveInst(un_op);4282 const operand = try func.resolveInst(un_op);
42774283 const ptr_ty = func.air.typeOf(un_op);
4278 const result = switch (operand) {4284 const result = if (ptr_ty.isSlice())
4285 try func.slicePtr(operand)
4286 else switch (operand) {
4279 // for stack offset, return a pointer to this offset.4287 // for stack offset, return a pointer to this offset.
4280 .stack_offset => try func.buildPointerOffset(operand, 0, .new),4288 .stack_offset => try func.buildPointerOffset(operand, 0, .new),
4281 else => func.reuseOperand(un_op, operand),4289 else => func.reuseOperand(un_op, operand),
...@@ -4376,15 +4384,19 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -4376,15 +4384,19 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
4376}4384}
43774385
4378fn airMemset(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {4386fn airMemset(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4379 const pl_op = func.air.instructions.items(.data)[inst].pl_op;4387 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
4380 const bin_op = func.air.extraData(Air.Bin, pl_op.payload).data;
43814388
4382 const ptr = try func.resolveInst(pl_op.operand);4389 const ptr = try func.resolveInst(bin_op.lhs);
4383 const value = try func.resolveInst(bin_op.lhs);4390 const ptr_ty = func.air.typeOf(bin_op.lhs);
4384 const len = try func.resolveInst(bin_op.rhs);4391 const value = try func.resolveInst(bin_op.rhs);
4392 const len = switch (ptr_ty.ptrSize()) {
4393 .Slice => try func.sliceLen(ptr),
4394 .One => @as(WValue, .{ .imm64 = ptr_ty.childType().arrayLen() }),
4395 .C, .Many => unreachable,
4396 };
4385 try func.memset(ptr, len, value);4397 try func.memset(ptr, len, value);
43864398
4387 func.finishAir(inst, .none, &.{ pl_op.operand, bin_op.lhs, bin_op.rhs });4399 func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
4388}4400}
43894401
4390/// Sets a region of memory at `ptr` to the value of `value`4402/// Sets a region of memory at `ptr` to the value of `value`
...@@ -5155,15 +5167,30 @@ fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5155,15 +5167,30 @@ fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5155 func.finishAir(inst, result, &.{extra.field_ptr});5167 func.finishAir(inst, result, &.{extra.field_ptr});
5156}5168}
51575169
5170fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue {
5171 if (ptr_ty.isSlice()) {
5172 return func.slicePtr(ptr);
5173 } else {
5174 return ptr;
5175 }
5176}
5177
5158fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5178fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5159 const pl_op = func.air.instructions.items(.data)[inst].pl_op;5179 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
5160 const bin_op = func.air.extraData(Air.Bin, pl_op.payload).data;5180 const dst = try func.resolveInst(bin_op.lhs);
5161 const dst = try func.resolveInst(pl_op.operand);5181 const dst_ty = func.air.typeOf(bin_op.lhs);
5162 const src = try func.resolveInst(bin_op.lhs);5182 const src = try func.resolveInst(bin_op.rhs);
5163 const len = try func.resolveInst(bin_op.rhs);5183 const src_ty = func.air.typeOf(bin_op.rhs);
5164 try func.memcpy(dst, src, len);5184 const len = switch (dst_ty.ptrSize()) {
5185 .Slice => try func.sliceLen(dst),
5186 .One => @as(WValue, .{ .imm64 = dst_ty.childType().arrayLen() }),
5187 .C, .Many => unreachable,
5188 };
5189 const dst_ptr = try func.sliceOrArrayPtr(dst, dst_ty);
5190 const src_ptr = try func.sliceOrArrayPtr(src, src_ty);
5191 try func.memcpy(dst_ptr, src_ptr, len);
51655192
5166 func.finishAir(inst, .none, &.{ pl_op.operand, bin_op.lhs, bin_op.rhs });5193 func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
5167}5194}
51685195
5169fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5196fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {