| ... | ... | @@ -563,9 +563,9 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 563 | 563 | |
| 564 | 564 | .bool_and => @panic("TODO try self.airBoolOp(inst)"), |
| 565 | 565 | .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), |
| 569 | 569 | .shr, .shr_exact => @panic("TODO try self.airShr(inst)"), |
| 570 | 570 | |
| 571 | 571 | .alloc => try self.airAlloc(inst), |
| ... | ... | @@ -2093,6 +2093,58 @@ fn binOp( |
| 2093 | 2093 | } |
| 2094 | 2094 | }, |
| 2095 | 2095 | |
| 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 | 2148 | .shl => { |
| 2097 | 2149 | const base_tag: Air.Inst.Tag = switch (tag) { |
| 2098 | 2150 | .shl => .shl_exact, |
| ... | ... | @@ -2221,6 +2273,10 @@ fn binOpImmediate( |
| 2221 | 2273 | const mir_data: Mir.Inst.Data = switch (mir_tag) { |
| 2222 | 2274 | .add, |
| 2223 | 2275 | .addcc, |
| 2276 | .@"and", |
| 2277 | .@"or", |
| 2278 | .xor, |
| 2279 | .xnor, |
| 2224 | 2280 | .mulx, |
| 2225 | 2281 | .subcc, |
| 2226 | 2282 | => .{ |
| ... | ... | @@ -2339,6 +2395,10 @@ fn binOpRegister( |
| 2339 | 2395 | const mir_data: Mir.Inst.Data = switch (mir_tag) { |
| 2340 | 2396 | .add, |
| 2341 | 2397 | .addcc, |
| 2398 | .@"and", |
| 2399 | .@"or", |
| 2400 | .xor, |
| 2401 | .xnor, |
| 2342 | 2402 | .mulx, |
| 2343 | 2403 | .subcc, |
| 2344 | 2404 | => .{ |