aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoakuma <koachan@protonmail.com>2022-06-02 23:45:52 +0700
committerKoakuma <koachan@protonmail.com>2022-06-06 20:34:53 +0700
commitf87dd285bbbea90ee186550e5ca64b743b05451d (patch)
tree6cda091842e360fc831c5bdc29c11d56d2f7bbea
parent31f24dbc5544fbebbd6259ee272aa9a7244b4d87 (diff)
downloadzig-f87dd285bbbea90ee186550e5ca64b743b05451d.tar.gz
zig-f87dd285bbbea90ee186550e5ca64b743b05451d.zip
stage2: sparc64: binOp/mul: Use template from `add`
-rw-r--r--src/arch/sparc64/CodeGen.zig41
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", .{});
}