aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjoachimschmidt557 <joachim.schmidt557@outlook.com>2022-02-27 21:38:09 +0100
committerjoachimschmidt557 <joachim.schmidt557@outlook.com>2022-02-27 21:38:56 +0100
commit1bf8da19e1b58159b27033d415b7289cf455b870 (patch)
tree8cff944a8b7632f4883015205e6e04568bd1cef6 /src
parent91fbcf70935118c0667031ba7ae76fa0e75d80cc (diff)
downloadzig-1bf8da19e1b58159b27033d415b7289cf455b870.tar.gz
zig-1bf8da19e1b58159b27033d415b7289cf455b870.zip
stage2 ARM: implement slice and array_to_slice
Diffstat (limited to 'src')
-rw-r--r--src/arch/arm/CodeGen.zig33
1 files changed, 28 insertions, 5 deletions
diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig
index 51b2e7f1a8..6cd4a1fd9f 100644
--- a/src/arch/arm/CodeGen.zig
+++ b/src/arch/arm/CodeGen.zig
@@ -433,7 +433,9 @@ fn gen(self: *Self) !void {
});
// exitlude jumps
- if (self.exitlude_jump_relocs.items.len == 1) {
+ const only_one_exitlude_jump = self.exitlude_jump_relocs.items.len == 1 and
+ self.exitlude_jump_relocs.items[0] == self.mir_instructions.len - 1;
+ if (only_one_exitlude_jump) {
// There is only one relocation. Hence,
// this relocation must be at the end of
// the code. Therefore, we can just delete
@@ -1066,7 +1068,17 @@ fn airMax(self: *Self, inst: Air.Inst.Index) !void {
fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
- const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice for {}", .{self.target.cpu.arch});
+ const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
+ const ptr = try self.resolveInst(bin_op.lhs);
+ const ptr_ty = self.air.typeOf(bin_op.lhs);
+ const len = try self.resolveInst(bin_op.rhs);
+ const len_ty = self.air.typeOf(bin_op.rhs);
+
+ const stack_offset = try self.allocMem(inst, 8, 8);
+ try self.genSetStack(ptr_ty, stack_offset + 4, ptr);
+ try self.genSetStack(len_ty, stack_offset, len);
+ break :result MCValue{ .stack_offset = stack_offset };
+ };
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
@@ -3855,9 +3867,17 @@ 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 result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
+ const ptr_ty = self.air.typeOf(ty_op.operand);
+ const ptr = try self.resolveInst(ty_op.operand);
+ const array_ty = ptr_ty.childType();
+ const array_len = @intCast(u32, array_ty.arrayLenIncludingSentinel());
+
+ const stack_offset = try self.allocMem(inst, 8, 8);
+ try self.genSetStack(ptr_ty, stack_offset + 4, ptr);
+ try self.genSetStack(Type.initTag(.usize), stack_offset, .{ .immediate = array_len });
+ break :result MCValue{ .stack_offset = stack_offset };
+ };
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
@@ -4078,6 +4098,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
}
switch (typed_value.ty.zigTypeTag()) {
+ .Array => {
+ return self.lowerUnnamedConst(typed_value);
+ },
.Pointer => switch (typed_value.ty.ptrSize()) {
.Slice => {
return self.lowerUnnamedConst(typed_value);