diff options
| author | Koakuma <koachan@protonmail.com> | 2022-04-20 21:16:17 +0700 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-05-05 19:34:03 +0200 |
| commit | b6d7f63f34bbdb7c67abecbcd47389d2a3d28743 (patch) | |
| tree | aee14c6f05d58cf1777847747a97d5a3c79070e9 | |
| parent | 59905a62f9da9946a797cc35a2523c9929663600 (diff) | |
| download | zig-b6d7f63f34bbdb7c67abecbcd47389d2a3d28743.tar.gz zig-b6d7f63f34bbdb7c67abecbcd47389d2a3d28743.zip | |
stage2: sparcv9: Implement jmpl lowering
| -rw-r--r-- | src/arch/sparcv9/CodeGen.zig | 20 | ||||
| -rw-r--r-- | src/arch/sparcv9/Emit.zig | 5 | ||||
| -rw-r--r-- | src/arch/sparcv9/Mir.zig | 12 | ||||
| -rw-r--r-- | src/arch/sparcv9/bits.zig | 16 |
4 files changed, 35 insertions, 18 deletions
diff --git a/src/arch/sparcv9/CodeGen.zig b/src/arch/sparcv9/CodeGen.zig index 7d93916fc1..ffd1dfde86 100644 --- a/src/arch/sparcv9/CodeGen.zig +++ b/src/arch/sparcv9/CodeGen.zig @@ -1,5 +1,7 @@ //! SPARCv9 codegen. //! This lowers AIR into MIR. +//! For now this only implements medium/low code model with absolute addressing. +//! TODO add support for other code models. const std = @import("std"); const assert = std.debug.assert; const log = std.log.scoped(.codegen); @@ -884,7 +886,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. _ = try self.addInst(.{ .tag = .jmpl, - .data = .{ .branch_link_indirect = .{ .reg = .o7 } }, + .data = .{ + .arithmetic_3op = .{ + .is_imm = false, + .rd = .o7, + .rs1 = .o7, + .rs2_or_imm = .{ .rs2 = .g0 }, + }, + }, }); } else if (func_value.castTag(.extern_fn)) |_| { return self.fail("TODO implement calling extern functions", .{}); @@ -899,7 +908,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. _ = try self.addInst(.{ .tag = .jmpl, - .data = .{ .branch_link_indirect = .{ .reg = .o7 } }, + .data = .{ + .arithmetic_3op = .{ + .is_imm = false, + .rd = .o7, + .rs1 = .o7, + .rs2_or_imm = .{ .rs2 = .g0 }, + }, + }, }); } diff --git a/src/arch/sparcv9/Emit.zig b/src/arch/sparcv9/Emit.zig index b811a3567f..a136c622e7 100644 --- a/src/arch/sparcv9/Emit.zig +++ b/src/arch/sparcv9/Emit.zig @@ -56,8 +56,7 @@ pub fn emitMir( .call => @panic("TODO implement sparcv9 call"), - .jmpl => @panic("TODO implement sparcv9 jmpl"), - .jmpl_i => @panic("TODO implement sparcv9 jmpl to reg"), + .jmpl => try emit.mirArithmetic3Op(inst), .ldub => try emit.mirArithmetic3Op(inst), .lduh => try emit.mirArithmetic3Op(inst), @@ -163,6 +162,7 @@ fn mirArithmetic3Op(emit: *Emit, inst: Mir.Inst.Index) !void { const imm = data.rs2_or_imm.imm; switch (tag) { .add => try emit.writeInstruction(Instruction.add(i13, rs1, imm, rd)), + .jmpl => try emit.writeInstruction(Instruction.jmpl(i13, rs1, imm, rd)), .ldub => try emit.writeInstruction(Instruction.ldub(i13, rs1, imm, rd)), .lduh => try emit.writeInstruction(Instruction.lduh(i13, rs1, imm, rd)), .lduw => try emit.writeInstruction(Instruction.lduw(i13, rs1, imm, rd)), @@ -177,6 +177,7 @@ fn mirArithmetic3Op(emit: *Emit, inst: Mir.Inst.Index) !void { const rs2 = data.rs2_or_imm.rs2; switch (tag) { .add => try emit.writeInstruction(Instruction.add(Register, rs1, rs2, rd)), + .jmpl => try emit.writeInstruction(Instruction.jmpl(Register, rs1, rs2, rd)), .ldub => try emit.writeInstruction(Instruction.ldub(Register, rs1, rs2, rd)), .lduh => try emit.writeInstruction(Instruction.lduh(Register, rs1, rs2, rd)), .lduw => try emit.writeInstruction(Instruction.lduw(Register, rs1, rs2, rd)), diff --git a/src/arch/sparcv9/Mir.zig b/src/arch/sparcv9/Mir.zig index c79ebdcac1..21f59322cd 100644 --- a/src/arch/sparcv9/Mir.zig +++ b/src/arch/sparcv9/Mir.zig @@ -54,11 +54,8 @@ pub const Inst = struct { call, /// A.24 Jump and Link - /// jmpl (far direct jump) uses the branch_link field, - /// while jmpl_i (indirect jump) uses the branch_link_indirect field. - /// Those two MIR instructions will be lowered into SPARCv9 jmpl instruction. + /// It uses the arithmetic_3op field. jmpl, - jmpl_i, /// A.27 Load Integer /// Those uses the arithmetic_3op field. @@ -167,13 +164,6 @@ pub const Inst = struct { link: Register = .o7, }, - /// Indirect branch and link (always unconditional). - /// Used by e.g. jmpl_i - branch_link_indirect: struct { - reg: Register, - link: Register = .o7, - }, - /// Branch with prediction. /// Used by e.g. bpcc branch_predict: struct { diff --git a/src/arch/sparcv9/bits.zig b/src/arch/sparcv9/bits.zig index bc8b8822b7..2b50e68d32 100644 --- a/src/arch/sparcv9/bits.zig +++ b/src/arch/sparcv9/bits.zig @@ -271,6 +271,8 @@ pub const Instruction = union(enum) { rd: u5, op3: u6, rs1: u5, + // See Errata 58 of SPARCv9 specification + // https://sparc.org/errata-for-v9/#58 i: u1 = 0b1, reserved: u8 = 0b00000000, rs2: u5, @@ -977,10 +979,10 @@ pub const Instruction = union(enum) { }; } - pub fn @"or"(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction { + pub fn jmpl(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction { return switch (s2) { - Register => format3a(0b10, 0b00_0010, rs1, rs2, rd), - i13 => format3b(0b10, 0b00_0010, rs1, rs2, rd), + Register => format3a(0b10, 0b11_1000, rs1, rs2, rd), + i13 => format3b(0b10, 0b11_1000, rs1, rs2, rd), else => unreachable, }; } @@ -1017,6 +1019,14 @@ pub const Instruction = union(enum) { }; } + pub fn @"or"(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction { + return switch (s2) { + Register => format3a(0b10, 0b00_0010, rs1, rs2, rd), + i13 => format3b(0b10, 0b00_0010, rs1, rs2, rd), + else => unreachable, + }; + } + pub fn nop() Instruction { return sethi(0, .g0); } |
