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