aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-02-17 17:54:37 +0100
committerJakub Konka <kubkon@jakubkonka.com>2022-02-18 09:14:15 +0100
commitabfaf8382b58d8bdfa029b74205d385cbc73d78e (patch)
tree8c677b9e277debee3ef10ee632ccd004053688ba /src
parent085c606b8739fac707e842069010661ed2ec8249 (diff)
downloadzig-abfaf8382b58d8bdfa029b74205d385cbc73d78e.tar.gz
zig-abfaf8382b58d8bdfa029b74205d385cbc73d78e.zip
x64: implement array_elem_val when array fits in register
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86_64/CodeGen.zig46
1 files changed, 31 insertions, 15 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig
index 7b96ea4baa..cc3953e57b 100644
--- a/src/arch/x86_64/CodeGen.zig
+++ b/src/arch/x86_64/CodeGen.zig
@@ -1589,21 +1589,37 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
self.register_manager.freezeRegs(&.{offset_reg});
defer self.register_manager.unfreezeRegs(&.{offset_reg});
- const addr_reg = try self.register_manager.allocReg(null);
- switch (array) {
- .stack_offset => |off| {
- // lea reg, [rbp]
- _ = try self.addInst(.{
- .tag = .lea,
- .ops = (Mir.Ops{
- .reg1 = addr_reg.to64(),
- .reg2 = .rbp,
- }).encode(),
- .data = .{ .imm = @bitCast(u32, -off) },
- });
- },
- else => return self.fail("TODO implement array_elem_val when array is {}", .{array}),
- }
+ const addr_reg = blk: {
+ const off = inner: {
+ switch (array) {
+ .register => {
+ const off = @intCast(i32, try self.allocMem(
+ inst,
+ @intCast(u32, array_ty.abiSize(self.target.*)),
+ array_ty.abiAlignment(self.target.*),
+ ));
+ try self.genSetStack(array_ty, off, array);
+ break :inner off;
+ },
+ .stack_offset => |off| {
+ break :inner off;
+ },
+ else => return self.fail("TODO implement array_elem_val when array is {}", .{array}),
+ }
+ };
+ const addr_reg = try self.register_manager.allocReg(null);
+ // lea reg, [rbp]
+ _ = try self.addInst(.{
+ .tag = .lea,
+ .ops = (Mir.Ops{
+ .reg1 = addr_reg.to64(),
+ .reg2 = .rbp,
+ }).encode(),
+ .data = .{ .imm = @bitCast(u32, -off) },
+ });
+ break :blk addr_reg.to64();
+ };
+
// TODO we could allocate register here, but need to expect addr register and potentially
// offset register.
const dst_mcv = try self.allocRegOrMem(inst, false);