authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-02-17 21:12:43+01:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-02-19 12:06:34+01:00
log7b833b2fba35a1022ea76e89b6760e462ba09651
treecb0a0953559626288bb0fb300535c5531f66e07d
parent985a442f462a0a0728ed96a2a77e5290b6d534af
signaturelock-open Commit is signed but in an unrecognized format.

stage2 ARM: move {bool,bit}_{or,and} to binOp lowering mechanism


1 files changed, 79 insertions(+), 44 deletions(-)

src/arch/arm/CodeGen.zig+79-44
...@@ -548,11 +548,11 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -548,11 +548,11 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
548 .cmp_gt => try self.airCmp(inst, .gt),548 .cmp_gt => try self.airCmp(inst, .gt),
549 .cmp_neq => try self.airCmp(inst, .neq),549 .cmp_neq => try self.airCmp(inst, .neq),
550550
551 .bool_and => try self.airBoolOp(inst),551 .bool_and => try self.airBinOp(inst),
552 .bool_or => try self.airBoolOp(inst),552 .bool_or => try self.airBinOp(inst),
553 .bit_and => try self.airBitAnd(inst),553 .bit_and => try self.airBinOp(inst),
554 .bit_or => try self.airBitOr(inst),554 .bit_or => try self.airBinOp(inst),
555 .xor => try self.airXor(inst),555 .xor => try self.airBinOp(inst),
556 .shr, .shr_exact => try self.airShr(inst),556 .shr, .shr_exact => try self.airShr(inst),
557557
558 .alloc => try self.airAlloc(inst),558 .alloc => try self.airAlloc(inst),
...@@ -1029,24 +1029,6 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void {...@@ -1029,24 +1029,6 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void {
1029 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });1029 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1030}1030}
10311031
1032fn airBitAnd(self: *Self, inst: Air.Inst.Index) !void {
1033 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1034 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else try self.genBinOp(inst, bin_op.lhs, bin_op.rhs, .bit_and);
1035 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1036}
1037
1038fn airBitOr(self: *Self, inst: Air.Inst.Index) !void {
1039 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1040 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else try self.genBinOp(inst, bin_op.lhs, bin_op.rhs, .bit_or);
1041 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1042}
1043
1044fn airXor(self: *Self, inst: Air.Inst.Index) !void {
1045 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1046 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else try self.genBinOp(inst, bin_op.lhs, bin_op.rhs, .xor);
1047 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1048}
1049
1050fn airShl(self: *Self, inst: Air.Inst.Index) !void {1032fn airShl(self: *Self, inst: Air.Inst.Index) !void {
1051 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1033 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1052 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else try self.genBinOp(inst, bin_op.lhs, bin_op.rhs, .shl);1034 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else try self.genBinOp(inst, bin_op.lhs, bin_op.rhs, .shl);
...@@ -1770,11 +1752,23 @@ fn binOpRegister(...@@ -1770,11 +1752,23 @@ fn binOpRegister(
1770 .add, .ptr_add => .add,1752 .add, .ptr_add => .add,
1771 .sub, .ptr_sub => .sub,1753 .sub, .ptr_sub => .sub,
1772 .mul => .mul,1754 .mul => .mul,
1755 .bit_and,
1756 .bool_and,
1757 => .@"and",
1758 .bit_or,
1759 .bool_or,
1760 => .orr,
1761 .xor => .eor,
1773 else => unreachable,1762 else => unreachable,
1774 };1763 };
1775 const mir_data: Mir.Inst.Data = switch (tag) {1764 const mir_data: Mir.Inst.Data = switch (tag) {
1776 .add,1765 .add,
1777 .sub,1766 .sub,
1767 .bit_and,
1768 .bool_and,
1769 .bit_or,
1770 .bool_or,
1771 .xor,
1778 .ptr_add,1772 .ptr_add,
1779 .ptr_sub,1773 .ptr_sub,
1780 => .{ .rr_op = .{1774 => .{ .rr_op = .{
...@@ -1862,11 +1856,23 @@ fn binOpImmediate(...@@ -1862,11 +1856,23 @@ fn binOpImmediate(
1862 const mir_tag: Mir.Inst.Tag = switch (tag) {1856 const mir_tag: Mir.Inst.Tag = switch (tag) {
1863 .add => .add,1857 .add => .add,
1864 .sub => .sub,1858 .sub => .sub,
1859 .bit_and,
1860 .bool_and,
1861 => .@"and",
1862 .bit_or,
1863 .bool_or,
1864 => .orr,
1865 .xor => .eor,
1865 else => unreachable,1866 else => unreachable,
1866 };1867 };
1867 const mir_data: Mir.Inst.Data = switch (tag) {1868 const mir_data: Mir.Inst.Data = switch (tag) {
1868 .add,1869 .add,
1869 .sub,1870 .sub,
1871 .bit_and,
1872 .bool_and,
1873 .bit_or,
1874 .bool_or,
1875 .xor,
1870 => .{ .rr_op = .{1876 => .{ .rr_op = .{
1871 .rd = dest_reg,1877 .rd = dest_reg,
1872 .rn = lhs_reg,1878 .rn = lhs_reg,
...@@ -1964,6 +1970,54 @@ fn binOp(...@@ -1964,6 +1970,54 @@ fn binOp(
1964 else => unreachable,1970 else => unreachable,
1965 }1971 }
1966 },1972 },
1973 .bit_and,
1974 .bit_or,
1975 .xor,
1976 => {
1977 switch (lhs_ty.zigTypeTag()) {
1978 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
1979 .Int => {
1980 assert(lhs_ty.eql(rhs_ty));
1981 const int_info = lhs_ty.intInfo(self.target.*);
1982 if (int_info.bits <= 32) {
1983 const lhs_immediate_ok = lhs == .immediate and Instruction.Operand.fromU32(lhs.immediate) != null;
1984 const rhs_immediate_ok = rhs == .immediate and Instruction.Operand.fromU32(rhs.immediate) != null;
1985
1986 if (rhs_immediate_ok) {
1987 return try self.binOpImmediate(tag, maybe_inst, lhs, rhs, lhs_ty, false);
1988 } else if (lhs_immediate_ok) {
1989 // swap lhs and rhs
1990 return try self.binOpImmediate(tag, maybe_inst, rhs, lhs, rhs_ty, true);
1991 } else {
1992 return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
1993 }
1994 } else {
1995 return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
1996 }
1997 },
1998 else => unreachable,
1999 }
2000 },
2001 .bool_and,
2002 .bool_or,
2003 => {
2004 switch (lhs_ty.zigTypeTag()) {
2005 .Bool => {
2006 const lhs_immediate_ok = lhs == .immediate;
2007 const rhs_immediate_ok = rhs == .immediate;
2008
2009 if (rhs_immediate_ok) {
2010 return try self.binOpImmediate(tag, maybe_inst, lhs, rhs, lhs_ty, false);
2011 } else if (lhs_immediate_ok) {
2012 // swap lhs and rhs
2013 return try self.binOpImmediate(tag, maybe_inst, rhs, lhs, rhs_ty, true);
2014 } else {
2015 return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
2016 }
2017 },
2018 else => unreachable,
2019 }
2020 },
1967 .ptr_add,2021 .ptr_add,
1968 .ptr_sub,2022 .ptr_sub,
1969 => {2023 => {
...@@ -2183,17 +2237,9 @@ fn genBinOpCode(...@@ -2183,17 +2237,9 @@ fn genBinOpCode(
2183 };2237 };
21842238
2185 switch (op) {2239 switch (op) {
2186 .bool_and,2240 .not => {
2187 .bit_and,
2188 .bool_or,
2189 .bit_or,
2190 .not,
2191 .xor,
2192 => {
2193 const tag: Mir.Inst.Tag = switch (op) {2241 const tag: Mir.Inst.Tag = switch (op) {
2194 .bool_and, .bit_and => .@"and",2242 .not => .eor,
2195 .bool_or, .bit_or => .orr,
2196 .not, .xor => .eor,
2197 else => unreachable,2243 else => unreachable,
2198 };2244 };
21992245
...@@ -3154,17 +3200,6 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {...@@ -3154,17 +3200,6 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {
3154 return self.finishAir(inst, .dead, .{ branch.operand, .none, .none });3200 return self.finishAir(inst, .dead, .{ branch.operand, .none, .none });
3155}3201}
31563202
3157fn airBoolOp(self: *Self, inst: Air.Inst.Index) !void {
3158 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
3159 const air_tags = self.air.instructions.items(.tag);
3160 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else switch (air_tags[inst]) {
3161 .bool_and => try self.genBinOp(inst, bin_op.lhs, bin_op.rhs, .bool_and),
3162 .bool_or => try self.genBinOp(inst, bin_op.lhs, bin_op.rhs, .bool_or),
3163 else => unreachable, // Not a boolean operation
3164 };
3165 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
3166}
3167
3168fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {3203fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
3169 const block_data = self.blocks.getPtr(block).?;3204 const block_data = self.blocks.getPtr(block).?;
31703205