authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-24 16:43:20-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-25 22:44:18-07:00
logb68fa9970b5cf5bb5954da476cc8679512ce489b
tree4ef143b30868e0f5f303634c2e17427b711277a9
parent982ab7df6cd61a874e98ef99e923a98e02cf7487

stage2 codegen: Rework genCondBr

so that the arch-independent logic isn't buried and duplicated.

2 files changed, 21 insertions(+), 22 deletions(-)

src-self-hosted/astgen.zig+2-1
...@@ -13,7 +13,8 @@ const Scope = Module.Scope;...@@ -13,7 +13,8 @@ const Scope = Module.Scope;
13const InnerError = Module.InnerError;13const InnerError = Module.InnerError;
1414
15pub const ResultLoc = union(enum) {15pub const ResultLoc = union(enum) {
16 /// The expression is the right-hand side of assignment to `_`.16 /// The expression is the right-hand side of assignment to `_`. Only the side-effects of the
17 /// expression should be generated.
17 discard,18 discard,
18 /// The expression has an inferred type, and it will be evaluated as an rvalue.19 /// The expression has an inferred type, and it will be evaluated as an rvalue.
19 none,20 none,
src-self-hosted/codegen.zig+19-21
...@@ -1540,14 +1540,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1540,14 +1540,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1540 }1540 }
15411541
1542 fn genCondBr(self: *Self, inst: *ir.Inst.CondBr) !MCValue {1542 fn genCondBr(self: *Self, inst: *ir.Inst.CondBr) !MCValue {
1543 // TODO Rework this so that the arch-independent logic isn't buried and duplicated.1543 const cond = try self.resolveInst(inst.condition);
1544 switch (arch) {1544
1545 .x86_64 => {1545 // TODO deal with liveness / deaths condbr's then_entry_deaths and else_entry_deaths
1546 const reloc: Reloc = switch (arch) {
1547 .i386, .x86_64 => reloc: {
1546 try self.code.ensureCapacity(self.code.items.len + 6);1548 try self.code.ensureCapacity(self.code.items.len + 6);
15471549
1548 const cond = try self.resolveInst(inst.condition);1550 const opcode: u8 = switch (cond) {
1549 switch (cond) {1551 .compare_flags_signed => |cmp_op| blk: {
1550 .compare_flags_signed => |cmp_op| {
1551 // Here we map to the opposite opcode because the jump is to the false branch.1552 // Here we map to the opposite opcode because the jump is to the false branch.
1552 const opcode: u8 = switch (cmp_op) {1553 const opcode: u8 = switch (cmp_op) {
1553 .gte => 0x8c,1554 .gte => 0x8c,
...@@ -1557,9 +1558,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1557,9 +1558,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1557 .lte => 0x8f,1558 .lte => 0x8f,
1558 .eq => 0x85,1559 .eq => 0x85,
1559 };1560 };
1560 return self.genX86CondBr(inst, opcode);1561 break :blk opcode;
1561 },1562 },
1562 .compare_flags_unsigned => |cmp_op| {1563 .compare_flags_unsigned => |cmp_op| blk: {
1563 // Here we map to the opposite opcode because the jump is to the false branch.1564 // Here we map to the opposite opcode because the jump is to the false branch.
1564 const opcode: u8 = switch (cmp_op) {1565 const opcode: u8 = switch (cmp_op) {
1565 .gte => 0x82,1566 .gte => 0x82,
...@@ -1569,9 +1570,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1569,9 +1570,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1569 .lte => 0x87,1570 .lte => 0x87,
1570 .eq => 0x85,1571 .eq => 0x85,
1571 };1572 };
1572 return self.genX86CondBr(inst, opcode);1573 break :blk opcode;
1573 },1574 },
1574 .register => |reg| {1575 .register => |reg| blk: {
1575 // test reg, 11576 // test reg, 1
1576 // TODO detect al, ax, eax1577 // TODO detect al, ax, eax
1577 try self.code.ensureCapacity(self.code.items.len + 4);1578 try self.code.ensureCapacity(self.code.items.len + 4);
...@@ -1583,20 +1584,17 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1583,20 +1584,17 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1583 @as(u8, 0xC0) | (0 << 3) | @truncate(u3, reg.id()),1584 @as(u8, 0xC0) | (0 << 3) | @truncate(u3, reg.id()),
1584 0x01,1585 0x01,
1585 });1586 });
1586 return self.genX86CondBr(inst, 0x84);1587 break :blk 0x84;
1587 },1588 },
1588 else => return self.fail(inst.base.src, "TODO implement condbr {} when condition is {}", .{ self.target.cpu.arch, @tagName(cond) }),1589 else => return self.fail(inst.base.src, "TODO implement condbr {} when condition is {}", .{ self.target.cpu.arch, @tagName(cond) }),
1589 }1590 };
1591 self.code.appendSliceAssumeCapacity(&[_]u8{ 0x0f, opcode });
1592 const reloc = Reloc{ .rel32 = self.code.items.len };
1593 self.code.items.len += 4;
1594 break :reloc reloc;
1590 },1595 },
1591 else => return self.fail(inst.base.src, "TODO implement condbr for {}", .{self.target.cpu.arch}),1596 else => return self.fail(inst.base.src, "TODO implement condbr {}", .{ self.target.cpu.arch }),
1592 }1597 };
1593 }
1594
1595 fn genX86CondBr(self: *Self, inst: *ir.Inst.CondBr, opcode: u8) !MCValue {
1596 // TODO deal with liveness / deaths condbr's then_entry_deaths and else_entry_deaths
1597 self.code.appendSliceAssumeCapacity(&[_]u8{ 0x0f, opcode });
1598 const reloc = Reloc{ .rel32 = self.code.items.len };
1599 self.code.items.len += 4;
1600 try self.genBody(inst.then_body);1598 try self.genBody(inst.then_body);
1601 try self.performReloc(inst.base.src, reloc);1599 try self.performReloc(inst.base.src, reloc);
1602 try self.genBody(inst.else_body);1600 try self.genBody(inst.else_body);