aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoachimschmidt557 <joachim.schmidt557@outlook.com>2022-09-09 17:01:09 +0200
committerjoachimschmidt557 <joachim.schmidt557@outlook.com>2022-09-09 20:26:04 +0200
commit94499898e5cd31209ddfdae3f0c9b418b7f67e60 (patch)
treec058983361e981d9cbc21139b79e9bfd1ad4864b
parentb976997e16835e822ef9400973ac12a20e3d0705 (diff)
downloadzig-94499898e5cd31209ddfdae3f0c9b418b7f67e60.tar.gz
zig-94499898e5cd31209ddfdae3f0c9b418b7f67e60.zip
stage2 ARM: implement basic array_elem_val
-rw-r--r--src/arch/arm/CodeGen.zig61
-rw-r--r--test/behavior/array.zig3
-rw-r--r--test/behavior/eval.zig1
-rw-r--r--test/behavior/for.zig3
-rw-r--r--test/behavior/slice.zig1
5 files changed, 60 insertions, 9 deletions
diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig
index 857c49fd78..0eeb7a7ded 100644
--- a/src/arch/arm/CodeGen.zig
+++ b/src/arch/arm/CodeGen.zig
@@ -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 });
}
diff --git a/test/behavior/array.zig b/test/behavior/array.zig
index 1e5e848c09..54f87927f5 100644
--- a/test/behavior/array.zig
+++ b/test/behavior/array.zig
@@ -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 {
diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig
index 373e4e33c6..47d2e4374e 100644
--- a/test/behavior/eval.zig
+++ b/test/behavior/eval.zig
@@ -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);
diff --git a/test/behavior/for.zig b/test/behavior/for.zig
index 20a88a3131..7f2cd2ab8d 100644
--- a/test/behavior/for.zig
+++ b/test/behavior/for.zig
@@ -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 {
diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig
index fad6cd643f..b9bae08878 100644
--- a/test/behavior/slice.zig
+++ b/test/behavior/slice.zig
@@ -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,