| ... | ... | @@ -4148,9 +4148,7 @@ fn airSliceLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4148 | 4148 | const ty_op = func.air.instructions.items(.data)[inst].ty_op; |
| 4149 | 4149 | |
| 4150 | 4150 | const operand = try func.resolveInst(ty_op.operand); |
| 4151 | | const len = try func.load(operand, Type.usize, func.ptrSize()); |
| 4152 | | const result = try len.toLocal(func, Type.usize); |
| 4153 | | func.finishAir(inst, result, &.{ty_op.operand}); |
| 4151 | func.finishAir(inst, try func.sliceLen(operand), &.{ty_op.operand}); |
| 4154 | 4152 | } |
| 4155 | 4153 | |
| 4156 | 4154 | fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| ... | ... | @@ -4208,9 +4206,17 @@ fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4208 | 4206 | fn airSlicePtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4209 | 4207 | const ty_op = func.air.instructions.items(.data)[inst].ty_op; |
| 4210 | 4208 | const operand = try func.resolveInst(ty_op.operand); |
| 4209 | func.finishAir(inst, try func.slicePtr(operand), &.{ty_op.operand}); |
| 4210 | } |
| 4211 | |
| 4212 | fn slicePtr(func: *CodeGen, operand: WValue) InnerError!WValue { |
| 4211 | 4213 | const ptr = try func.load(operand, Type.usize, 0); |
| 4212 | | const result = try ptr.toLocal(func, Type.usize); |
| 4213 | | func.finishAir(inst, result, &.{ty_op.operand}); |
| 4214 | return ptr.toLocal(func, Type.usize); |
| 4215 | } |
| 4216 | |
| 4217 | fn 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 | } |
| 4215 | 4221 | |
| 4216 | 4222 | fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| ... | ... | @@ -4274,8 +4280,10 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4274 | 4280 | fn airPtrToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4275 | 4281 | const un_op = func.air.instructions.items(.data)[inst].un_op; |
| 4276 | 4282 | const operand = try func.resolveInst(un_op); |
| 4277 | | |
| 4278 | | const result = switch (operand) { |
| 4283 | const ptr_ty = func.air.typeOf(un_op); |
| 4284 | const result = if (ptr_ty.isSlice()) |
| 4285 | try func.slicePtr(operand) |
| 4286 | else switch (operand) { |
| 4279 | 4287 | // for stack offset, return a pointer to this offset. |
| 4280 | 4288 | .stack_offset => try func.buildPointerOffset(operand, 0, .new), |
| 4281 | 4289 | else => func.reuseOperand(un_op, operand), |
| ... | ... | @@ -4376,15 +4384,19 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 4376 | 4384 | } |
| 4377 | 4385 | |
| 4378 | 4386 | fn airMemset(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4379 | | const pl_op = func.air.instructions.items(.data)[inst].pl_op; |
| 4380 | | const bin_op = func.air.extraData(Air.Bin, pl_op.payload).data; |
| 4387 | const bin_op = func.air.instructions.items(.data)[inst].bin_op; |
| 4381 | 4388 | |
| 4382 | | const ptr = try func.resolveInst(pl_op.operand); |
| 4383 | | const value = try func.resolveInst(bin_op.lhs); |
| 4384 | | const len = try func.resolveInst(bin_op.rhs); |
| 4389 | const ptr = try func.resolveInst(bin_op.lhs); |
| 4390 | const ptr_ty = func.air.typeOf(bin_op.lhs); |
| 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 | 4397 | try func.memset(ptr, len, value); |
| 4386 | 4398 | |
| 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 | } |
| 4389 | 4401 | |
| 4390 | 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 | 5167 | func.finishAir(inst, result, &.{extra.field_ptr}); |
| 5156 | 5168 | } |
| 5157 | 5169 | |
| 5170 | fn 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 | |
| 5158 | 5178 | fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5159 | | const pl_op = func.air.instructions.items(.data)[inst].pl_op; |
| 5160 | | const bin_op = func.air.extraData(Air.Bin, pl_op.payload).data; |
| 5161 | | const dst = try func.resolveInst(pl_op.operand); |
| 5162 | | const src = try func.resolveInst(bin_op.lhs); |
| 5163 | | const len = try func.resolveInst(bin_op.rhs); |
| 5164 | | try func.memcpy(dst, src, len); |
| 5179 | const bin_op = func.air.instructions.items(.data)[inst].bin_op; |
| 5180 | const dst = try func.resolveInst(bin_op.lhs); |
| 5181 | const dst_ty = func.air.typeOf(bin_op.lhs); |
| 5182 | const src = try func.resolveInst(bin_op.rhs); |
| 5183 | const src_ty = func.air.typeOf(bin_op.rhs); |
| 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); |
| 5165 | 5192 | |
| 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 | } |
| 5168 | 5195 | |
| 5169 | 5196 | fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |