aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-01-18 01:25:48 +0100
committerGitHub <noreply@github.com>2022-01-18 01:25:48 +0100
commite69cb9105a716dfd4a8cc2684417545b2438f606 (patch)
treed80540e1ff8f325f753ee3537daac3d8cbf0f975 /src
parentf4e051e35d8019c9a8d99ccae8f2e9d8f032629a (diff)
parent3145fa97c21704d8822db928e5f988f22497b1b8 (diff)
downloadzig-e69cb9105a716dfd4a8cc2684417545b2438f606.tar.gz
zig-e69cb9105a716dfd4a8cc2684417545b2438f606.zip
Merge pull request #10616 from ziglang/stage2-x86_64-array-to-slice
stage2: implement airArrayToSlice for x86_64
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86_64/CodeGen.zig33
1 files changed, 27 insertions, 6 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig
index 8f7f4746ec..2cf585fe4e 100644
--- a/src/arch/x86_64/CodeGen.zig
+++ b/src/arch/x86_64/CodeGen.zig
@@ -1659,6 +1659,18 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
},
}
},
+ .register => |src_reg| {
+ const abi_size = value_ty.abiSize(self.target.*);
+ _ = try self.addInst(.{
+ .tag = .mov,
+ .ops = (Mir.Ops{
+ .reg1 = reg.to64(),
+ .reg2 = registerAlias(src_reg, @intCast(u32, abi_size)),
+ .flags = 0b10,
+ }).encode(),
+ .data = .{ .imm = 0 },
+ });
+ },
else => |other| {
return self.fail("TODO implement set pointee with {}", .{other});
},
@@ -1822,7 +1834,7 @@ fn genBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs:
const dst_ty = self.air.typeOfIndex(inst);
const air_tags = self.air.instructions.items(.tag);
switch (air_tags[inst]) {
- .add, .addwrap => try self.genBinMathOpMir(.add, dst_ty, .unsigned, dst_mcv, src_mcv),
+ .add, .addwrap, .ptr_add => try self.genBinMathOpMir(.add, dst_ty, .unsigned, dst_mcv, src_mcv),
.bool_or, .bit_or => try self.genBinMathOpMir(.@"or", dst_ty, .unsigned, dst_mcv, src_mcv),
.bool_and, .bit_and => try self.genBinMathOpMir(.@"and", dst_ty, .unsigned, dst_mcv, src_mcv),
.sub, .subwrap => try self.genBinMathOpMir(.sub, dst_ty, .unsigned, dst_mcv, src_mcv),
@@ -3125,7 +3137,6 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void {
fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
switch (mcv) {
.dead => unreachable,
- .ptr_stack_offset => unreachable,
.ptr_embedded_in_code => unreachable,
.unreach, .none => return, // Nothing to do.
.undef => {
@@ -3241,6 +3252,10 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
}
return self.fail("TODO implement memcpy for setting stack from {}", .{mcv});
},
+ .ptr_stack_offset => {
+ const reg = try self.copyToTmpRegister(ty, mcv);
+ return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
+ },
.stack_offset => |off| {
if (stack_offset == off) {
// Copy stack variable to itself; nothing to do.
@@ -3618,10 +3633,16 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const result: MCValue = if (self.liveness.isUnused(inst))
- .dead
- else
- return self.fail("TODO implement airArrayToSlice for {}", .{self.target.cpu.arch});
+ const ptr_ty = self.air.typeOf(ty_op.operand);
+ const ptr = try self.resolveInst(ty_op.operand);
+ const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {
+ const stack_offset = try self.allocMem(inst, 16, 16);
+ const array_ty = ptr_ty.childType();
+ const array_len = array_ty.arrayLenIncludingSentinel();
+ try self.genSetStack(Type.initTag(.usize), stack_offset + 8, ptr);
+ try self.genSetStack(Type.initTag(.u64), stack_offset + 16, .{ .immediate = array_len });
+ break :blk .{ .stack_offset = stack_offset };
+ };
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}