authorgravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-06-15 23:23:38+07:00
committergravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-06-24 21:19:33+07:00
log6218d70d09cf60e3c1d83cdd5b49ea9eed3d5259
tree3cbac22b8594fb5e72e42f3da908d8feab7094d0
parent921f77622492bce8995ac61bdfcf4b46c44865a2

stage2: sparc64: Implement airBinOp for and, or, and xor


3 files changed, 65 insertions(+), 3 deletions(-)

src/arch/sparc64/CodeGen.zig+63-3
......@@ -563,9 +563,9 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
563563
564564 .bool_and => @panic("TODO try self.airBoolOp(inst)"),
565565 .bool_or => @panic("TODO try self.airBoolOp(inst)"),
566 .bit_and => @panic("TODO try self.airBitAnd(inst)"),
567 .bit_or => @panic("TODO try self.airBitOr(inst)"),
568 .xor => @panic("TODO try self.airXor(inst)"),
566 .bit_and => try self.airBinOp(inst, .bit_and),
567 .bit_or => try self.airBinOp(inst, .bit_or),
568 .xor => try self.airBinOp(inst, .xor),
569569 .shr, .shr_exact => @panic("TODO try self.airShr(inst)"),
570570
571571 .alloc => try self.airAlloc(inst),
......@@ -2093,6 +2093,58 @@ fn binOp(
20932093 }
20942094 },
20952095
2096 .bit_and,
2097 .bit_or,
2098 .xor,
2099 => {
2100 switch (lhs_ty.zigTypeTag()) {
2101 .Vector => return self.fail("TODO binary operations on vectors", .{}),
2102 .Int => {
2103 assert(lhs_ty.eql(rhs_ty, mod));
2104 const int_info = lhs_ty.intInfo(self.target.*);
2105 if (int_info.bits <= 64) {
2106 // Only say yes if the operation is
2107 // commutative, i.e. we can swap both of the
2108 // operands
2109 const lhs_immediate_ok = switch (tag) {
2110 .bit_and,
2111 .bit_or,
2112 .xor,
2113 => lhs == .immediate and lhs.immediate <= std.math.maxInt(u13),
2114 else => unreachable,
2115 };
2116 const rhs_immediate_ok = switch (tag) {
2117 .bit_and,
2118 .bit_or,
2119 .xor,
2120 => rhs == .immediate and rhs.immediate <= std.math.maxInt(u13),
2121 else => unreachable,
2122 };
2123
2124 const mir_tag: Mir.Inst.Tag = switch (tag) {
2125 .bit_and => .@"and",
2126 .bit_or => .@"or",
2127 .xor => .xor,
2128 else => unreachable,
2129 };
2130
2131 if (rhs_immediate_ok) {
2132 return try self.binOpImmediate(mir_tag, lhs, rhs, lhs_ty, false, metadata);
2133 } else if (lhs_immediate_ok) {
2134 // swap lhs and rhs
2135 return try self.binOpImmediate(mir_tag, rhs, lhs, rhs_ty, true, metadata);
2136 } else {
2137 // TODO convert large immediates to register before adding
2138 return try self.binOpRegister(mir_tag, lhs, rhs, lhs_ty, rhs_ty, metadata);
2139 }
2140 } else {
2141 return self.fail("TODO binary operations on int with bits > 64", .{});
2142 }
2143 },
2144 else => unreachable,
2145 }
2146 },
2147
20962148 .shl => {
20972149 const base_tag: Air.Inst.Tag = switch (tag) {
20982150 .shl => .shl_exact,
......@@ -2221,6 +2273,10 @@ fn binOpImmediate(
22212273 const mir_data: Mir.Inst.Data = switch (mir_tag) {
22222274 .add,
22232275 .addcc,
2276 .@"and",
2277 .@"or",
2278 .xor,
2279 .xnor,
22242280 .mulx,
22252281 .subcc,
22262282 => .{
......@@ -2339,6 +2395,10 @@ fn binOpRegister(
23392395 const mir_data: Mir.Inst.Data = switch (mir_tag) {
23402396 .add,
23412397 .addcc,
2398 .@"and",
2399 .@"or",
2400 .xor,
2401 .xnor,
23422402 .mulx,
23432403 .subcc,
23442404 => .{
src/arch/sparc64/Emit.zig+1
......@@ -93,6 +93,7 @@ pub fn emitMir(
9393 .lduw => try emit.mirArithmetic3Op(inst),
9494 .ldx => try emit.mirArithmetic3Op(inst),
9595
96 .@"and" => @panic("TODO implement sparc64 and"),
9697 .@"or" => try emit.mirArithmetic3Op(inst),
9798 .xor => try emit.mirArithmetic3Op(inst),
9899 .xnor => try emit.mirArithmetic3Op(inst),
src/arch/sparc64/Mir.zig+1
......@@ -73,6 +73,7 @@ pub const Inst = struct {
7373 /// A.31 Logical Operations
7474 /// This uses the arithmetic_3op field.
7575 // TODO add other operations.
76 @"and",
7677 @"or",
7778 xor,
7879 xnor,