aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/riscv64.zig
diff options
context:
space:
mode:
authorjoachimschmidt557 <joachim.schmidt557@outlook.com>2021-04-27 16:12:59 +0800
committerJakub Konka <kubkon@jakubkonka.com>2021-04-28 07:20:45 +0200
commitbc06e19828428ed9c2fc3698f418d46e62e327f5 (patch)
tree548505ed9a0bd1e769a2fc59a80098ec610ff9c4 /src/codegen/riscv64.zig
parentda9da76e3f91bf1b7e0dc89cb6d1b79dd0f0ad4b (diff)
downloadzig-bc06e19828428ed9c2fc3698f418d46e62e327f5.tar.gz
zig-bc06e19828428ed9c2fc3698f418d46e62e327f5.zip
stage2 riscv64: cleanup code and add tests
Diffstat (limited to 'src/codegen/riscv64.zig')
-rw-r--r--src/codegen/riscv64.zig57
1 files changed, 47 insertions, 10 deletions
diff --git a/src/codegen/riscv64.zig b/src/codegen/riscv64.zig
index 96b9c58f9c..a01f38289a 100644
--- a/src/codegen/riscv64.zig
+++ b/src/codegen/riscv64.zig
@@ -1,5 +1,7 @@
const std = @import("std");
const DW = std.dwarf;
+const assert = std.debug.assert;
+const testing = std.testing;
// TODO: this is only tagged to facilitate the monstrosity.
// Once packed structs work make it packed.
@@ -110,7 +112,7 @@ pub const Instruction = union(enum) {
// -- less burden on callsite, bonus semantic checking
fn bType(op: u7, fn3: u3, r1: Register, r2: Register, imm: i13) Instruction {
const umm = @bitCast(u13, imm);
- if (umm % 2 != 0) @panic("Internal error: misaligned branch target");
+ assert(umm % 2 == 0); // misaligned branch target
return Instruction{
.B = .{
@@ -140,15 +142,15 @@ pub const Instruction = union(enum) {
}
fn jType(op: u7, rd: Register, imm: i21) Instruction {
- const umm = @bitcast(u21, imm);
- if (umm % 2 != 0) @panic("Internal error: misaligned jump target");
+ const umm = @bitCast(u21, imm);
+ assert(umm % 2 == 0); // misaligned jump target
return Instruction{
.J = .{
.opcode = op,
.rd = @enumToInt(rd),
.imm1_10 = @truncate(u10, umm >> 1),
- .imm11 = @truncate(u1, umm >> 1),
+ .imm11 = @truncate(u1, umm >> 11),
.imm12_19 = @truncate(u8, umm >> 12),
.imm20 = @truncate(u1, umm >> 20),
},
@@ -340,27 +342,27 @@ pub const Instruction = union(enum) {
// Branch
- pub fn beq(r1: Register, r2: Register, offset: u13) Instruction {
+ pub fn beq(r1: Register, r2: Register, offset: i13) Instruction {
return bType(0b1100011, 0b000, r1, r2, offset);
}
- pub fn bne(r1: Register, r2: Register, offset: u13) Instruction {
+ pub fn bne(r1: Register, r2: Register, offset: i13) Instruction {
return bType(0b1100011, 0b001, r1, r2, offset);
}
- pub fn blt(r1: Register, r2: Register, offset: u13) Instruction {
+ pub fn blt(r1: Register, r2: Register, offset: i13) Instruction {
return bType(0b1100011, 0b100, r1, r2, offset);
}
- pub fn bge(r1: Register, r2: Register, offset: u13) Instruction {
+ pub fn bge(r1: Register, r2: Register, offset: i13) Instruction {
return bType(0b1100011, 0b101, r1, r2, offset);
}
- pub fn bltu(r1: Register, r2: Register, offset: u13) Instruction {
+ pub fn bltu(r1: Register, r2: Register, offset: i13) Instruction {
return bType(0b1100011, 0b110, r1, r2, offset);
}
- pub fn bgeu(r1: Register, r2: Register, offset: u13) Instruction {
+ pub fn bgeu(r1: Register, r2: Register, offset: i13) Instruction {
return bType(0b1100011, 0b111, r1, r2, offset);
}
@@ -431,3 +433,38 @@ pub const Register = enum(u5) {
pub const callee_preserved_regs = [_]Register{
.s0, .s1, .s2, .s3, .s4, .s5, .s6, .s7, .s8, .s9, .s10, .s11,
};
+
+test "serialize instructions" {
+ const Testcase = struct {
+ inst: Instruction,
+ expected: u32,
+ };
+
+ const testcases = [_]Testcase{
+ .{ // add t6, zero, zero
+ .inst = Instruction.add(.t6, .zero, .zero),
+ .expected = 0b0000000_00000_00000_000_11111_0110011,
+ },
+ .{ // sd s0, 0x7f(s0)
+ .inst = Instruction.sd(.s0, 0x7f, .s0),
+ .expected = 0b0000011_01000_01000_011_11111_0100011,
+ },
+ .{ // bne s0, s1, 0x42
+ .inst = Instruction.bne(.s0, .s1, 0x42),
+ .expected = 0b0_000010_01001_01000_001_0001_0_1100011,
+ },
+ .{ // j 0x1a
+ .inst = Instruction.jal(.zero, 0x1a),
+ .expected = 0b0_0000001101_0_00000000_00000_1101111,
+ },
+ .{ // ebreak
+ .inst = Instruction.ebreak,
+ .expected = 0b000000000001_00000_000_00000_1110011,
+ },
+ };
+
+ for (testcases) |case| {
+ const actual = case.inst.toU32();
+ testing.expectEqual(case.expected, actual);
+ }
+}