| author | |
| committer | |
| log | 94499898e5cd31209ddfdae3f0c9b418b7f67e60 |
| tree | c058983361e981d9cbc21139b79e9bfd1ad4864b |
| parent | b976997e16835e822ef9400973ac12a20e3d0705 |
| signature | Commit is signed but in an unrecognized format. |
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 { | ... | @@ -2359,9 +2359,68 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 2359 | return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none }); | 2359 | return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none }); |
| 2360 | } | 2360 | } |
| 2361 | 2361 | ||
| 2362 | fn 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 | |||
| 2362 | fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | 2415 | fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2363 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 2416 | 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 | }; | ||
| 2365 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | 2424 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 2366 | } | 2425 | } |
| 2367 | 2426 |
test/behavior/array.zig-3| ... | @@ -244,7 +244,6 @@ const Sub = struct { b: u8 }; | ... | @@ -244,7 +244,6 @@ const Sub = struct { b: u8 }; |
| 244 | const Str = struct { a: []Sub }; | 244 | const Str = struct { a: []Sub }; |
| 245 | test "set global var array via slice embedded in struct" { | 245 | test "set global var array via slice embedded in struct" { |
| 246 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 246 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 247 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 248 | 247 | ||
| 249 | var s = Str{ .a = s_array[0..] }; | 248 | var s = Str{ .a = s_array[0..] }; |
| 250 | 249 | ||
| ... | @@ -297,7 +296,6 @@ fn testArrayByValAtComptime(b: [2]u8) u8 { | ... | @@ -297,7 +296,6 @@ fn testArrayByValAtComptime(b: [2]u8) u8 { |
| 297 | 296 | ||
| 298 | test "comptime evaluating function that takes array by value" { | 297 | test "comptime evaluating function that takes array by value" { |
| 299 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 298 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 300 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 301 | 299 | ||
| 302 | const arr = [_]u8{ 1, 2 }; | 300 | const arr = [_]u8{ 1, 2 }; |
| 303 | const x = comptime testArrayByValAtComptime(arr); | 301 | const x = comptime testArrayByValAtComptime(arr); |
| ... | @@ -426,7 +424,6 @@ test "anonymous literal in array" { | ... | @@ -426,7 +424,6 @@ test "anonymous literal in array" { |
| 426 | 424 | ||
| 427 | test "access the null element of a null terminated array" { | 425 | test "access the null element of a null terminated array" { |
| 428 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 426 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 429 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 430 | 427 | ||
| 431 | const S = struct { | 428 | const S = struct { |
| 432 | fn doTheTest() !void { | 429 | fn doTheTest() !void { |
test/behavior/eval.zig-1| ... | @@ -336,7 +336,6 @@ fn doesAlotT(comptime T: type, value: usize) T { | ... | @@ -336,7 +336,6 @@ fn doesAlotT(comptime T: type, value: usize) T { |
| 336 | } | 336 | } |
| 337 | 337 | ||
| 338 | test "@setEvalBranchQuota at same scope as generic function call" { | 338 | test "@setEvalBranchQuota at same scope as generic function call" { |
| 339 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 340 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 339 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 341 | 340 | ||
| 342 | try expect(doesAlotT(u32, 2) == 2); | 341 | try expect(doesAlotT(u32, 2) == 2); |
test/behavior/for.zig-3| ... | @@ -5,7 +5,6 @@ const expectEqual = std.testing.expectEqual; | ... | @@ -5,7 +5,6 @@ const expectEqual = std.testing.expectEqual; |
| 5 | const mem = std.mem; | 5 | const mem = std.mem; |
| 6 | 6 | ||
| 7 | test "continue in for loop" { | 7 | test "continue in for loop" { |
| 8 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | ||
| 9 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 8 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 10 | 9 | ||
| 11 | const array = [_]i32{ 1, 2, 3, 4, 5 }; | 10 | 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" { | ... | @@ -130,7 +129,6 @@ test "for with null and T peer types and inferred result location type" { |
| 130 | } | 129 | } |
| 131 | 130 | ||
| 132 | test "2 break statements and an else" { | 131 | test "2 break statements and an else" { |
| 133 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | ||
| 134 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 132 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 135 | 133 | ||
| 136 | const S = struct { | 134 | const S = struct { |
| ... | @@ -177,7 +175,6 @@ fn mangleString(s: []u8) void { | ... | @@ -177,7 +175,6 @@ fn mangleString(s: []u8) void { |
| 177 | } | 175 | } |
| 178 | 176 | ||
| 179 | test "for copies its payload" { | 177 | test "for copies its payload" { |
| 180 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 181 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 178 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 182 | 179 | ||
| 183 | const S = struct { | 180 | const S = struct { |
test/behavior/slice.zig-1| ... | @@ -268,7 +268,6 @@ fn sliceSum(comptime q: []const u8) i32 { | ... | @@ -268,7 +268,6 @@ fn sliceSum(comptime q: []const u8) i32 { |
| 268 | 268 | ||
| 269 | test "slice type with custom alignment" { | 269 | test "slice type with custom alignment" { |
| 270 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 270 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 271 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | ||
| 272 | 271 | ||
| 273 | const LazilyResolvedType = struct { | 272 | const LazilyResolvedType = struct { |
| 274 | anything: i32, | 273 | anything: i32, |