diff options
Diffstat (limited to 'src/arch/riscv64/Encoding.zig')
| -rw-r--r-- | src/arch/riscv64/Encoding.zig | 90 |
1 files changed, 67 insertions, 23 deletions
diff --git a/src/arch/riscv64/Encoding.zig b/src/arch/riscv64/Encoding.zig index b280b8a483..08044e644e 100644 --- a/src/arch/riscv64/Encoding.zig +++ b/src/arch/riscv64/Encoding.zig @@ -2,25 +2,30 @@ mnemonic: Mnemonic, data: Data, const OpCode = enum(u7) { - OP = 0b0110011, + LOAD = 0b0000011, + LOAD_FP = 0b0000111, + MISC_MEM = 0b0001111, OP_IMM = 0b0010011, + AUIPC = 0b0010111, OP_IMM_32 = 0b0011011, - OP_32 = 0b0111011, - - BRANCH = 0b1100011, - LOAD = 0b0000011, STORE = 0b0100011, - SYSTEM = 0b1110011, - - OP_FP = 0b1010011, - LOAD_FP = 0b0000111, STORE_FP = 0b0100111, - - JALR = 0b1100111, - AUIPC = 0b0010111, + AMO = 0b0101111, + OP = 0b0110011, + OP_32 = 0b0111011, LUI = 0b0110111, + MADD = 0b1000011, + MSUB = 0b1000111, + NMSUB = 0b1001011, + NMADD = 0b1001111, + OP_FP = 0b1010011, + OP_IMM_64 = 0b1011011, + BRANCH = 0b1100011, + JALR = 0b1100111, JAL = 0b1101111, - NONE = 0b0000000, + SYSTEM = 0b1110011, + OP_64 = 0b1111011, + NONE = 0b00000000, }; const Fmt = enum(u2) { @@ -28,7 +33,9 @@ const Fmt = enum(u2) { S = 0b00, /// 64-bit double-precision D = 0b01, - _reserved = 0b10, + + // H = 0b10, unused in the G extension + /// 128-bit quad-precision Q = 0b11, }; @@ -192,6 +199,9 @@ pub const Mnemonic = enum { fsgnjnd, fsgnjxd, + // MISC + fence, + pub fn encoding(mnem: Mnemonic) Enc { return switch (mnem) { // zig fmt: off @@ -366,6 +376,10 @@ pub const Mnemonic = enum { .unimp => .{ .opcode = .NONE, .data = .{ .f = .{ .funct3 = 0b000 } } }, + // MISC_MEM + + .fence => .{ .opcode = .MISC_MEM, .data = .{ .f = .{ .funct3 = 0b000 } } }, + // zig fmt: on }; @@ -380,7 +394,7 @@ pub const InstEnc = enum { B, U, J, - + fence, /// extras that have unusual op counts system, @@ -509,20 +523,24 @@ pub const InstEnc = enum { .ebreak, .unimp, => .system, + + .fence, + => .fence, }; } pub fn opsList(enc: InstEnc) [4]std.meta.FieldEnum(Operand) { return switch (enc) { // zig fmt: off - .R => .{ .reg, .reg, .reg, .none }, - .R4 => .{ .reg, .reg, .reg, .reg }, - .I => .{ .reg, .reg, .imm, .none }, - .S => .{ .reg, .reg, .imm, .none }, - .B => .{ .reg, .reg, .imm, .none }, - .U => .{ .reg, .imm, .none, .none }, - .J => .{ .reg, .imm, .none, .none }, - .system => .{ .none, .none, .none, .none }, + .R => .{ .reg, .reg, .reg, .none }, + .R4 => .{ .reg, .reg, .reg, .reg }, + .I => .{ .reg, .reg, .imm, .none }, + .S => .{ .reg, .reg, .imm, .none }, + .B => .{ .reg, .reg, .imm, .none }, + .U => .{ .reg, .imm, .none, .none }, + .J => .{ .reg, .imm, .none, .none }, + .system => .{ .none, .none, .none, .none }, + .fence => .{ .barrier, .barrier, .none, .none }, // zig fmt: on }; } @@ -584,6 +602,15 @@ pub const Data = union(InstEnc) { imm1_10: u10, imm20: u1, }, + fence: packed struct { + opcode: u7, + rd: u5 = 0, + funct3: u3, + rs1: u5 = 0, + succ: u4, + pred: u4, + _ignored: u4 = 0, + }, system: void, pub fn toU32(self: Data) u32 { @@ -596,6 +623,7 @@ pub const Data = union(InstEnc) { .B => |v| @as(u32, @intCast(v.opcode)) + (@as(u32, @intCast(v.imm11)) << 7) + (@as(u32, @intCast(v.imm1_4)) << 8) + (@as(u32, @intCast(v.funct3)) << 12) + (@as(u32, @intCast(v.rs1)) << 15) + (@as(u32, @intCast(v.rs2)) << 20) + (@as(u32, @intCast(v.imm5_10)) << 25) + (@as(u32, @intCast(v.imm12)) << 31), .U => |v| @bitCast(v), .J => |v| @bitCast(v), + .fence => |v| @bitCast(v), .system => unreachable, // zig fmt: on }; @@ -748,6 +776,22 @@ pub const Data = union(InstEnc) { }, }; }, + .fence => { + assert(ops.len == 2); + + const succ = ops[0]; + const pred = ops[1]; + + return .{ + .fence = .{ + .succ = @intFromEnum(succ.barrier), + .pred = @intFromEnum(pred.barrier), + + .opcode = @intFromEnum(enc.opcode), + .funct3 = enc.data.f.funct3, + }, + }; + }, else => std.debug.panic("TODO: construct {s}", .{@tagName(inst_enc)}), } |
