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 {...@@ -563,9 +563,9 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
563563
564 .bool_and => @panic("TODO try self.airBoolOp(inst)"),564 .bool_and => @panic("TODO try self.airBoolOp(inst)"),
565 .bool_or => @panic("TODO try self.airBoolOp(inst)"),565 .bool_or => @panic("TODO try self.airBoolOp(inst)"),
566 .bit_and => @panic("TODO try self.airBitAnd(inst)"),566 .bit_and => try self.airBinOp(inst, .bit_and),
567 .bit_or => @panic("TODO try self.airBitOr(inst)"),567 .bit_or => try self.airBinOp(inst, .bit_or),
568 .xor => @panic("TODO try self.airXor(inst)"),568 .xor => try self.airBinOp(inst, .xor),
569 .shr, .shr_exact => @panic("TODO try self.airShr(inst)"),569 .shr, .shr_exact => @panic("TODO try self.airShr(inst)"),
570570
571 .alloc => try self.airAlloc(inst),571 .alloc => try self.airAlloc(inst),
...@@ -2093,6 +2093,58 @@ fn binOp(...@@ -2093,6 +2093,58 @@ fn binOp(
2093 }2093 }
2094 },2094 },
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
2096 .shl => {2148 .shl => {
2097 const base_tag: Air.Inst.Tag = switch (tag) {2149 const base_tag: Air.Inst.Tag = switch (tag) {
2098 .shl => .shl_exact,2150 .shl => .shl_exact,
...@@ -2221,6 +2273,10 @@ fn binOpImmediate(...@@ -2221,6 +2273,10 @@ fn binOpImmediate(
2221 const mir_data: Mir.Inst.Data = switch (mir_tag) {2273 const mir_data: Mir.Inst.Data = switch (mir_tag) {
2222 .add,2274 .add,
2223 .addcc,2275 .addcc,
2276 .@"and",
2277 .@"or",
2278 .xor,
2279 .xnor,
2224 .mulx,2280 .mulx,
2225 .subcc,2281 .subcc,
2226 => .{2282 => .{
...@@ -2339,6 +2395,10 @@ fn binOpRegister(...@@ -2339,6 +2395,10 @@ fn binOpRegister(
2339 const mir_data: Mir.Inst.Data = switch (mir_tag) {2395 const mir_data: Mir.Inst.Data = switch (mir_tag) {
2340 .add,2396 .add,
2341 .addcc,2397 .addcc,
2398 .@"and",
2399 .@"or",
2400 .xor,
2401 .xnor,
2342 .mulx,2402 .mulx,
2343 .subcc,2403 .subcc,
2344 => .{2404 => .{
src/arch/sparc64/Emit.zig+1
...@@ -93,6 +93,7 @@ pub fn emitMir(...@@ -93,6 +93,7 @@ pub fn emitMir(
93 .lduw => try emit.mirArithmetic3Op(inst),93 .lduw => try emit.mirArithmetic3Op(inst),
94 .ldx => try emit.mirArithmetic3Op(inst),94 .ldx => try emit.mirArithmetic3Op(inst),
9595
96 .@"and" => @panic("TODO implement sparc64 and"),
96 .@"or" => try emit.mirArithmetic3Op(inst),97 .@"or" => try emit.mirArithmetic3Op(inst),
97 .xor => try emit.mirArithmetic3Op(inst),98 .xor => try emit.mirArithmetic3Op(inst),
98 .xnor => try emit.mirArithmetic3Op(inst),99 .xnor => try emit.mirArithmetic3Op(inst),
src/arch/sparc64/Mir.zig+1
...@@ -73,6 +73,7 @@ pub const Inst = struct {...@@ -73,6 +73,7 @@ pub const Inst = struct {
73 /// A.31 Logical Operations73 /// A.31 Logical Operations
74 /// This uses the arithmetic_3op field.74 /// This uses the arithmetic_3op field.
75 // TODO add other operations.75 // TODO add other operations.
76 @"and",
76 @"or",77 @"or",
77 xor,78 xor,
78 xnor,79 xnor,