authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2020-12-28 18:17:22+01:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2021-01-01 12:22:16+01:00
log85e1b47c40c023d8a3d75fadaeeb643a361bbc4d
tree1b578d78315792ff73fa7abb3be3287260987ab1
parent4d2919a1eed3a916f87cc5f838c9cd2b23ddef70
signaturelock-open Commit is signed but in an unrecognized format.

stage2 ARM: implement genCondBr for compare_flags


1 files changed, 42 insertions(+), 3 deletions(-)

src/codegen.zig+42-3
......@@ -1277,11 +1277,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
12771277
12781278 switch (op) {
12791279 .add => {
1280 // TODO runtime safety checks (overflow)
12811280 writeInt(u32, try self.code.addManyAsArray(4), Instruction.add(.al, dst_reg, dst_reg, operand).toU32());
12821281 },
12831282 .sub => {
1284 // TODO runtime safety checks (underflow)
12851283 if (lhs_is_dest) {
12861284 writeInt(u32, try self.code.addManyAsArray(4), Instruction.sub(.al, dst_reg, dst_reg, operand).toU32());
12871285 } else {
......@@ -1297,6 +1295,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
12971295 .not, .xor => {
12981296 writeInt(u32, try self.code.addManyAsArray(4), Instruction.eor(.al, dst_reg, dst_reg, operand).toU32());
12991297 },
1298 .cmp_eq => {
1299 writeInt(u32, try self.code.addManyAsArray(4), Instruction.cmp(.al, dst_reg, operand).toU32());
1300 },
13001301 else => unreachable, // not a binary instruction
13011302 }
13021303 }
......@@ -1957,6 +1958,20 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
19571958 .unsigned => MCValue{ .compare_flags_unsigned = op },
19581959 };
19591960 },
1961 .arm, .armeb => {
1962 const lhs = try self.resolveInst(inst.lhs);
1963 const rhs = try self.resolveInst(inst.rhs);
1964
1965 const src_mcv = rhs;
1966 const dst_mcv = if (lhs != .register) try self.copyToNewRegister(&inst.base, lhs) else lhs;
1967
1968 try self.genArmBinOpCode(inst.base.src, dst_mcv.register, src_mcv, true, .cmp_eq);
1969 const info = inst.lhs.ty.intInfo(self.target.*);
1970 return switch (info.signedness) {
1971 .signed => MCValue{ .compare_flags_signed = op },
1972 .unsigned => MCValue{ .compare_flags_unsigned = op },
1973 };
1974 },
19601975 else => return self.fail(inst.base.src, "TODO implement cmp for {}", .{self.target.cpu.arch}),
19611976 }
19621977 }
......@@ -2022,6 +2037,30 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
20222037 },
20232038 .arm, .armeb => reloc: {
20242039 const condition: Condition = switch (cond) {
2040 .compare_flags_signed => |cmp_op| blk: {
2041 // Here we map to the opposite condition because the jump is to the false branch.
2042 const condition: Condition = switch (cmp_op) {
2043 .gte => .lt,
2044 .gt => .le,
2045 .neq => .eq,
2046 .lt => .ge,
2047 .lte => .gt,
2048 .eq => .ne,
2049 };
2050 break :blk condition;
2051 },
2052 .compare_flags_unsigned => |cmp_op| blk: {
2053 // Here we map to the opposite condition because the jump is to the false branch.
2054 const condition: Condition = switch (cmp_op) {
2055 .gte => .cc,
2056 .gt => .ls,
2057 .neq => .eq,
2058 .lt => .cs,
2059 .lte => .hi,
2060 .eq => .ne,
2061 };
2062 break :blk condition;
2063 },
20252064 .register => |reg| blk: {
20262065 // cmp reg, 1
20272066 // bne ...
......@@ -2253,7 +2292,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
22532292 .arm_branch => |info| {
22542293 switch (arch) {
22552294 .arm, .armeb => {
2256 const amt = self.code.items.len - (info.pos + 4);
2295 const amt = @intCast(i32, self.code.items.len) - @intCast(i32, info.pos + 8);
22572296 if (math.cast(i26, amt)) |delta| {
22582297 writeInt(u32, self.code.items[info.pos..][0..4], Instruction.b(info.cond, delta).toU32());
22592298 } else |_| {