stage2 ARM: implement basic array_elem_val

This commit is contained in:
joachimschmidt557 2022-09-09 17:01:09 +02:00
parent b976997e16
commit 94499898e5
No known key found for this signature in database
GPG Key ID: E0B575BE2884ACC5
5 changed files with 60 additions and 9 deletions

View File

@ -2359,9 +2359,68 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void {
return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none });
}
fn arrayElemVal(
self: *Self,
array_bind: ReadArg.Bind,
index_bind: ReadArg.Bind,
array_ty: Type,
maybe_inst: ?Air.Inst.Index,
) InnerError!MCValue {
const elem_ty = array_ty.childType();
const mcv = try array_bind.resolveToMcv(self);
switch (mcv) {
.stack_offset,
.memory,
.stack_argument_offset,
=> {
const ptr_to_mcv = switch (mcv) {
.stack_offset => |off| MCValue{ .ptr_stack_offset = off },
.memory => |addr| MCValue{ .immediate = @intCast(u32, addr) },
.stack_argument_offset => |off| blk: {
const reg = try self.register_manager.allocReg(null, gp);
_ = try self.addInst(.{
.tag = .ldr_ptr_stack_argument,
.data = .{ .r_stack_offset = .{
.rt = reg,
.stack_offset = off,
} },
});
break :blk MCValue{ .register = reg };
},
else => unreachable,
};
const ptr_to_mcv_lock: ?RegisterLock = switch (ptr_to_mcv) {
.register => |reg| self.register_manager.lockRegAssumeUnused(reg),
else => null,
};
defer if (ptr_to_mcv_lock) |lock| self.register_manager.unlockReg(lock);
const base_bind: ReadArg.Bind = .{ .mcv = ptr_to_mcv };
var ptr_ty_payload: Type.Payload.ElemType = .{
.base = .{ .tag = .single_mut_pointer },
.data = elem_ty,
};
const ptr_ty = Type.initPayload(&ptr_ty_payload.base);
return try self.ptrElemVal(base_bind, index_bind, ptr_ty, maybe_inst);
},
else => return self.fail("TODO implement array_elem_val for {}", .{mcv}),
}
}
fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement array_elem_val for {}", .{self.target.cpu.arch});
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const array_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs };
const array_ty = self.air.typeOf(bin_op.lhs);
break :result try self.arrayElemVal(array_bind, index_bind, array_ty, inst);
};
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}

View File

@ -244,7 +244,6 @@ const Sub = struct { b: u8 };
const Str = struct { a: []Sub };
test "set global var array via slice embedded in struct" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
var s = Str{ .a = s_array[0..] };
@ -297,7 +296,6 @@ fn testArrayByValAtComptime(b: [2]u8) u8 {
test "comptime evaluating function that takes array by value" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
const arr = [_]u8{ 1, 2 };
const x = comptime testArrayByValAtComptime(arr);
@ -426,7 +424,6 @@ test "anonymous literal in array" {
test "access the null element of a null terminated array" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
const S = struct {
fn doTheTest() !void {

View File

@ -336,7 +336,6 @@ fn doesAlotT(comptime T: type, value: usize) T {
}
test "@setEvalBranchQuota at same scope as generic function call" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
try expect(doesAlotT(u32, 2) == 2);

View File

@ -5,7 +5,6 @@ const expectEqual = std.testing.expectEqual;
const mem = std.mem;
test "continue in for loop" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
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" {
}
test "2 break statements and an else" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
const S = struct {
@ -177,7 +175,6 @@ fn mangleString(s: []u8) void {
}
test "for copies its payload" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
const S = struct {

View File

@ -268,7 +268,6 @@ fn sliceSum(comptime q: []const u8) i32 {
test "slice type with custom alignment" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
const LazilyResolvedType = struct {
anything: i32,