authorgravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-05-26 13:08:39+07:00
committergravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-05-26 13:08:39+07:00
log0310d88d7e6a855b3641b59c25f5b0f13726d14f
tree22bd5154426108c2e24a21a943d35004d328377a
parentab88165326abfd81c5046e8c064bd6603198ed94

stage2: sparc64: Add cmp and mov synthetic instructions


3 files changed, 51 insertions(+), 20 deletions(-)

src/arch/sparc64/CodeGen.zig+26-17
......@@ -1677,7 +1677,7 @@ fn binOp(
16771677
16781678 const mir_tag: Mir.Inst.Tag = switch (tag) {
16791679 .add => .add,
1680 .cmp_eq => .subcc,
1680 .cmp_eq => .cmp,
16811681 else => unreachable,
16821682 };
16831683
......@@ -1903,6 +1903,13 @@ fn binOpImmediate(
19031903 .rs2_or_imm = .{ .imm = @intCast(u6, rhs.immediate) },
19041904 },
19051905 },
1906 .cmp => .{
1907 .arithmetic_2op = .{
1908 .is_imm = true,
1909 .rs1 = lhs_reg,
1910 .rs2_or_imm = .{ .imm = @intCast(i13, rhs.immediate) },
1911 },
1912 },
19061913 else => unreachable,
19071914 };
19081915
......@@ -2012,6 +2019,13 @@ fn binOpRegister(
20122019 .rs2_or_imm = .{ .rs2 = rhs_reg },
20132020 },
20142021 },
2022 .cmp => .{
2023 .arithmetic_2op = .{
2024 .is_imm = false,
2025 .rs1 = lhs_reg,
2026 .rs2_or_imm = .{ .rs2 = rhs_reg },
2027 },
2028 },
20152029 else => unreachable,
20162030 };
20172031
......@@ -2303,12 +2317,11 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
23032317 .immediate => |x| {
23042318 if (x <= math.maxInt(u12)) {
23052319 _ = try self.addInst(.{
2306 .tag = .@"or",
2320 .tag = .mov,
23072321 .data = .{
2308 .arithmetic_3op = .{
2322 .arithmetic_2op = .{
23092323 .is_imm = true,
2310 .rd = reg,
2311 .rs1 = .g0,
2324 .rs1 = reg,
23122325 .rs2_or_imm = .{ .imm = @truncate(u12, x) },
23132326 },
23142327 },
......@@ -2400,14 +2413,12 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
24002413 if (src_reg.id() == reg.id())
24012414 return;
24022415
2403 // or %g0, src, dst (aka mov src, dst)
24042416 _ = try self.addInst(.{
2405 .tag = .@"or",
2417 .tag = .mov,
24062418 .data = .{
2407 .arithmetic_3op = .{
2419 .arithmetic_2op = .{
24082420 .is_imm = false,
2409 .rd = reg,
2410 .rs1 = .g0,
2421 .rs1 = reg,
24112422 .rs2_or_imm = .{ .rs2 = src_reg },
24122423 },
24132424 },
......@@ -2625,12 +2636,11 @@ fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
26252636 };
26262637
26272638 _ = try self.addInst(.{
2628 .tag = .subcc,
2629 .data = .{ .arithmetic_3op = .{
2639 .tag = .cmp,
2640 .data = .{ .arithmetic_2op = .{
26302641 .is_imm = true,
26312642 .rs1 = reg_mcv.register,
26322643 .rs2_or_imm = .{ .imm = 0 },
2633 .rd = .g0,
26342644 } },
26352645 });
26362646
......@@ -3163,12 +3173,11 @@ fn truncRegister(
31633173 },
31643174 64 => {
31653175 _ = try self.addInst(.{
3166 .tag = .@"or",
3176 .tag = .mov,
31673177 .data = .{
3168 .arithmetic_3op = .{
3178 .arithmetic_2op = .{
31693179 .is_imm = true,
3170 .rd = dest_reg,
3171 .rs1 = .g0,
3180 .rs1 = dest_reg,
31723181 .rs2_or_imm = .{ .rs2 = operand_reg },
31733182 },
31743183 },
src/arch/sparc64/Emit.zig+8
......@@ -121,6 +121,10 @@ pub fn emitMir(
121121 .subcc => try emit.mirArithmetic3Op(inst),
122122
123123 .tcc => try emit.mirTrap(inst),
124
125 .cmp => try emit.mirArithmetic2Op(inst),
126
127 .mov => try emit.mirArithmetic2Op(inst),
124128 }
125129 }
126130}
......@@ -179,12 +183,16 @@ fn mirArithmetic2Op(emit: *Emit, inst: Mir.Inst.Index) !void {
179183 const imm = data.rs2_or_imm.imm;
180184 switch (tag) {
181185 .@"return" => try emit.writeInstruction(Instruction.@"return"(i13, rs1, imm)),
186 .cmp => try emit.writeInstruction(Instruction.subcc(i13, rs1, imm, .g0)),
187 .mov => try emit.writeInstruction(Instruction.@"or"(i13, .g0, imm, rs1)),
182188 else => unreachable,
183189 }
184190 } else {
185191 const rs2 = data.rs2_or_imm.rs2;
186192 switch (tag) {
187193 .@"return" => try emit.writeInstruction(Instruction.@"return"(Register, rs1, rs2)),
194 .cmp => try emit.writeInstruction(Instruction.subcc(Register, rs1, rs2, .g0)),
195 .mov => try emit.writeInstruction(Instruction.@"or"(Register, .g0, rs2, rs1)),
188196 else => unreachable,
189197 }
190198 }
src/arch/sparc64/Mir.zig+17-3
......@@ -125,9 +125,23 @@ pub const Inst = struct {
125125 /// This uses the trap field.
126126 tcc,
127127
128 // TODO add synthetic instructions
129 // TODO add cmp synthetic instruction to avoid wasting a register when
130 // comparing with subcc
128 // SPARCv9 synthetic instructions
129 // Note that the instructions that is added here are only those that
130 // will simplify backend development. Synthetic instructions that is
131 // only used to provide syntactic sugar in, e.g. inline assembly should
132 // be deconstructed inside the parser instead.
133 // See also: G.3 Synthetic Instructions
134 // TODO add more synthetic instructions
135
136 /// Comparison
137 /// This uses the arithmetic_2op field.
138 cmp, // cmp rs1, rs2/imm -> subcc rs1, rs2/imm, %g0
139
140 /// Copy register/immediate contents to another register
141 /// This uses the arithmetic_2op field, with rs1
142 /// being the *destination* register.
143 // TODO is it okay to abuse rs1 in this way?
144 mov, // mov rs2/imm, rs1 -> or %g0, rs2/imm, rs1
131145 };
132146
133147 /// The position of an MIR instruction within the `Mir` instructions array.