Commit 75a1360cdd

Koakuma <koachan@protonmail.com>
2023-02-20 16:40:08
stage2: sparc64: Implement ASI load/store ops
1 parent 83e6223
Changed files (3)
src/arch/sparc64/bits.zig
@@ -1229,6 +1229,22 @@ pub const Instruction = union(enum) {
         };
     }
 
+    pub fn lduba(rs1: Register, rs2: Register, asi: ASI, rd: Register) Instruction {
+        return format3i(0b11, 0b01_0001, rs1, rs2, rd, asi);
+    }
+
+    pub fn lduha(rs1: Register, rs2: Register, asi: ASI, rd: Register) Instruction {
+        return format3i(0b11, 0b01_0010, rs1, rs2, rd, asi);
+    }
+
+    pub fn lduwa(rs1: Register, rs2: Register, asi: ASI, rd: Register) Instruction {
+        return format3i(0b11, 0b01_0000, rs1, rs2, rd, asi);
+    }
+
+    pub fn ldxa(rs1: Register, rs2: Register, asi: ASI, rd: Register) Instruction {
+        return format3i(0b11, 0b01_1011, rs1, rs2, rd, asi);
+    }
+
     pub fn @"and"(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
         return switch (s2) {
             Register => format3a(0b10, 0b00_0001, rs1, rs2, rd),
@@ -1417,6 +1433,22 @@ pub const Instruction = union(enum) {
         };
     }
 
+    pub fn stba(rs1: Register, rs2: Register, asi: ASI, rd: Register) Instruction {
+        return format3i(0b11, 0b01_0101, rs1, rs2, rd, asi);
+    }
+
+    pub fn stha(rs1: Register, rs2: Register, asi: ASI, rd: Register) Instruction {
+        return format3i(0b11, 0b01_0110, rs1, rs2, rd, asi);
+    }
+
+    pub fn stwa(rs1: Register, rs2: Register, asi: ASI, rd: Register) Instruction {
+        return format3i(0b11, 0b01_0100, rs1, rs2, rd, asi);
+    }
+
+    pub fn stxa(rs1: Register, rs2: Register, asi: ASI, rd: Register) Instruction {
+        return format3i(0b11, 0b01_1110, rs1, rs2, rd, asi);
+    }
+
     pub fn sub(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
         return switch (s2) {
             Register => format3a(0b10, 0b00_0100, rs1, rs2, rd),
src/arch/sparc64/CodeGen.zig
@@ -1254,7 +1254,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
 
                         try self.genStoreASI(reg, .sp, off_reg, abi_size, opposite_endian_asi);
                         try self.genLoad(reg, .sp, Register, off_reg, abi_size);
-                        break :result reg;
+                        break :result .{ .register = reg };
                     },
                     .memory => {
                         if (int_info.bits > 64 or @popCount(int_info.bits) != 1)
@@ -1264,7 +1264,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
                         const dst_reg = try self.register_manager.allocReg(null, gp);
 
                         try self.genLoadASI(dst_reg, addr_reg, .g0, abi_size, opposite_endian_asi);
-                        break :result dst_reg;
+                        break :result .{ .register = dst_reg };
                     },
                     .stack_offset => |off| {
                         if (int_info.bits > 64 or @popCount(int_info.bits) != 1)
@@ -1274,7 +1274,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
                         const dst_reg = try self.register_manager.allocReg(null, gp);
 
                         try self.genLoadASI(dst_reg, .sp, off_reg, abi_size, opposite_endian_asi);
-                        break :result dst_reg;
+                        break :result .{ .register = dst_reg };
                     },
                     else => unreachable,
                 }
src/arch/sparc64/Emit.zig
@@ -91,10 +91,10 @@ pub fn emitMir(
             .lduw => try emit.mirArithmetic3Op(inst),
             .ldx => try emit.mirArithmetic3Op(inst),
 
-            .lduba => unreachable,
-            .lduha => unreachable,
-            .lduwa => unreachable,
-            .ldxa => unreachable,
+            .lduba => try emit.mirMemASI(inst),
+            .lduha => try emit.mirMemASI(inst),
+            .lduwa => try emit.mirMemASI(inst),
+            .ldxa => try emit.mirMemASI(inst),
 
             .@"and" => try emit.mirArithmetic3Op(inst),
             .@"or" => try emit.mirArithmetic3Op(inst),
@@ -132,10 +132,10 @@ pub fn emitMir(
             .stw => try emit.mirArithmetic3Op(inst),
             .stx => try emit.mirArithmetic3Op(inst),
 
-            .stba => unreachable,
-            .stha => unreachable,
-            .stwa => unreachable,
-            .stxa => unreachable,
+            .stba => try emit.mirMemASI(inst),
+            .stha => try emit.mirMemASI(inst),
+            .stwa => try emit.mirMemASI(inst),
+            .stxa => try emit.mirMemASI(inst),
 
             .sub => try emit.mirArithmetic3Op(inst),
             .subcc => try emit.mirArithmetic3Op(inst),
@@ -378,6 +378,29 @@ fn mirConditionalMove(emit: *Emit, inst: Mir.Inst.Index) !void {
     }
 }
 
+fn mirMemASI(emit: *Emit, inst: Mir.Inst.Index) !void {
+    const tag = emit.mir.instructions.items(.tag)[inst];
+    const data = emit.mir.instructions.items(.data)[inst].mem_asi;
+
+    const rd = data.rd;
+    const rs1 = data.rs1;
+    const rs2 = data.rs2;
+    const asi = data.asi;
+
+    switch (tag) {
+        .lduba => try emit.writeInstruction(Instruction.lduba(rs1, rs2, asi, rd)),
+        .lduha => try emit.writeInstruction(Instruction.lduha(rs1, rs2, asi, rd)),
+        .lduwa => try emit.writeInstruction(Instruction.lduwa(rs1, rs2, asi, rd)),
+        .ldxa => try emit.writeInstruction(Instruction.ldxa(rs1, rs2, asi, rd)),
+
+        .stba => try emit.writeInstruction(Instruction.stba(rs1, rs2, asi, rd)),
+        .stha => try emit.writeInstruction(Instruction.stha(rs1, rs2, asi, rd)),
+        .stwa => try emit.writeInstruction(Instruction.stwa(rs1, rs2, asi, rd)),
+        .stxa => try emit.writeInstruction(Instruction.stxa(rs1, rs2, asi, rd)),
+        else => unreachable,
+    }
+}
+
 fn mirMembar(emit: *Emit, inst: Mir.Inst.Index) !void {
     const tag = emit.mir.instructions.items(.tag)[inst];
     const mask = emit.mir.instructions.items(.data)[inst].membar_mask;