From 4d50e52c37cad45bd3d8fd520359cdaee70aaf1f Mon Sep 17 00:00:00 2001 From: Koakuma Date: Wed, 1 Jun 2022 19:29:09 +0700 Subject: [PATCH] stage2: sparc64: Implement SPARCv9 xor, xnor, & not --- src/arch/sparc64/Emit.zig | 12 +++++++++--- src/arch/sparc64/bits.zig | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/arch/sparc64/Emit.zig b/src/arch/sparc64/Emit.zig index 2fcb593585..5a082f163a 100644 --- a/src/arch/sparc64/Emit.zig +++ b/src/arch/sparc64/Emit.zig @@ -94,8 +94,8 @@ pub fn emitMir( .ldx => try emit.mirArithmetic3Op(inst), .@"or" => try emit.mirArithmetic3Op(inst), - .xor => @panic("TODO implement sparc64 xor"), - .xnor => @panic("TODO implement sparc64 xnor"), + .xor => try emit.mirArithmetic3Op(inst), + .xnor => try emit.mirArithmetic3Op(inst), .movcc => try emit.mirConditionalMove(inst), @@ -131,7 +131,7 @@ pub fn emitMir( .mov => try emit.mirArithmetic2Op(inst), - .not => @panic("TODO implement sparc64 not"), + .not => try emit.mirArithmetic2Op(inst), } } } @@ -192,6 +192,7 @@ fn mirArithmetic2Op(emit: *Emit, inst: Mir.Inst.Index) !void { .@"return" => try emit.writeInstruction(Instruction.@"return"(i13, rs1, imm)), .cmp => try emit.writeInstruction(Instruction.subcc(i13, rs1, imm, .g0)), .mov => try emit.writeInstruction(Instruction.@"or"(i13, .g0, imm, rs1)), + .not => try emit.writeInstruction(Instruction.xnor(i13, .g0, imm, rs1)), else => unreachable, } } else { @@ -200,6 +201,7 @@ fn mirArithmetic2Op(emit: *Emit, inst: Mir.Inst.Index) !void { .@"return" => try emit.writeInstruction(Instruction.@"return"(Register, rs1, rs2)), .cmp => try emit.writeInstruction(Instruction.subcc(Register, rs1, rs2, .g0)), .mov => try emit.writeInstruction(Instruction.@"or"(Register, .g0, rs2, rs1)), + .not => try emit.writeInstruction(Instruction.xnor(Register, .g0, rs2, rs1)), else => unreachable, } } @@ -223,6 +225,8 @@ fn mirArithmetic3Op(emit: *Emit, inst: Mir.Inst.Index) !void { .lduw => try emit.writeInstruction(Instruction.lduw(i13, rs1, imm, rd)), .ldx => try emit.writeInstruction(Instruction.ldx(i13, rs1, imm, rd)), .@"or" => try emit.writeInstruction(Instruction.@"or"(i13, rs1, imm, rd)), + .xor => try emit.writeInstruction(Instruction.xor(i13, rs1, imm, rd)), + .xnor => try emit.writeInstruction(Instruction.xnor(i13, rs1, imm, rd)), .mulx => try emit.writeInstruction(Instruction.mulx(i13, rs1, imm, rd)), .save => try emit.writeInstruction(Instruction.save(i13, rs1, imm, rd)), .restore => try emit.writeInstruction(Instruction.restore(i13, rs1, imm, rd)), @@ -245,6 +249,8 @@ fn mirArithmetic3Op(emit: *Emit, inst: Mir.Inst.Index) !void { .lduw => try emit.writeInstruction(Instruction.lduw(Register, rs1, rs2, rd)), .ldx => try emit.writeInstruction(Instruction.ldx(Register, rs1, rs2, rd)), .@"or" => try emit.writeInstruction(Instruction.@"or"(Register, rs1, rs2, rd)), + .xor => try emit.writeInstruction(Instruction.xor(Register, rs1, rs2, rd)), + .xnor => try emit.writeInstruction(Instruction.xnor(Register, rs1, rs2, rd)), .mulx => try emit.writeInstruction(Instruction.mulx(Register, rs1, rs2, rd)), .save => try emit.writeInstruction(Instruction.save(Register, rs1, rs2, rd)), .restore => try emit.writeInstruction(Instruction.restore(Register, rs1, rs2, rd)), diff --git a/src/arch/sparc64/bits.zig b/src/arch/sparc64/bits.zig index 615c224ae7..7b0342e2a3 100644 --- a/src/arch/sparc64/bits.zig +++ b/src/arch/sparc64/bits.zig @@ -1205,6 +1205,22 @@ pub const Instruction = union(enum) { }; } + pub fn xor(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction { + return switch (s2) { + Register => format3a(0b10, 0b00_0011, rs1, rs2, rd), + i13 => format3b(0b10, 0b00_0011, rs1, rs2, rd), + else => unreachable, + }; + } + + pub fn xnor(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction { + return switch (s2) { + Register => format3a(0b10, 0b00_0111, rs1, rs2, rd), + i13 => format3b(0b10, 0b00_0111, rs1, rs2, rd), + else => unreachable, + }; + } + pub fn movcc(comptime s2: type, cond: Condition, ccr: CCR, rs2: s2, rd: Register) Instruction { return switch (s2) { Register => format4c(0b10_1100, cond, ccr, rs2, rd),