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 {
548548 .cmp_gt => try self.airCmp(inst, .gt),
549549 .cmp_neq => try self.airCmp(inst, .neq),
550550
551 .bool_and => try self.airBoolOp(inst),
552 .bool_or => try self.airBoolOp(inst),
553 .bit_and => try self.airBitAnd(inst),
554 .bit_or => try self.airBitOr(inst),
555 .xor => try self.airXor(inst),
551 .bool_and => try self.airBinOp(inst),
552 .bool_or => try self.airBinOp(inst),
553 .bit_and => try self.airBinOp(inst),
554 .bit_or => try self.airBinOp(inst),
555 .xor => try self.airBinOp(inst),
556556 .shr, .shr_exact => try self.airShr(inst),
557557
558558 .alloc => try self.airAlloc(inst),
......@@ -1029,24 +1029,6 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void {
10291029 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
10301030}
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
10501032fn airShl(self: *Self, inst: Air.Inst.Index) !void {
10511033 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
10521034 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(
17701752 .add, .ptr_add => .add,
17711753 .sub, .ptr_sub => .sub,
17721754 .mul => .mul,
1755 .bit_and,
1756 .bool_and,
1757 => .@"and",
1758 .bit_or,
1759 .bool_or,
1760 => .orr,
1761 .xor => .eor,
17731762 else => unreachable,
17741763 };
17751764 const mir_data: Mir.Inst.Data = switch (tag) {
17761765 .add,
17771766 .sub,
1767 .bit_and,
1768 .bool_and,
1769 .bit_or,
1770 .bool_or,
1771 .xor,
17781772 .ptr_add,
17791773 .ptr_sub,
17801774 => .{ .rr_op = .{
......@@ -1862,11 +1856,23 @@ fn binOpImmediate(
18621856 const mir_tag: Mir.Inst.Tag = switch (tag) {
18631857 .add => .add,
18641858 .sub => .sub,
1859 .bit_and,
1860 .bool_and,
1861 => .@"and",
1862 .bit_or,
1863 .bool_or,
1864 => .orr,
1865 .xor => .eor,
18651866 else => unreachable,
18661867 };
18671868 const mir_data: Mir.Inst.Data = switch (tag) {
18681869 .add,
18691870 .sub,
1871 .bit_and,
1872 .bool_and,
1873 .bit_or,
1874 .bool_or,
1875 .xor,
18701876 => .{ .rr_op = .{
18711877 .rd = dest_reg,
18721878 .rn = lhs_reg,
......@@ -1964,6 +1970,54 @@ fn binOp(
19641970 else => unreachable,
19651971 }
19661972 },
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 },
19672021 .ptr_add,
19682022 .ptr_sub,
19692023 => {
......@@ -2183,17 +2237,9 @@ fn genBinOpCode(
21832237 };
21842238
21852239 switch (op) {
2186 .bool_and,
2187 .bit_and,
2188 .bool_or,
2189 .bit_or,
2190 .not,
2191 .xor,
2192 => {
2240 .not => {
21932241 const tag: Mir.Inst.Tag = switch (op) {
2194 .bool_and, .bit_and => .@"and",
2195 .bool_or, .bit_or => .orr,
2196 .not, .xor => .eor,
2242 .not => .eor,
21972243 else => unreachable,
21982244 };
21992245
......@@ -3154,17 +3200,6 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {
31543200 return self.finishAir(inst, .dead, .{ branch.operand, .none, .none });
31553201}
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
31683203fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
31693204 const block_data = self.blocks.getPtr(block).?;
31703205