authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-02-27 21:38:09+01:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-02-27 21:38:56+01:00
log1bf8da19e1b58159b27033d415b7289cf455b870
tree8cff944a8b7632f4883015205e6e04568bd1cef6
parent91fbcf70935118c0667031ba7ae76fa0e75d80cc
signaturelock-open Commit is signed but in an unrecognized format.

stage2 ARM: implement slice and array_to_slice


6 files changed, 28 insertions(+), 14 deletions(-)

src/arch/arm/CodeGen.zig+28-5
...@@ -433,7 +433,9 @@ fn gen(self: *Self) !void {...@@ -433,7 +433,9 @@ fn gen(self: *Self) !void {
433 });433 });
434434
435 // exitlude jumps435 // exitlude jumps
436 if (self.exitlude_jump_relocs.items.len == 1) {436 const only_one_exitlude_jump = self.exitlude_jump_relocs.items.len == 1 and
437 self.exitlude_jump_relocs.items[0] == self.mir_instructions.len - 1;
438 if (only_one_exitlude_jump) {
437 // There is only one relocation. Hence,439 // There is only one relocation. Hence,
438 // this relocation must be at the end of440 // this relocation must be at the end of
439 // the code. Therefore, we can just delete441 // the code. Therefore, we can just delete
...@@ -1066,7 +1068,17 @@ fn airMax(self: *Self, inst: Air.Inst.Index) !void {...@@ -1066,7 +1068,17 @@ fn airMax(self: *Self, inst: Air.Inst.Index) !void {
1066fn airSlice(self: *Self, inst: Air.Inst.Index) !void {1068fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
1067 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;1069 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
1068 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;1070 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
1069 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice for {}", .{self.target.cpu.arch});1071 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1072 const ptr = try self.resolveInst(bin_op.lhs);
1073 const ptr_ty = self.air.typeOf(bin_op.lhs);
1074 const len = try self.resolveInst(bin_op.rhs);
1075 const len_ty = self.air.typeOf(bin_op.rhs);
1076
1077 const stack_offset = try self.allocMem(inst, 8, 8);
1078 try self.genSetStack(ptr_ty, stack_offset + 4, ptr);
1079 try self.genSetStack(len_ty, stack_offset, len);
1080 break :result MCValue{ .stack_offset = stack_offset };
1081 };
1070 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });1082 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1071}1083}
10721084
...@@ -3855,9 +3867,17 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -3855,9 +3867,17 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
38553867
3856fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {3868fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
3857 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3869 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3858 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airArrayToSlice for {}", .{3870 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3859 self.target.cpu.arch,3871 const ptr_ty = self.air.typeOf(ty_op.operand);
3860 });3872 const ptr = try self.resolveInst(ty_op.operand);
3873 const array_ty = ptr_ty.childType();
3874 const array_len = @intCast(u32, array_ty.arrayLenIncludingSentinel());
3875
3876 const stack_offset = try self.allocMem(inst, 8, 8);
3877 try self.genSetStack(ptr_ty, stack_offset + 4, ptr);
3878 try self.genSetStack(Type.initTag(.usize), stack_offset, .{ .immediate = array_len });
3879 break :result MCValue{ .stack_offset = stack_offset };
3880 };
3861 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });3881 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
3862}3882}
38633883
...@@ -4078,6 +4098,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -4078,6 +4098,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
4078 }4098 }
40794099
4080 switch (typed_value.ty.zigTypeTag()) {4100 switch (typed_value.ty.zigTypeTag()) {
4101 .Array => {
4102 return self.lowerUnnamedConst(typed_value);
4103 },
4081 .Pointer => switch (typed_value.ty.ptrSize()) {4104 .Pointer => switch (typed_value.ty.ptrSize()) {
4082 .Slice => {4105 .Slice => {
4083 return self.lowerUnnamedConst(typed_value);4106 return self.lowerUnnamedConst(typed_value);
test/behavior/array.zig-2
...@@ -49,7 +49,6 @@ fn getArrayLen(a: []const u32) usize {...@@ -49,7 +49,6 @@ fn getArrayLen(a: []const u32) usize {
4949
50test "array init with mult" {50test "array init with mult" {
51 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;51 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
52 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
5352
54 const a = 'a';53 const a = 'a';
55 var i: [8]u8 = [2]u8{ a, 'b' } ** 4;54 var i: [8]u8 = [2]u8{ a, 'b' } ** 4;
...@@ -98,7 +97,6 @@ test "array literal with specified size" {...@@ -98,7 +97,6 @@ test "array literal with specified size" {
9897
99test "array len field" {98test "array len field" {
100 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;99 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
101 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
102100
103 var arr = [4]u8{ 0, 0, 0, 0 };101 var arr = [4]u8{ 0, 0, 0, 0 };
104 var ptr = &arr;102 var ptr = &arr;
test/behavior/cast.zig-3
...@@ -273,7 +273,6 @@ test "*const ?[*]const T to [*c]const [*c]const T" {...@@ -273,7 +273,6 @@ test "*const ?[*]const T to [*c]const [*c]const T" {
273273
274test "array coersion to undefined at runtime" {274test "array coersion to undefined at runtime" {
275 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;275 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
276 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
277276
278 @setRuntimeSafety(true);277 @setRuntimeSafety(true);
279278
...@@ -337,7 +336,6 @@ test "peer type unsigned int to signed" {...@@ -337,7 +336,6 @@ test "peer type unsigned int to signed" {
337336
338test "expected [*c]const u8, found [*:0]const u8" {337test "expected [*c]const u8, found [*:0]const u8" {
339 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;338 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
340 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
341339
342 var a: [*:0]const u8 = "hello";340 var a: [*:0]const u8 = "hello";
343 var b: [*c]const u8 = a;341 var b: [*c]const u8 = a;
...@@ -648,7 +646,6 @@ test "peer cast *[0]T to []const T" {...@@ -648,7 +646,6 @@ test "peer cast *[0]T to []const T" {
648test "peer cast *[N]T to [*]T" {646test "peer cast *[N]T to [*]T" {
649 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;647 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
650 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO648 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
651 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
652 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO649 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
653650
654 var array = [4:99]i32{ 1, 2, 3, 4 };651 var array = [4:99]i32{ 1, 2, 3, 4 };
test/behavior/if.zig-1
...@@ -4,7 +4,6 @@ const expect = std.testing.expect;...@@ -4,7 +4,6 @@ const expect = std.testing.expect;
4const expectEqual = std.testing.expectEqual;4const expectEqual = std.testing.expectEqual;
55
6test "if statements" {6test "if statements" {
7 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;7 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
98
10 shouldBeEqual(1, 1);9 shouldBeEqual(1, 1);
test/behavior/slice.zig-2
...@@ -257,7 +257,6 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 {...@@ -257,7 +257,6 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 {
257257
258test "C pointer" {258test "C pointer" {
259 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;259 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
260 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
261260
262 var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf";261 var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf";
263 var len: u32 = 10;262 var len: u32 = 10;
...@@ -356,7 +355,6 @@ test "empty array to slice" {...@@ -356,7 +355,6 @@ test "empty array to slice" {
356355
357test "@ptrCast slice to pointer" {356test "@ptrCast slice to pointer" {
358 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;357 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
359 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
360358
361 const S = struct {359 const S = struct {
362 fn doTheTest() !void {360 fn doTheTest() !void {
test/behavior/while.zig-1
...@@ -249,7 +249,6 @@ fn returnTrue() bool {...@@ -249,7 +249,6 @@ fn returnTrue() bool {
249249
250test "return with implicit cast from while loop" {250test "return with implicit cast from while loop" {
251 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;251 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
252 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
253 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;252 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
254253
255 returnWithImplicitCastFromWhileLoopTest() catch unreachable;254 returnWithImplicitCastFromWhileLoopTest() catch unreachable;