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 {...@@ -1277,11 +1277,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
12771277
1278 switch (op) {1278 switch (op) {
1279 .add => {1279 .add => {
1280 // TODO runtime safety checks (overflow)
1281 writeInt(u32, try self.code.addManyAsArray(4), Instruction.add(.al, dst_reg, dst_reg, operand).toU32());1280 writeInt(u32, try self.code.addManyAsArray(4), Instruction.add(.al, dst_reg, dst_reg, operand).toU32());
1282 },1281 },
1283 .sub => {1282 .sub => {
1284 // TODO runtime safety checks (underflow)
1285 if (lhs_is_dest) {1283 if (lhs_is_dest) {
1286 writeInt(u32, try self.code.addManyAsArray(4), Instruction.sub(.al, dst_reg, dst_reg, operand).toU32());1284 writeInt(u32, try self.code.addManyAsArray(4), Instruction.sub(.al, dst_reg, dst_reg, operand).toU32());
1287 } else {1285 } else {
...@@ -1297,6 +1295,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1297,6 +1295,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1297 .not, .xor => {1295 .not, .xor => {
1298 writeInt(u32, try self.code.addManyAsArray(4), Instruction.eor(.al, dst_reg, dst_reg, operand).toU32());1296 writeInt(u32, try self.code.addManyAsArray(4), Instruction.eor(.al, dst_reg, dst_reg, operand).toU32());
1299 },1297 },
1298 .cmp_eq => {
1299 writeInt(u32, try self.code.addManyAsArray(4), Instruction.cmp(.al, dst_reg, operand).toU32());
1300 },
1300 else => unreachable, // not a binary instruction1301 else => unreachable, // not a binary instruction
1301 }1302 }
1302 }1303 }
...@@ -1957,6 +1958,20 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1957,6 +1958,20 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1957 .unsigned => MCValue{ .compare_flags_unsigned = op },1958 .unsigned => MCValue{ .compare_flags_unsigned = op },
1958 };1959 };
1959 },1960 },
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 },
1960 else => return self.fail(inst.base.src, "TODO implement cmp for {}", .{self.target.cpu.arch}),1975 else => return self.fail(inst.base.src, "TODO implement cmp for {}", .{self.target.cpu.arch}),
1961 }1976 }
1962 }1977 }
...@@ -2022,6 +2037,30 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2022,6 +2037,30 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2022 },2037 },
2023 .arm, .armeb => reloc: {2038 .arm, .armeb => reloc: {
2024 const condition: Condition = switch (cond) {2039 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 },
2025 .register => |reg| blk: {2064 .register => |reg| blk: {
2026 // cmp reg, 12065 // cmp reg, 1
2027 // bne ...2066 // bne ...
...@@ -2253,7 +2292,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2253,7 +2292,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2253 .arm_branch => |info| {2292 .arm_branch => |info| {
2254 switch (arch) {2293 switch (arch) {
2255 .arm, .armeb => {2294 .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);
2257 if (math.cast(i26, amt)) |delta| {2296 if (math.cast(i26, amt)) |delta| {
2258 writeInt(u32, self.code.items[info.pos..][0..4], Instruction.b(info.cond, delta).toU32());2297 writeInt(u32, self.code.items[info.pos..][0..4], Instruction.b(info.cond, delta).toU32());
2259 } else |_| {2298 } else |_| {