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;
1313const InnerError = Module.InnerError;
1414
1515pub 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.
1718 discard,
1819 /// The expression has an inferred type, and it will be evaluated as an rvalue.
1920 none,
src-self-hosted/codegen.zig+19-21
......@@ -1540,14 +1540,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
15401540 }
15411541
15421542 fn genCondBr(self: *Self, inst: *ir.Inst.CondBr) !MCValue {
1543 // TODO Rework this so that the arch-independent logic isn't buried and duplicated.
1544 switch (arch) {
1545 .x86_64 => {
1543 const cond = try self.resolveInst(inst.condition);
1544
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: {
15461548 try self.code.ensureCapacity(self.code.items.len + 6);
15471549
1548 const cond = try self.resolveInst(inst.condition);
1549 switch (cond) {
1550 .compare_flags_signed => |cmp_op| {
1550 const opcode: u8 = switch (cond) {
1551 .compare_flags_signed => |cmp_op| blk: {
15511552 // Here we map to the opposite opcode because the jump is to the false branch.
15521553 const opcode: u8 = switch (cmp_op) {
15531554 .gte => 0x8c,
......@@ -1557,9 +1558,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
15571558 .lte => 0x8f,
15581559 .eq => 0x85,
15591560 };
1560 return self.genX86CondBr(inst, opcode);
1561 break :blk opcode;
15611562 },
1562 .compare_flags_unsigned => |cmp_op| {
1563 .compare_flags_unsigned => |cmp_op| blk: {
15631564 // Here we map to the opposite opcode because the jump is to the false branch.
15641565 const opcode: u8 = switch (cmp_op) {
15651566 .gte => 0x82,
......@@ -1569,9 +1570,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
15691570 .lte => 0x87,
15701571 .eq => 0x85,
15711572 };
1572 return self.genX86CondBr(inst, opcode);
1573 break :blk opcode;
15731574 },
1574 .register => |reg| {
1575 .register => |reg| blk: {
15751576 // test reg, 1
15761577 // TODO detect al, ax, eax
15771578 try self.code.ensureCapacity(self.code.items.len + 4);
......@@ -1583,20 +1584,17 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
15831584 @as(u8, 0xC0) | (0 << 3) | @truncate(u3, reg.id()),
15841585 0x01,
15851586 });
1586 return self.genX86CondBr(inst, 0x84);
1587 break :blk 0x84;
15871588 },
15881589 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;
15901595 },
1591 else => return self.fail(inst.base.src, "TODO implement condbr for {}", .{self.target.cpu.arch}),
1592 }
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;
1596 else => return self.fail(inst.base.src, "TODO implement condbr {}", .{ self.target.cpu.arch }),
1597 };
16001598 try self.genBody(inst.then_body);
16011599 try self.performReloc(inst.base.src, reloc);
16021600 try self.genBody(inst.else_body);