Commit 6218d70d09

Koakuma <koachan@protonmail.com>
2022-06-15 18:23:38
stage2: sparc64: Implement airBinOp for and, or, and xor
1 parent 921f776
Changed files (3)
src/arch/sparc64/CodeGen.zig
@@ -563,9 +563,9 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
 
             .bool_and        => @panic("TODO try self.airBoolOp(inst)"),
             .bool_or         => @panic("TODO try self.airBoolOp(inst)"),
-            .bit_and         => @panic("TODO try self.airBitAnd(inst)"),
-            .bit_or          => @panic("TODO try self.airBitOr(inst)"),
-            .xor             => @panic("TODO try self.airXor(inst)"),
+            .bit_and         => try self.airBinOp(inst, .bit_and),
+            .bit_or          => try self.airBinOp(inst, .bit_or),
+            .xor             => try self.airBinOp(inst, .xor),
             .shr, .shr_exact => @panic("TODO try self.airShr(inst)"),
 
             .alloc           => try self.airAlloc(inst),
@@ -2093,6 +2093,58 @@ fn binOp(
             }
         },
 
+        .bit_and,
+        .bit_or,
+        .xor,
+        => {
+            switch (lhs_ty.zigTypeTag()) {
+                .Vector => return self.fail("TODO binary operations on vectors", .{}),
+                .Int => {
+                    assert(lhs_ty.eql(rhs_ty, mod));
+                    const int_info = lhs_ty.intInfo(self.target.*);
+                    if (int_info.bits <= 64) {
+                        // Only say yes if the operation is
+                        // commutative, i.e. we can swap both of the
+                        // operands
+                        const lhs_immediate_ok = switch (tag) {
+                            .bit_and,
+                            .bit_or,
+                            .xor,
+                            => lhs == .immediate and lhs.immediate <= std.math.maxInt(u13),
+                            else => unreachable,
+                        };
+                        const rhs_immediate_ok = switch (tag) {
+                            .bit_and,
+                            .bit_or,
+                            .xor,
+                            => rhs == .immediate and rhs.immediate <= std.math.maxInt(u13),
+                            else => unreachable,
+                        };
+
+                        const mir_tag: Mir.Inst.Tag = switch (tag) {
+                            .bit_and => .@"and",
+                            .bit_or => .@"or",
+                            .xor => .xor,
+                            else => unreachable,
+                        };
+
+                        if (rhs_immediate_ok) {
+                            return try self.binOpImmediate(mir_tag, lhs, rhs, lhs_ty, false, metadata);
+                        } else if (lhs_immediate_ok) {
+                            // swap lhs and rhs
+                            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", .{});
+                    }
+                },
+                else => unreachable,
+            }
+        },
+
         .shl => {
             const base_tag: Air.Inst.Tag = switch (tag) {
                 .shl => .shl_exact,
@@ -2221,6 +2273,10 @@ fn binOpImmediate(
     const mir_data: Mir.Inst.Data = switch (mir_tag) {
         .add,
         .addcc,
+        .@"and",
+        .@"or",
+        .xor,
+        .xnor,
         .mulx,
         .subcc,
         => .{
@@ -2339,6 +2395,10 @@ fn binOpRegister(
     const mir_data: Mir.Inst.Data = switch (mir_tag) {
         .add,
         .addcc,
+        .@"and",
+        .@"or",
+        .xor,
+        .xnor,
         .mulx,
         .subcc,
         => .{
src/arch/sparc64/Emit.zig
@@ -93,6 +93,7 @@ pub fn emitMir(
             .lduw => try emit.mirArithmetic3Op(inst),
             .ldx => try emit.mirArithmetic3Op(inst),
 
+            .@"and" => @panic("TODO implement sparc64 and"),
             .@"or" => try emit.mirArithmetic3Op(inst),
             .xor => try emit.mirArithmetic3Op(inst),
             .xnor => try emit.mirArithmetic3Op(inst),
src/arch/sparc64/Mir.zig
@@ -73,6 +73,7 @@ pub const Inst = struct {
         /// A.31 Logical Operations
         /// This uses the arithmetic_3op field.
         // TODO add other operations.
+        @"and",
         @"or",
         xor,
         xnor,