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 {...@@ -1589,21 +1589,37 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
1589 self.register_manager.freezeRegs(&.{offset_reg});1589 self.register_manager.freezeRegs(&.{offset_reg});
1590 defer self.register_manager.unfreezeRegs(&.{offset_reg});1590 defer self.register_manager.unfreezeRegs(&.{offset_reg});
15911591
1592 const addr_reg = try self.register_manager.allocReg(null);1592 const addr_reg = blk: {
1593 switch (array) {1593 const off = inner: {
1594 .stack_offset => |off| {1594 switch (array) {
1595 // lea reg, [rbp]1595 .register => {
1596 _ = try self.addInst(.{1596 const off = @intCast(i32, try self.allocMem(
1597 .tag = .lea,1597 inst,
1598 .ops = (Mir.Ops{1598 @intCast(u32, array_ty.abiSize(self.target.*)),
1599 .reg1 = addr_reg.to64(),1599 array_ty.abiAlignment(self.target.*),
1600 .reg2 = .rbp,1600 ));
1601 }).encode(),1601 try self.genSetStack(array_ty, off, array);
1602 .data = .{ .imm = @bitCast(u32, -off) },1602 break :inner off;
1603 });1603 },
1604 },1604 .stack_offset => |off| {
1605 else => return self.fail("TODO implement array_elem_val when array is {}", .{array}),1605 break :inner off;
1606 }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
1607 // TODO we could allocate register here, but need to expect addr register and potentially1623 // TODO we could allocate register here, but need to expect addr register and potentially
1608 // offset register.1624 // offset register.
1609 const dst_mcv = try self.allocRegOrMem(inst, false);1625 const dst_mcv = try self.allocRegOrMem(inst, false);
test/behavior/array.zig+6-14
...@@ -8,7 +8,6 @@ const expectEqual = testing.expectEqual;...@@ -8,7 +8,6 @@ const expectEqual = testing.expectEqual;
8test "array to slice" {8test "array to slice" {
9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
11 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1211
13 const a: u32 align(4) = 3;12 const a: u32 align(4) = 3;
14 const b: u32 align(8) = 4;13 const b: u32 align(8) = 4;
...@@ -62,7 +61,7 @@ test "array init with mult" {...@@ -62,7 +61,7 @@ test "array init with mult" {
6261
63test "array literal with explicit type" {62test "array literal with explicit type" {
64 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;63 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
67 const hex_mult: [4]u16 = .{ 4096, 256, 16, 1 };66 const hex_mult: [4]u16 = .{ 4096, 256, 16, 1 };
6867
...@@ -71,7 +70,7 @@ test "array literal with explicit type" {...@@ -71,7 +70,7 @@ test "array literal with explicit type" {
71}70}
7271
73test "array literal with inferred length" {72test "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
76 const hex_mult = [_]u16{ 4096, 256, 16, 1 };75 const hex_mult = [_]u16{ 4096, 256, 16, 1 };
7776
...@@ -92,7 +91,7 @@ const some_array = [_]u8{ 0, 1, 2, 3 };...@@ -92,7 +91,7 @@ const some_array = [_]u8{ 0, 1, 2, 3 };
9291
93test "array literal with specified size" {92test "array literal with specified size" {
94 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;93 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
97 var array = [2]u8{ 1, 2 };96 var array = [2]u8{ 1, 2 };
98 try expect(array[0] == 1);97 try expect(array[0] == 1);
...@@ -101,7 +100,7 @@ test "array literal with specified size" {...@@ -101,7 +100,7 @@ test "array literal with specified size" {
101100
102test "array len field" {101test "array len field" {
103 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;102 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
106 var arr = [4]u8{ 0, 0, 0, 0 };105 var arr = [4]u8{ 0, 0, 0, 0 };
107 var ptr = &arr;106 var ptr = &arr;
...@@ -143,7 +142,7 @@ test "array with sentinels" {...@@ -143,7 +142,7 @@ test "array with sentinels" {
143142
144test "void arrays" {143test "void arrays" {
145 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;144 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
148 var array: [4]void = undefined;147 var array: [4]void = undefined;
149 array[0] = void{};148 array[0] = void{};
...@@ -222,7 +221,7 @@ test "implicit cast zero sized array ptr to slice" {...@@ -222,7 +221,7 @@ test "implicit cast zero sized array ptr to slice" {
222221
223test "anonymous list literal syntax" {222test "anonymous list literal syntax" {
224 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;223 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
227 const S = struct {226 const S = struct {
228 fn doTheTest() !void {227 fn doTheTest() !void {
...@@ -282,7 +281,6 @@ test "read/write through global variable array of struct fields initialized via...@@ -282,7 +281,6 @@ test "read/write through global variable array of struct fields initialized via
282test "implicit cast single-item pointer" {281test "implicit cast single-item pointer" {
283 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;282 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
284 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO283 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
285 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
286 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO284 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
287285
288 try testImplicitCastSingleItemPtr();286 try testImplicitCastSingleItemPtr();
...@@ -303,7 +301,6 @@ fn testArrayByValAtComptime(b: [2]u8) u8 {...@@ -303,7 +301,6 @@ fn testArrayByValAtComptime(b: [2]u8) u8 {
303test "comptime evaluating function that takes array by value" {301test "comptime evaluating function that takes array by value" {
304 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;302 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
305 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO303 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
306 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
307 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO304 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
308305
309 const arr = [_]u8{ 1, 2 };306 const arr = [_]u8{ 1, 2 };
...@@ -316,7 +313,6 @@ test "comptime evaluating function that takes array by value" {...@@ -316,7 +313,6 @@ test "comptime evaluating function that takes array by value" {
316test "runtime initialize array elem and then implicit cast to slice" {313test "runtime initialize array elem and then implicit cast to slice" {
317 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;314 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
318 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO315 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
319 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
320 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO316 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
321317
322 var two: i32 = 2;318 var two: i32 = 2;
...@@ -327,7 +323,6 @@ test "runtime initialize array elem and then implicit cast to slice" {...@@ -327,7 +323,6 @@ test "runtime initialize array elem and then implicit cast to slice" {
327test "array literal as argument to function" {323test "array literal as argument to function" {
328 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;324 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
329 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO325 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
330 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
331 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO326 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
332327
333 const S = struct {328 const S = struct {
...@@ -418,7 +413,6 @@ test "double nested array to const slice cast in array literal" {...@@ -418,7 +413,6 @@ test "double nested array to const slice cast in array literal" {
418test "anonymous literal in array" {413test "anonymous literal in array" {
419 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;414 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
420 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO415 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
421 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
422 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO416 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
423417
424 const S = struct {418 const S = struct {
...@@ -444,7 +438,6 @@ test "anonymous literal in array" {...@@ -444,7 +438,6 @@ test "anonymous literal in array" {
444test "access the null element of a null terminated array" {438test "access the null element of a null terminated array" {
445 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;439 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
446 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO440 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
447 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
448 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO441 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
449442
450 const S = struct {443 const S = struct {
...@@ -462,7 +455,6 @@ test "access the null element of a null terminated array" {...@@ -462,7 +455,6 @@ test "access the null element of a null terminated array" {
462test "type deduction for array subscript expression" {455test "type deduction for array subscript expression" {
463 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;456 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
464 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO457 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
465 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
466 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO458 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
467459
468 const S = struct {460 const S = struct {