diff options
| author | Koakuma <koachan@protonmail.com> | 2022-06-02 23:45:52 +0700 |
|---|---|---|
| committer | Koakuma <koachan@protonmail.com> | 2022-06-06 20:34:53 +0700 |
| commit | f87dd285bbbea90ee186550e5ca64b743b05451d (patch) | |
| tree | 6cda091842e360fc831c5bdc29c11d56d2f7bbea | |
| parent | 31f24dbc5544fbebbd6259ee272aa9a7244b4d87 (diff) | |
| download | zig-f87dd285bbbea90ee186550e5ca64b743b05451d.tar.gz zig-f87dd285bbbea90ee186550e5ca64b743b05451d.zip | |
stage2: sparc64: binOp/mul: Use template from `add`
| -rw-r--r-- | src/arch/sparc64/CodeGen.zig | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig index 0cab96d609..2b6945810c 100644 --- a/src/arch/sparc64/CodeGen.zig +++ b/src/arch/sparc64/CodeGen.zig @@ -2036,21 +2036,34 @@ fn binOp( assert(lhs_ty.eql(rhs_ty, mod)); const int_info = lhs_ty.intInfo(self.target.*); if (int_info.bits <= 64) { - // If LHS is immediate, then swap it with RHS. - const lhs_is_imm = lhs == .immediate; - const new_lhs = if (lhs_is_imm) rhs else lhs; - const new_rhs = if (lhs_is_imm) lhs else rhs; - const new_lhs_ty = if (lhs_is_imm) rhs_ty else lhs_ty; - const new_rhs_ty = if (lhs_is_imm) lhs_ty else rhs_ty; - - // At this point, RHS might be an immediate - // If it's a power of two immediate then we emit an shl instead - // TODO add similar checks for LHS - if (new_rhs == .immediate and math.isPowerOfTwo(new_rhs.immediate)) { - return try self.binOp(.shl, new_lhs, .{ .immediate = math.log2(new_rhs.immediate) }, new_lhs_ty, Type.usize, metadata); - } + // Only say yes if the operation is + // commutative, i.e. we can swap both of the + // operands + const lhs_immediate_ok = switch (tag) { + .mul => lhs == .immediate and lhs.immediate <= std.math.maxInt(u12), + else => unreachable, + }; + const rhs_immediate_ok = switch (tag) { + .mul => rhs == .immediate and rhs.immediate <= std.math.maxInt(u12), + else => unreachable, + }; - return try self.binOpRegister(.mulx, new_lhs, new_rhs, new_lhs_ty, new_rhs_ty, metadata); + const mir_tag: Mir.Inst.Tag = switch (tag) { + .mul => .mulx, + else => unreachable, + }; + + if (rhs_immediate_ok) { + // At this point, rhs is an immediate + return try self.binOpImmediate(mir_tag, lhs, rhs, lhs_ty, false, metadata); + } else if (lhs_immediate_ok) { + // swap lhs and rhs + // At this point, lhs is an immediate + return try self.binOpImmediate(mir_tag, rhs, lhs, rhs_ty, true, metadata); + } else { + // TODO convert large immediates to register before adding + return try self.binOpRegister(mir_tag, lhs, rhs, lhs_ty, rhs_ty, metadata); + } } else { return self.fail("TODO binary operations on int with bits > 64", .{}); } |
