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 {
20892089 defer self.register_manager.unlockReg(src_lock);
20902090
20912091 const dst_ty = self.air.typeOfIndex(inst);
2092 const dst_reg = try self.register_manager.allocReg(inst, gp);
2093 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
2094 defer self.register_manager.unlockReg(dst_lock);
2092 const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
2093 src_reg
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
20962099 const eu_ty = src_ty.childType();
20972100 const pl_ty = eu_ty.errorUnionPayload();
......@@ -2133,9 +2136,12 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
21332136 if (self.liveness.isUnused(inst)) break :result .dead;
21342137
21352138 const dst_ty = self.air.typeOfIndex(inst);
2136 const dst_reg = try self.register_manager.allocReg(inst, gp);
2137 const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg);
2138 defer self.register_manager.unlockReg(dst_lock);
2139 const dst_reg = if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
2140 src_reg
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
21402146 const pl_off = @intCast(i32, errUnionErrorOffset(pl_ty, self.target.*));
21412147 const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*));
......@@ -2309,19 +2315,53 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
23092315
23102316fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
23112317 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2312 const result: MCValue = if (self.liveness.isUnused(inst))
2313 .dead
2314 else
2315 return self.fail("TODO implement ptr_slice_len_ptr for {}", .{self.target.cpu.arch});
2318 const result: MCValue = result: {
2319 if (self.liveness.isUnused(inst)) break :result .dead;
2320
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 };
23162349 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
23172350}
23182351
23192352fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
23202353 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2321 const result: MCValue = if (self.liveness.isUnused(inst))
2322 .dead
2323 else
2324 return self.fail("TODO implement ptr_slice_ptr_ptr for {}", .{self.target.cpu.arch});
2354 const result: MCValue = result: {
2355 if (self.liveness.isUnused(inst)) break :result .dead;
2356
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 };
23252365 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
23262366}
23272367