authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-19 09:43:07-04:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-21 08:49:54+01:00
log6c453dd806d9a0207b1f1e64adfc38eca0c38f16
tree046cb0b9ec92075e0125e249a3ff95a7627f9996
parent958c8e1ce97671bcd7dc5b2dd9ddc1b87d0d1196

x86_64: implement some slice ops


1 files changed, 54 insertions(+), 14 deletions(-)

src/arch/x86_64/CodeGen.zig+54-14
...@@ -2089,9 +2089,12 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2089,9 +2089,12 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
2089 defer self.register_manager.unlockReg(src_lock);2089 defer self.register_manager.unlockReg(src_lock);
20902090
2091 const dst_ty = self.air.typeOfIndex(inst);2091 const dst_ty = self.air.typeOfIndex(inst);
2092 const dst_reg = try self.register_manager.allocReg(inst, gp);2092 const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
2093 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);2093 src_reg
2094 defer self.register_manager.unlockReg(dst_lock);2094 else
2095 try self.register_manager.allocReg(inst, gp);
2096 const dst_lock = self.register_manager.lockReg(dst_reg);
2097 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
20952098
2096 const eu_ty = src_ty.childType();2099 const eu_ty = src_ty.childType();
2097 const pl_ty = eu_ty.errorUnionPayload();2100 const pl_ty = eu_ty.errorUnionPayload();
...@@ -2133,9 +2136,12 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -2133,9 +2136,12 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
2133 if (self.liveness.isUnused(inst)) break :result .dead;2136 if (self.liveness.isUnused(inst)) break :result .dead;
21342137
2135 const dst_ty = self.air.typeOfIndex(inst);2138 const dst_ty = self.air.typeOfIndex(inst);
2136 const dst_reg = try self.register_manager.allocReg(inst, gp);2139 const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
2137 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);2140 src_reg
2138 defer self.register_manager.unlockReg(dst_lock);2141 else
2142 try self.register_manager.allocReg(inst, gp);
2143 const dst_lock = self.register_manager.lockReg(dst_reg);
2144 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
21392145
2140 const pl_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*));2146 const pl_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*));
2141 const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*));2147 const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*));
...@@ -2309,19 +2315,53 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {...@@ -2309,19 +2315,53 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
23092315
2310fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {2316fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
2311 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2317 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2312 const result: MCValue = if (self.liveness.isUnused(inst))2318 const result: MCValue = result: {
2313 .dead2319 if (self.liveness.isUnused(inst)) break :result .dead;
2314 else2320
2315 return self.fail("TODO implement ptr_slice_len_ptr for {}", .{self.target.cpu.arch});2321 const src_ty = self.air.typeOf(ty_op.operand);
2322 const src_mcv = try self.resolveInst(ty_op.operand);
2323 const src_reg = switch (src_mcv) {
2324 .register => |reg| reg,
2325 else => try self.copyToTmpRegister(src_ty, src_mcv),
2326 };
2327 const src_lock = self.register_manager.lockRegAssumeUnused(src_reg);
2328 defer self.register_manager.unlockReg(src_lock);
2329
2330 const dst_ty = self.air.typeOfIndex(inst);
2331 const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
2332 src_reg
2333 else
2334 try self.register_manager.allocReg(inst, gp);
2335 const dst_lock = self.register_manager.lockReg(dst_reg);
2336 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
2337
2338 const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*));
2339 try self.asmRegisterMemory(
2340 .lea,
2341 registerAlias(dst_reg, dst_abi_size),
2342 Memory.sib(.qword, .{
2343 .base = src_reg,
2344 .disp = @divExact(self.target.cpu.arch.ptrBitWidth(), 8),
2345 }),
2346 );
2347 break :result .{ .register = dst_reg };
2348 };
2316 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });2349 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
2317}2350}
23182351
2319fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {2352fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
2320 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2353 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2321 const result: MCValue = if (self.liveness.isUnused(inst))2354 const result: MCValue = result: {
2322 .dead2355 if (self.liveness.isUnused(inst)) break :result .dead;
2323 else2356
2324 return self.fail("TODO implement ptr_slice_ptr_ptr for {}", .{self.target.cpu.arch});2357 const dst_ty = self.air.typeOfIndex(inst);
2358 const opt_mcv = try self.resolveInst(ty_op.operand);
2359
2360 break :result if (self.reuseOperand(inst, ty_op.operand, 0, opt_mcv))
2361 opt_mcv
2362 else
2363 try self.copyToRegisterWithInstTracking(inst, dst_ty, opt_mcv);
2364 };
2325 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });2365 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
2326}2366}
23272367