authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-09-09 17:01:09+02:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-09-09 20:26:04+02:00
log94499898e5cd31209ddfdae3f0c9b418b7f67e60
treec058983361e981d9cbc21139b79e9bfd1ad4864b
parentb976997e16835e822ef9400973ac12a20e3d0705
signaturelock-open Commit is signed but in an unrecognized format.

stage2 ARM: implement basic array_elem_val


5 files changed, 60 insertions(+), 9 deletions(-)

src/arch/arm/CodeGen.zig+60-1
......@@ -2359,9 +2359,68 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void {
23592359 return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none });
23602360}
23612361
2362fn arrayElemVal(
2363 self: *Self,
2364 array_bind: ReadArg.Bind,
2365 index_bind: ReadArg.Bind,
2366 array_ty: Type,
2367 maybe_inst: ?Air.Inst.Index,
2368) InnerError!MCValue {
2369 const elem_ty = array_ty.childType();
2370
2371 const mcv = try array_bind.resolveToMcv(self);
2372 switch (mcv) {
2373 .stack_offset,
2374 .memory,
2375 .stack_argument_offset,
2376 => {
2377 const ptr_to_mcv = switch (mcv) {
2378 .stack_offset => |off| MCValue{ .ptr_stack_offset = off },
2379 .memory => |addr| MCValue{ .immediate = @intCast(u32, addr) },
2380 .stack_argument_offset => |off| blk: {
2381 const reg = try self.register_manager.allocReg(null, gp);
2382
2383 _ = try self.addInst(.{
2384 .tag = .ldr_ptr_stack_argument,
2385 .data = .{ .r_stack_offset = .{
2386 .rt = reg,
2387 .stack_offset = off,
2388 } },
2389 });
2390
2391 break :blk MCValue{ .register = reg };
2392 },
2393 else => unreachable,
2394 };
2395 const ptr_to_mcv_lock: ?RegisterLock = switch (ptr_to_mcv) {
2396 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
2397 else => null,
2398 };
2399 defer if (ptr_to_mcv_lock) |lock| self.register_manager.unlockReg(lock);
2400
2401 const base_bind: ReadArg.Bind = .{ .mcv = ptr_to_mcv };
2402
2403 var ptr_ty_payload: Type.Payload.ElemType = .{
2404 .base = .{ .tag = .single_mut_pointer },
2405 .data = elem_ty,
2406 };
2407 const ptr_ty = Type.initPayload(&ptr_ty_payload.base);
2408
2409 return try self.ptrElemVal(base_bind, index_bind, ptr_ty, maybe_inst);
2410 },
2411 else => return self.fail("TODO implement array_elem_val for {}", .{mcv}),
2412 }
2413}
2414
23622415fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
23632416 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2364 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement array_elem_val for {}", .{self.target.cpu.arch});
2417 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2418 const array_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
2419 const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs };
2420 const array_ty = self.air.typeOf(bin_op.lhs);
2421
2422 break :result try self.arrayElemVal(array_bind, index_bind, array_ty, inst);
2423 };
23652424 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
23662425}
23672426
test/behavior/array.zig-3
......@@ -244,7 +244,6 @@ const Sub = struct { b: u8 };
244244const Str = struct { a: []Sub };
245245test "set global var array via slice embedded in struct" {
246246 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
247 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
248247
249248 var s = Str{ .a = s_array[0..] };
250249
......@@ -297,7 +296,6 @@ fn testArrayByValAtComptime(b: [2]u8) u8 {
297296
298297test "comptime evaluating function that takes array by value" {
299298 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
300 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
301299
302300 const arr = [_]u8{ 1, 2 };
303301 const x = comptime testArrayByValAtComptime(arr);
......@@ -426,7 +424,6 @@ test "anonymous literal in array" {
426424
427425test "access the null element of a null terminated array" {
428426 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
429 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
430427
431428 const S = struct {
432429 fn doTheTest() !void {
test/behavior/eval.zig-1
......@@ -336,7 +336,6 @@ fn doesAlotT(comptime T: type, value: usize) T {
336336}
337337
338338test "@setEvalBranchQuota at same scope as generic function call" {
339 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
340339 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
341340
342341 try expect(doesAlotT(u32, 2) == 2);
test/behavior/for.zig-3
......@@ -5,7 +5,6 @@ const expectEqual = std.testing.expectEqual;
55const mem = std.mem;
66
77test "continue in for loop" {
8 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
98 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
109
1110 const array = [_]i32{ 1, 2, 3, 4, 5 };
......@@ -130,7 +129,6 @@ test "for with null and T peer types and inferred result location type" {
130129}
131130
132131test "2 break statements and an else" {
133 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
134132 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
135133
136134 const S = struct {
......@@ -177,7 +175,6 @@ fn mangleString(s: []u8) void {
177175}
178176
179177test "for copies its payload" {
180 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
181178 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
182179
183180 const S = struct {
test/behavior/slice.zig-1
......@@ -268,7 +268,6 @@ fn sliceSum(comptime q: []const u8) i32 {
268268
269269test "slice type with custom alignment" {
270270 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
271 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
272271
273272 const LazilyResolvedType = struct {
274273 anything: i32,