authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-17 17:54:37+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-18 09:14:15+01:00
logabfaf8382b58d8bdfa029b74205d385cbc73d78e
tree8c677b9e277debee3ef10ee632ccd004053688ba
parent085c606b8739fac707e842069010661ed2ec8249

x64: implement array_elem_val when array fits in register


2 files changed, 37 insertions(+), 29 deletions(-)

src/arch/x86_64/CodeGen.zig+31-15
......@@ -1589,21 +1589,37 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
15891589 self.register_manager.freezeRegs(&.{offset_reg});
15901590 defer self.register_manager.unfreezeRegs(&.{offset_reg});
15911591
1592 const addr_reg = try self.register_manager.allocReg(null);
1593 switch (array) {
1594 .stack_offset => |off| {
1595 // lea reg, [rbp]
1596 _ = try self.addInst(.{
1597 .tag = .lea,
1598 .ops = (Mir.Ops{
1599 .reg1 = addr_reg.to64(),
1600 .reg2 = .rbp,
1601 }).encode(),
1602 .data = .{ .imm = @bitCast(u32, -off) },
1603 });
1604 },
1605 else => return self.fail("TODO implement array_elem_val when array is {}", .{array}),
1606 }
1592 const addr_reg = blk: {
1593 const off = inner: {
1594 switch (array) {
1595 .register => {
1596 const off = @intCast(i32, try self.allocMem(
1597 inst,
1598 @intCast(u32, array_ty.abiSize(self.target.*)),
1599 array_ty.abiAlignment(self.target.*),
1600 ));
1601 try self.genSetStack(array_ty, off, array);
1602 break :inner off;
1603 },
1604 .stack_offset => |off| {
1605 break :inner off;
1606 },
1607 else => return self.fail("TODO implement array_elem_val when array is {}", .{array}),
1608 }
1609 };
1610 const addr_reg = try self.register_manager.allocReg(null);
1611 // lea reg, [rbp]
1612 _ = try self.addInst(.{
1613 .tag = .lea,
1614 .ops = (Mir.Ops{
1615 .reg1 = addr_reg.to64(),
1616 .reg2 = .rbp,
1617 }).encode(),
1618 .data = .{ .imm = @bitCast(u32, -off) },
1619 });
1620 break :blk addr_reg.to64();
1621 };
1622
16071623 // TODO we could allocate register here, but need to expect addr register and potentially
16081624 // offset register.
16091625 const dst_mcv = try self.allocRegOrMem(inst, false);
test/behavior/array.zig+6-14
......@@ -8,7 +8,6 @@ const expectEqual = testing.expectEqual;
88test "array to slice" {
99 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1010 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
11 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1211
1312 const a: u32 align(4) = 3;
1413 const b: u32 align(8) = 4;
......@@ -62,7 +61,7 @@ test "array init with mult" {
6261
6362test "array literal with explicit type" {
6463 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
65 if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
64 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
6665
6766 const hex_mult: [4]u16 = .{ 4096, 256, 16, 1 };
6867
......@@ -71,7 +70,7 @@ test "array literal with explicit type" {
7170}
7271
7372test "array literal with inferred length" {
74 if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
73 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
7574
7675 const hex_mult = [_]u16{ 4096, 256, 16, 1 };
7776
......@@ -92,7 +91,7 @@ const some_array = [_]u8{ 0, 1, 2, 3 };
9291
9392test "array literal with specified size" {
9493 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
95 if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
94 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
9695
9796 var array = [2]u8{ 1, 2 };
9897 try expect(array[0] == 1);
......@@ -101,7 +100,7 @@ test "array literal with specified size" {
101100
102101test "array len field" {
103102 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
104 if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
103 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
105104
106105 var arr = [4]u8{ 0, 0, 0, 0 };
107106 var ptr = &arr;
......@@ -143,7 +142,7 @@ test "array with sentinels" {
143142
144143test "void arrays" {
145144 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
146 if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
145 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
147146
148147 var array: [4]void = undefined;
149148 array[0] = void{};
......@@ -222,7 +221,7 @@ test "implicit cast zero sized array ptr to slice" {
222221
223222test "anonymous list literal syntax" {
224223 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
225 if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
224 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
226225
227226 const S = struct {
228227 fn doTheTest() !void {
......@@ -282,7 +281,6 @@ test "read/write through global variable array of struct fields initialized via
282281test "implicit cast single-item pointer" {
283282 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
284283 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
285 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
286284 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
287285
288286 try testImplicitCastSingleItemPtr();
......@@ -303,7 +301,6 @@ fn testArrayByValAtComptime(b: [2]u8) u8 {
303301test "comptime evaluating function that takes array by value" {
304302 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
305303 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
306 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
307304 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
308305
309306 const arr = [_]u8{ 1, 2 };
......@@ -316,7 +313,6 @@ test "comptime evaluating function that takes array by value" {
316313test "runtime initialize array elem and then implicit cast to slice" {
317314 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
318315 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
319 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
320316 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
321317
322318 var two: i32 = 2;
......@@ -327,7 +323,6 @@ test "runtime initialize array elem and then implicit cast to slice" {
327323test "array literal as argument to function" {
328324 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
329325 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
330 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
331326 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
332327
333328 const S = struct {
......@@ -418,7 +413,6 @@ test "double nested array to const slice cast in array literal" {
418413test "anonymous literal in array" {
419414 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
420415 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
421 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
422416 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
423417
424418 const S = struct {
......@@ -444,7 +438,6 @@ test "anonymous literal in array" {
444438test "access the null element of a null terminated array" {
445439 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
446440 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
447 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
448441 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
449442
450443 const S = struct {
......@@ -462,7 +455,6 @@ test "access the null element of a null terminated array" {
462455test "type deduction for array subscript expression" {
463456 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
464457 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
465 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
466458 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
467459
468460 const S = struct {