Commit 0310d88d7e
Changed files (3)
src
arch
sparc64
src/arch/sparc64/CodeGen.zig
@@ -1677,7 +1677,7 @@ fn binOp(
const mir_tag: Mir.Inst.Tag = switch (tag) {
.add => .add,
- .cmp_eq => .subcc,
+ .cmp_eq => .cmp,
else => unreachable,
};
@@ -1903,6 +1903,13 @@ fn binOpImmediate(
.rs2_or_imm = .{ .imm = @intCast(u6, rhs.immediate) },
},
},
+ .cmp => .{
+ .arithmetic_2op = .{
+ .is_imm = true,
+ .rs1 = lhs_reg,
+ .rs2_or_imm = .{ .imm = @intCast(i13, rhs.immediate) },
+ },
+ },
else => unreachable,
};
@@ -2012,6 +2019,13 @@ fn binOpRegister(
.rs2_or_imm = .{ .rs2 = rhs_reg },
},
},
+ .cmp => .{
+ .arithmetic_2op = .{
+ .is_imm = false,
+ .rs1 = lhs_reg,
+ .rs2_or_imm = .{ .rs2 = rhs_reg },
+ },
+ },
else => unreachable,
};
@@ -2303,12 +2317,11 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
.immediate => |x| {
if (x <= math.maxInt(u12)) {
_ = try self.addInst(.{
- .tag = .@"or",
+ .tag = .mov,
.data = .{
- .arithmetic_3op = .{
+ .arithmetic_2op = .{
.is_imm = true,
- .rd = reg,
- .rs1 = .g0,
+ .rs1 = reg,
.rs2_or_imm = .{ .imm = @truncate(u12, x) },
},
},
@@ -2400,14 +2413,12 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
if (src_reg.id() == reg.id())
return;
- // or %g0, src, dst (aka mov src, dst)
_ = try self.addInst(.{
- .tag = .@"or",
+ .tag = .mov,
.data = .{
- .arithmetic_3op = .{
+ .arithmetic_2op = .{
.is_imm = false,
- .rd = reg,
- .rs1 = .g0,
+ .rs1 = reg,
.rs2_or_imm = .{ .rs2 = src_reg },
},
},
@@ -2625,12 +2636,11 @@ fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
};
_ = try self.addInst(.{
- .tag = .subcc,
- .data = .{ .arithmetic_3op = .{
+ .tag = .cmp,
+ .data = .{ .arithmetic_2op = .{
.is_imm = true,
.rs1 = reg_mcv.register,
.rs2_or_imm = .{ .imm = 0 },
- .rd = .g0,
} },
});
@@ -3163,12 +3173,11 @@ fn truncRegister(
},
64 => {
_ = try self.addInst(.{
- .tag = .@"or",
+ .tag = .mov,
.data = .{
- .arithmetic_3op = .{
+ .arithmetic_2op = .{
.is_imm = true,
- .rd = dest_reg,
- .rs1 = .g0,
+ .rs1 = dest_reg,
.rs2_or_imm = .{ .rs2 = operand_reg },
},
},
src/arch/sparc64/Emit.zig
@@ -121,6 +121,10 @@ pub fn emitMir(
.subcc => try emit.mirArithmetic3Op(inst),
.tcc => try emit.mirTrap(inst),
+
+ .cmp => try emit.mirArithmetic2Op(inst),
+
+ .mov => try emit.mirArithmetic2Op(inst),
}
}
}
@@ -179,12 +183,16 @@ fn mirArithmetic2Op(emit: *Emit, inst: Mir.Inst.Index) !void {
const imm = data.rs2_or_imm.imm;
switch (tag) {
.@"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)),
else => unreachable,
}
} else {
const rs2 = data.rs2_or_imm.rs2;
switch (tag) {
.@"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)),
else => unreachable,
}
}
src/arch/sparc64/Mir.zig
@@ -125,9 +125,23 @@ pub const Inst = struct {
/// This uses the trap field.
tcc,
- // TODO add synthetic instructions
- // TODO add cmp synthetic instruction to avoid wasting a register when
- // comparing with subcc
+ // SPARCv9 synthetic instructions
+ // Note that the instructions that is added here are only those that
+ // will simplify backend development. Synthetic instructions that is
+ // only used to provide syntactic sugar in, e.g. inline assembly should
+ // be deconstructed inside the parser instead.
+ // See also: G.3 Synthetic Instructions
+ // TODO add more synthetic instructions
+
+ /// Comparison
+ /// This uses the arithmetic_2op field.
+ cmp, // cmp rs1, rs2/imm -> subcc rs1, rs2/imm, %g0
+
+ /// Copy register/immediate contents to another register
+ /// This uses the arithmetic_2op field, with rs1
+ /// being the *destination* register.
+ // TODO is it okay to abuse rs1 in this way?
+ mov, // mov rs2/imm, rs1 -> or %g0, rs2/imm, rs1
};
/// The position of an MIR instruction within the `Mir` instructions array.