Add capability-aware compressed decoding

This commit is contained in:
Peter Rugg
2021-04-14 14:56:19 +01:00
parent 88751cccba
commit 1b5f4ee9e0
3 changed files with 294 additions and 242 deletions

View File

@@ -38,71 +38,72 @@ export fv_decode_C;
// ================================================================
// Project imports
import ISA_Decls :: *;
import ISA_Decls :: *;
import ISA_Decls_CHERI :: *;
// ================================================================
function Instr fv_decode_C (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Instr fv_decode_C (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
// ----------------
// Try each possible C instruction
match { .valid_C_LWSP, .i_C_LWSP } = fv_decode_C_LWSP (misa, xl, instr_C);
match { .valid_C_SWSP, .i_C_SWSP } = fv_decode_C_SWSP (misa, xl, instr_C);
match { .valid_C_LW, .i_C_LW } = fv_decode_C_LW (misa, xl, instr_C);
match { .valid_C_SW, .i_C_SW } = fv_decode_C_SW (misa, xl, instr_C);
match { .valid_C_LWSP, .i_C_LWSP } = fv_decode_C_LWSP (misa, xl, cap_enc, instr_C);
match { .valid_C_SWSP, .i_C_SWSP } = fv_decode_C_SWSP (misa, xl, cap_enc, instr_C);
match { .valid_C_LW, .i_C_LW } = fv_decode_C_LW (misa, xl, cap_enc, instr_C);
match { .valid_C_SW, .i_C_SW } = fv_decode_C_SW (misa, xl, cap_enc, instr_C);
match { .valid_C_J, .i_C_J } = fv_decode_C_J (misa, xl, instr_C);
match { .valid_C_JAL, .i_C_JAL } = fv_decode_C_JAL (misa, xl, instr_C);
match { .valid_C_JR, .i_C_JR } = fv_decode_C_JR (misa, xl, instr_C);
match { .valid_C_JALR, .i_C_JALR } = fv_decode_C_JALR (misa, xl, instr_C);
match { .valid_C_BEQZ, .i_C_BEQZ } = fv_decode_C_BEQZ (misa, xl, instr_C);
match { .valid_C_BNEZ, .i_C_BNEZ } = fv_decode_C_BNEZ (misa, xl, instr_C);
match { .valid_C_LI, .i_C_LI } = fv_decode_C_LI (misa, xl, instr_C);
match { .valid_C_LUI, .i_C_LUI } = fv_decode_C_LUI (misa, xl, instr_C);
match { .valid_C_ADDI, .i_C_ADDI } = fv_decode_C_ADDI (misa, xl, instr_C);
match { .valid_C_NOP, .i_C_NOP } = fv_decode_C_NOP (misa, xl, instr_C);
match { .valid_C_ADDIW, .i_C_ADDIW } = fv_decode_C_ADDIW (misa, xl, instr_C);
match { .valid_C_ADDI16SP, .i_C_ADDI16SP } = fv_decode_C_ADDI16SP (misa, xl, instr_C);
match { .valid_C_ADDI4SPN, .i_C_ADDI4SPN } = fv_decode_C_ADDI4SPN (misa, xl, instr_C);
match { .valid_C_SLLI, .i_C_SLLI } = fv_decode_C_SLLI (misa, xl, instr_C);
match { .valid_C_SRLI, .i_C_SRLI } = fv_decode_C_SRLI (misa, xl, instr_C);
match { .valid_C_SRAI, .i_C_SRAI } = fv_decode_C_SRAI (misa, xl, instr_C);
match { .valid_C_ANDI, .i_C_ANDI } = fv_decode_C_ANDI (misa, xl, instr_C);
match { .valid_C_MV, .i_C_MV } = fv_decode_C_MV (misa, xl, instr_C);
match { .valid_C_ADD, .i_C_ADD } = fv_decode_C_ADD (misa, xl, instr_C);
match { .valid_C_AND, .i_C_AND } = fv_decode_C_AND (misa, xl, instr_C);
match { .valid_C_OR, .i_C_OR } = fv_decode_C_OR (misa, xl, instr_C);
match { .valid_C_XOR, .i_C_XOR } = fv_decode_C_XOR (misa, xl, instr_C);
match { .valid_C_SUB, .i_C_SUB } = fv_decode_C_SUB (misa, xl, instr_C);
match { .valid_C_ADDW, .i_C_ADDW } = fv_decode_C_ADDW (misa, xl, instr_C);
match { .valid_C_SUBW, .i_C_SUBW } = fv_decode_C_SUBW (misa, xl, instr_C);
match { .valid_C_EBREAK, .i_C_EBREAK } = fv_decode_C_EBREAK (misa, xl, instr_C);
match { .valid_C_J, .i_C_J } = fv_decode_C_J (misa, xl, cap_enc, instr_C);
match { .valid_C_JAL, .i_C_JAL } = fv_decode_C_JAL (misa, xl, cap_enc, instr_C);
match { .valid_C_JR, .i_C_JR } = fv_decode_C_JR (misa, xl, cap_enc, instr_C);
match { .valid_C_JALR, .i_C_JALR } = fv_decode_C_JALR (misa, xl, cap_enc, instr_C);
match { .valid_C_BEQZ, .i_C_BEQZ } = fv_decode_C_BEQZ (misa, xl, cap_enc, instr_C);
match { .valid_C_BNEZ, .i_C_BNEZ } = fv_decode_C_BNEZ (misa, xl, cap_enc, instr_C);
match { .valid_C_LI, .i_C_LI } = fv_decode_C_LI (misa, xl, cap_enc, instr_C);
match { .valid_C_LUI, .i_C_LUI } = fv_decode_C_LUI (misa, xl, cap_enc, instr_C);
match { .valid_C_ADDI, .i_C_ADDI } = fv_decode_C_ADDI (misa, xl, cap_enc, instr_C);
match { .valid_C_NOP, .i_C_NOP } = fv_decode_C_NOP (misa, xl, cap_enc, instr_C);
match { .valid_C_ADDIW, .i_C_ADDIW } = fv_decode_C_ADDIW (misa, xl, cap_enc, instr_C);
match { .valid_C_ADDI16SP, .i_C_ADDI16SP } = fv_decode_C_ADDI16SP (misa, xl, cap_enc, instr_C);
match { .valid_C_CIncOffsetImm16CSP, .i_C_CIncOffsetImm16CSP } = fv_decode_C_CIncOffsetImm16CSP (misa, xl, cap_enc, instr_C);
match { .valid_C_ADDI4SPN, .i_C_ADDI4SPN } = fv_decode_C_ADDI4SPN (misa, xl, cap_enc, instr_C);
match { .valid_C_CIncOffsetImm4CSPN, .i_C_CIncOffsetImm4CSPN } = fv_decode_C_CIncOffsetImm4CSPN (misa, xl, cap_enc, instr_C);
match { .valid_C_SLLI, .i_C_SLLI } = fv_decode_C_SLLI (misa, xl, cap_enc, instr_C);
match { .valid_C_SRLI, .i_C_SRLI } = fv_decode_C_SRLI (misa, xl, cap_enc, instr_C);
match { .valid_C_SRAI, .i_C_SRAI } = fv_decode_C_SRAI (misa, xl, cap_enc, instr_C);
match { .valid_C_ANDI, .i_C_ANDI } = fv_decode_C_ANDI (misa, xl, cap_enc, instr_C);
match { .valid_C_MV, .i_C_MV } = fv_decode_C_MV (misa, xl, cap_enc, instr_C);
match { .valid_C_ADD, .i_C_ADD } = fv_decode_C_ADD (misa, xl, cap_enc, instr_C);
match { .valid_C_AND, .i_C_AND } = fv_decode_C_AND (misa, xl, cap_enc, instr_C);
match { .valid_C_OR, .i_C_OR } = fv_decode_C_OR (misa, xl, cap_enc, instr_C);
match { .valid_C_XOR, .i_C_XOR } = fv_decode_C_XOR (misa, xl, cap_enc, instr_C);
match { .valid_C_SUB, .i_C_SUB } = fv_decode_C_SUB (misa, xl, cap_enc, instr_C);
match { .valid_C_ADDW, .i_C_ADDW } = fv_decode_C_ADDW (misa, xl, cap_enc, instr_C);
match { .valid_C_SUBW, .i_C_SUBW } = fv_decode_C_SUBW (misa, xl, cap_enc, instr_C);
match { .valid_C_EBREAK, .i_C_EBREAK } = fv_decode_C_EBREAK (misa, xl, cap_enc, instr_C);
match { .valid_C_LDSP, .i_C_LDSP } = fv_decode_C_LDSP (misa, xl, cap_enc, instr_C);
match { .valid_C_SDSP, .i_C_SDSP } = fv_decode_C_SDSP (misa, xl, cap_enc, instr_C);
match { .valid_C_LD, .i_C_LD } = fv_decode_C_LD (misa, xl, cap_enc, instr_C);
match { .valid_C_SD, .i_C_SD } = fv_decode_C_SD (misa, xl, cap_enc, instr_C);
`ifdef RV64
match { .valid_C_LDSP, .i_C_LDSP } = fv_decode_C_LDSP (misa, xl, instr_C);
match { .valid_C_SDSP, .i_C_SDSP } = fv_decode_C_SDSP (misa, xl, instr_C);
match { .valid_C_LD, .i_C_LD } = fv_decode_C_LD (misa, xl, instr_C);
match { .valid_C_SD, .i_C_SD } = fv_decode_C_SD (misa, xl, instr_C);
`endif
`ifdef RV128
match { .valid_C_LQSP, .i_C_LQSP } = fv_decode_C_LQSP (misa, xl, instr_C);
match { .valid_C_SQSP, .i_C_SQSP } = fv_decode_C_SQSP (misa, xl, instr_C);
match { .valid_C_LQ, .i_C_LQ } = fv_decode_C_LQ (misa, xl, instr_C);
match { .valid_C_SQ, .i_C_SQ } = fv_decode_C_SQ (misa, xl, instr_C);
match { .valid_C_LQSP, .i_C_LQSP } = fv_decode_C_LQSP (misa, xl, cap_enc, instr_C);
match { .valid_C_SQSP, .i_C_SQSP } = fv_decode_C_SQSP (misa, xl, cap_enc, instr_C);
match { .valid_C_LQ, .i_C_LQ } = fv_decode_C_LQ (misa, xl, cap_enc, instr_C);
match { .valid_C_SQ, .i_C_SQ } = fv_decode_C_SQ (misa, xl, cap_enc, instr_C);
`endif
`ifdef ISA_F
match { .valid_C_FLWSP, .i_C_FLWSP } = fv_decode_C_FLWSP (misa, xl, instr_C);
match { .valid_C_FSWSP, .i_C_FSWSP } = fv_decode_C_FSWSP (misa, xl, instr_C);
match { .valid_C_FLW, .i_C_FLW } = fv_decode_C_FLW (misa, xl, instr_C);
match { .valid_C_FSW, .i_C_FSW } = fv_decode_C_FSW (misa, xl, instr_C);
match { .valid_C_FLWSP, .i_C_FLWSP } = fv_decode_C_FLWSP (misa, xl, cap_enc, instr_C);
match { .valid_C_FSWSP, .i_C_FSWSP } = fv_decode_C_FSWSP (misa, xl, cap_enc, instr_C);
match { .valid_C_FLW, .i_C_FLW } = fv_decode_C_FLW (misa, xl, cap_enc, instr_C);
match { .valid_C_FSW, .i_C_FSW } = fv_decode_C_FSW (misa, xl, cap_enc, instr_C);
`endif
`ifdef ISA_D
match { .valid_C_FLDSP, .i_C_FLDSP } = fv_decode_C_FLDSP (misa, xl, instr_C);
match { .valid_C_FSDSP, .i_C_FSDSP } = fv_decode_C_FSDSP (misa, xl, instr_C);
match { .valid_C_FLD, .i_C_FLD } = fv_decode_C_FLD (misa, xl, instr_C);
match { .valid_C_FSD, .i_C_FSD } = fv_decode_C_FSD (misa, xl, instr_C);
match { .valid_C_FLDSP, .i_C_FLDSP } = fv_decode_C_FLDSP (misa, xl, cap_enc, instr_C);
match { .valid_C_FSDSP, .i_C_FSDSP } = fv_decode_C_FSDSP (misa, xl, cap_enc, instr_C);
match { .valid_C_FLD, .i_C_FLD } = fv_decode_C_FLD (misa, xl, cap_enc, instr_C);
match { .valid_C_FSD, .i_C_FSD } = fv_decode_C_FSD (misa, xl, cap_enc, instr_C);
`endif
// ----------------
@@ -110,64 +111,64 @@ function Instr fv_decode_C (MISA misa, Bit #(2) xl, Instr_C instr_C);
Instr instr = ?;
if (valid_C_LWSP) instr = i_C_LWSP;
else if (valid_C_SWSP) instr = i_C_SWSP;
else if (valid_C_LW) instr = i_C_LW;
else if (valid_C_SW) instr = i_C_SW;
if (valid_C_LWSP) instr = i_C_LWSP;
else if (valid_C_SWSP) instr = i_C_SWSP;
else if (valid_C_LW) instr = i_C_LW;
else if (valid_C_SW) instr = i_C_SW;
else if (valid_C_J) instr = i_C_J;
else if (valid_C_JAL) instr = i_C_JAL;
else if (valid_C_JR) instr = i_C_JR;
else if (valid_C_JALR) instr = i_C_JALR;
else if (valid_C_BEQZ) instr = i_C_BEQZ;
else if (valid_C_BNEZ) instr = i_C_BNEZ;
else if (valid_C_LI) instr = i_C_LI;
else if (valid_C_LUI) instr = i_C_LUI;
else if (valid_C_ADDI) instr = i_C_ADDI;
else if (valid_C_NOP) instr = i_C_NOP;
else if (valid_C_ADDIW) instr = i_C_ADDIW;
else if (valid_C_ADDI16SP) instr = i_C_ADDI16SP;
else if (valid_C_ADDI4SPN) instr = i_C_ADDI4SPN;
else if (valid_C_SLLI) instr = i_C_SLLI;
else if (valid_C_SRLI) instr = i_C_SRLI;
else if (valid_C_SRAI) instr = i_C_SRAI;
else if (valid_C_ANDI) instr = i_C_ANDI;
else if (valid_C_MV) instr = i_C_MV;
else if (valid_C_ADD) instr = i_C_ADD;
else if (valid_C_AND) instr = i_C_AND;
else if (valid_C_OR) instr = i_C_OR;
else if (valid_C_XOR) instr = i_C_XOR;
else if (valid_C_SUB) instr = i_C_SUB;
else if (valid_C_ADDW) instr = i_C_ADDW;
else if (valid_C_SUBW) instr = i_C_SUBW;
else if (valid_C_EBREAK) instr = i_C_EBREAK;
else if (valid_C_J) instr = i_C_J;
else if (valid_C_JAL) instr = i_C_JAL;
else if (valid_C_JR) instr = i_C_JR;
else if (valid_C_JALR) instr = i_C_JALR;
else if (valid_C_BEQZ) instr = i_C_BEQZ;
else if (valid_C_BNEZ) instr = i_C_BNEZ;
else if (valid_C_LI) instr = i_C_LI;
else if (valid_C_LUI) instr = i_C_LUI;
else if (valid_C_ADDI) instr = i_C_ADDI;
else if (valid_C_NOP) instr = i_C_NOP;
else if (valid_C_ADDIW) instr = i_C_ADDIW;
else if (valid_C_ADDI16SP) instr = i_C_ADDI16SP;
else if (valid_C_CIncOffsetImm16CSP) instr = i_C_CIncOffsetImm16CSP;
else if (valid_C_ADDI4SPN) instr = i_C_ADDI4SPN;
else if (valid_C_CIncOffsetImm4CSPN) instr = i_C_CIncOffsetImm4CSPN;
else if (valid_C_SLLI) instr = i_C_SLLI;
else if (valid_C_SRLI) instr = i_C_SRLI;
else if (valid_C_SRAI) instr = i_C_SRAI;
else if (valid_C_ANDI) instr = i_C_ANDI;
else if (valid_C_MV) instr = i_C_MV;
else if (valid_C_ADD) instr = i_C_ADD;
else if (valid_C_AND) instr = i_C_AND;
else if (valid_C_OR) instr = i_C_OR;
else if (valid_C_XOR) instr = i_C_XOR;
else if (valid_C_SUB) instr = i_C_SUB;
else if (valid_C_ADDW) instr = i_C_ADDW;
else if (valid_C_SUBW) instr = i_C_SUBW;
else if (valid_C_EBREAK) instr = i_C_EBREAK;
`ifdef RV64
else if (valid_C_LDSP) instr = i_C_LDSP;
else if (valid_C_SDSP) instr = i_C_SDSP;
else if (valid_C_LD) instr = i_C_LD;
else if (valid_C_SD) instr = i_C_SD;
else if (valid_C_LDSP) instr = i_C_LDSP;
else if (valid_C_SDSP) instr = i_C_SDSP;
else if (valid_C_LD) instr = i_C_LD;
else if (valid_C_SD) instr = i_C_SD;
`endif
`ifdef RV128
else if (valid_C_LQSP) instr = i_C_LQSP;
else if (valid_C_SQSP) instr = i_C_SQSP;
else if (valid_C_LQ) instr = i_C_LQ;
else if (valid_C_SQ) instr = i_C_SQ;
`endif
else if (valid_C_LQSP) instr = i_C_LQSP;
else if (valid_C_SQSP) instr = i_C_SQSP;
else if (valid_C_LQ) instr = i_C_LQ;
else if (valid_C_SQ) instr = i_C_SQ;
`ifdef ISA_F
else if (valid_C_FLWSP) instr = i_C_FLWSP;
else if (valid_C_FSWSP) instr = i_C_FSWSP;
else if (valid_C_FLW) instr = i_C_FLW;
else if (valid_C_FSW) instr = i_C_FSW;
else if (valid_C_FLWSP) instr = i_C_FLWSP;
else if (valid_C_FSWSP) instr = i_C_FSWSP;
else if (valid_C_FLW) instr = i_C_FLW;
else if (valid_C_FSW) instr = i_C_FSW;
`endif
`ifdef ISA_D
else if (valid_C_FLDSP) instr = i_C_FLDSP;
else if (valid_C_FSDSP) instr = i_C_FSDSP;
else if (valid_C_FLD) instr = i_C_FLD;
else if (valid_C_FSD) instr = i_C_FSD;
else if (valid_C_FLDSP) instr = i_C_FLDSP;
else if (valid_C_FSDSP) instr = i_C_FSDSP;
else if (valid_C_FLD) instr = i_C_FLD;
else if (valid_C_FSD) instr = i_C_FSD;
`endif
else
@@ -180,7 +181,7 @@ endfunction
// 'C' Extension Stack-Pointer-Based Loads
// LWSP: expands into LW
function Tuple2 #(Bool, Instr) fv_decode_C_LWSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_LWSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: I-type
match { .funct3, .imm_at_12, .rd, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -198,9 +199,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LWSP (MISA misa, Bit #(2) xl, Instr
end
endfunction
`ifdef RV64
// LDSP: expands into LD
function Tuple2 #(Bool, Instr) fv_decode_C_LDSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_LDSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: I-type
match { .funct3, .imm_at_12, .rd, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -211,7 +211,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LDSP (MISA misa, Bit #(2) xl, Instr
&& (rd != 0)
&& (funct3 == funct3_C_LDSP)
&& ( (xl == misa_mxl_64)
|| (xl == misa_mxl_128)));
|| (cap_enc)));
RegName rs1 = reg_sp;
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_LD, rd, op_LOAD);
@@ -219,11 +219,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LDSP (MISA misa, Bit #(2) xl, Instr
return tuple2 (is_legal, instr);
end
endfunction
`endif
`ifdef RV128
`ifdef RV64
// LQSP: expands into LQ
function Tuple2 #(Bool, Instr) fv_decode_C_LQSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_LQSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: I-type
match { .funct3, .imm_at_12, .rd, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -233,10 +232,11 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LQSP (MISA misa, Bit #(2) xl, Instr
&& (op == opcode_C2)
&& (rd != 0)
&& (funct3 == funct3_C_LQSP)
&& (xl == misa_mxl_128));
&& (xl == misa_mxl_64)
&& (cap_enc));
RegName rs1 = reg_sp;
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_LQ, rd, op_LOAD);
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_LQ, rd, op_MISC_MEM);
return tuple2 (is_legal, instr);
end
@@ -245,7 +245,7 @@ endfunction
`ifdef ISA_F
// FLWSP: expands into FLW
function Tuple2 #(Bool, Instr) fv_decode_C_FLWSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_FLWSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: I-type
match { .funct3, .imm_at_12, .rd, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -254,7 +254,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FLWSP (MISA misa, Bit #(2) xl, Inst
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C2)
&& (funct3 == funct3_C_FLWSP)
&& (misa.f == 1'b1));
&& (misa.f == 1'b1)
&& (! cap_enc));
RegName rs1 = reg_sp;
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_FLW, rd, op_LOAD_FP);
@@ -266,7 +267,7 @@ endfunction
`ifdef ISA_D
// FLDSP: expands into FLD
function Tuple2 #(Bool, Instr) fv_decode_C_FLDSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_FLDSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: I-type
match { .funct3, .imm_at_12, .rd, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -276,8 +277,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FLDSP (MISA misa, Bit #(2) xl, Inst
&& (op == opcode_C2)
&& (funct3 == funct3_C_FLDSP)
&& (misa.d == 1'b1)
&& ( (xl == misa_mxl_64)
|| (xl == misa_mxl_128)));
&& ( (xl == misa_mxl_32)
|| (! cap_enc)));
RegName rs1 = reg_sp;
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_FLD, rd, op_LOAD_FP);
@@ -291,7 +292,7 @@ endfunction
// 'C' Extension Stack-Pointer-Based Stores
// SWSP: expands to SW
function Tuple2 #(Bool, Instr) fv_decode_C_SWSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SWSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CSS-type
match { .funct3, .imm_at_12_7, .rs2, .op } = fv_ifields_CSS_type (instr_C);
@@ -308,9 +309,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SWSP (MISA misa, Bit #(2) xl, Inst
end
endfunction
`ifdef RV64
// SDSP: expands to SD
function Tuple2 #(Bool, Instr) fv_decode_C_SDSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SDSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CSS-type
match { .funct3, .imm_at_12_7, .rs2, .op } = fv_ifields_CSS_type (instr_C);
@@ -320,7 +320,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SDSP (MISA misa, Bit #(2) xl, Inst
&& (op == opcode_C2)
&& (funct3 == funct3_C_SDSP)
&& ( (xl == misa_mxl_64)
|| (xl == misa_mxl_128)));
|| (cap_enc)));
RegName rs1 = reg_sp;
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_SD, op_STORE);
@@ -328,11 +328,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SDSP (MISA misa, Bit #(2) xl, Inst
return tuple2 (is_legal, instr);
end
endfunction
`endif
`ifdef RV128
`ifdef RV64
// SQSP: expands to SQ
function Tuple2 #(Bool, Instr) fv_decode_C_SQSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SQSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CSS-type
match { .funct3, .imm_at_12_7, .rs2, .op } = fv_ifields_CSS_type (instr_C);
@@ -341,7 +340,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SQSP (MISA misa, Bit #(2) xl, Inst
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C2)
&& (funct3 == funct3_C_SQSP)
&& (xl == misa_mxl_128));
&& (xl == misa_mxl_64)
&& (cap_enc));
RegName rs1 = reg_sp;
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_SQ, op_STORE);
@@ -353,7 +353,7 @@ endfunction
`ifdef ISA_F
// FSWSP: expands to FSW
function Tuple2 #(Bool, Instr) fv_decode_C_FSWSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_FSWSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CSS-type
match { .funct3, .imm_at_12_7, .rs2, .op } = fv_ifields_CSS_type (instr_C);
@@ -361,7 +361,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FSWSP (MISA misa, Bit #(2) xl, Ins
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C2)
&& (funct3 == funct3_C_FSWSP));
&& (funct3 == funct3_C_FSWSP)
&& (xl == misa_mxl_32)
&& (! cap_enc));
RegName rs1 = reg_sp;
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_FSW, op_STORE_FP);
@@ -373,7 +375,7 @@ endfunction
`ifdef ISA_D
// FSDSP: expands to FSD
function Tuple2 #(Bool, Instr) fv_decode_C_FSDSP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_FSDSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CSS-type
match { .funct3, .imm_at_12_7, .rs2, .op } = fv_ifields_CSS_type (instr_C);
@@ -382,8 +384,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FSDSP (MISA misa, Bit #(2) xl, Ins
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C2)
&& (funct3 == funct3_C_FSDSP)
&& ( (xl == misa_mxl_64)
|| (xl == misa_mxl_128)));
&& ( (xl == misa_mxl_32)
|| (! cap_enc)));
RegName rs1 = reg_sp;
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_FSD, op_STORE_FP);
@@ -397,7 +399,7 @@ endfunction
// 'C' Extension Register-Based Loads
// C_LW: expands to LW
function Tuple2 #(Bool, Instr) fv_decode_C_LW (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_LW (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CL-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rd, .op } = fv_ifields_CL_type (instr_C);
@@ -413,9 +415,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LW (MISA misa, Bit #(2) xl, Instr
end
endfunction
`ifdef RV64
// C_LD: expands to LD
function Tuple2 #(Bool, Instr) fv_decode_C_LD (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_LD (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CL-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rd, .op } = fv_ifields_CL_type (instr_C);
@@ -425,18 +426,17 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LD (MISA misa, Bit #(2) xl, Instr
&& (op == opcode_C0)
&& (funct3 == funct3_C_LD)
&& ( (xl == misa_mxl_64)
|| (xl == misa_mxl_128)));
|| (cap_enc)));
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_LD, rd, op_LOAD);
return tuple2 (is_legal, instr);
end
endfunction
`endif
`ifdef RV128
`ifdef RV64
// C_LQ: expands to LQ
function Tuple2 #(Bool, Instr) fv_decode_C_LQ (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_LQ (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CL-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rd, .op } = fv_ifields_CL_type (instr_C);
@@ -445,9 +445,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LQ (MISA misa, Bit #(2) xl, Instr
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C0)
&& (funct3 == funct3_C_LQ)
&& (xl == misa_mxl_128));
&& (xl == misa_mxl_64)
&& (cap_enc));
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_LQ, rd, op_LOAD);
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_LQ, rd, op_MISC_MEM);
return tuple2 (is_legal, instr);
end
@@ -456,7 +457,7 @@ endfunction
`ifdef ISA_F
// C_FLW: expands to FLW
function Tuple2 #(Bool, Instr) fv_decode_C_FLW (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_FLW (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CL-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rd, .op } = fv_ifields_CL_type (instr_C);
@@ -464,7 +465,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FLW (MISA misa, Bit #(2) xl, Inst
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C0)
&& (funct3 == funct3_C_FLW));
&& (funct3 == funct3_C_FLW)
&& (xl == misa_mxl_32)
&& (! cap_enc));
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_FLW, rd, op_LOAD_FP);
@@ -475,7 +478,7 @@ endfunction
`ifdef ISA_D
// C_FLD: expands to FLD
function Tuple2 #(Bool, Instr) fv_decode_C_FLD (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_FLD (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CL-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rd, .op } = fv_ifields_CL_type (instr_C);
@@ -484,8 +487,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FLD (MISA misa, Bit #(2) xl, Inst
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C0)
&& (funct3 == funct3_C_FLD)
&& ( (xl == misa_mxl_64)
|| (xl == misa_mxl_128)));
&& ( (xl == misa_mxl_32)
|| (! cap_enc)));
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_FLD, rd, op_LOAD_FP);
@@ -498,7 +501,7 @@ endfunction
// 'C' Extension Register-Based Stores
// C_SW: expands to SW
function Tuple2 #(Bool, Instr) fv_decode_C_SW (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SW (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CS-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rs2, .op } = fv_ifields_CS_type (instr_C);
@@ -514,9 +517,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SW (MISA misa, Bit #(2) xl, Instr
end
endfunction
`ifdef RV64
// C_SD: expands to SD
function Tuple2 #(Bool, Instr) fv_decode_C_SD (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SD (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CS-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rs2, .op } = fv_ifields_CS_type (instr_C);
@@ -524,18 +526,19 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SD (MISA misa, Bit #(2) xl, Instr
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C0)
&& (funct3 == funct3_C_SD));
&& (funct3 == funct3_C_SD)
&& ( (xl == misa_mxl_64)
|| (cap_enc)));
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_SD, op_STORE);
return tuple2 (is_legal, instr);
end
endfunction
`endif
`ifdef RV128
`ifdef RV64
// C_SQ: expands to SQ
function Tuple2 #(Bool, Instr) fv_decode_C_SQ (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SQ (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CS-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rs2, .op } = fv_ifields_CS_type (instr_C);
@@ -543,7 +546,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SQ (MISA misa, Bit #(2) xl, Instr
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C0)
&& (funct3 == funct3_C_SQ));
&& (funct3 == funct3_C_SQ)
&& (xl == misa_mxl_64)
&& (cap_enc));
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_SQ, op_STORE);
@@ -554,7 +559,7 @@ endfunction
`ifdef ISA_F
// C_FSW: expands to FSW
function Tuple2 #(Bool, Instr) fv_decode_C_FSW (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_FSW (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CS-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rs2, .op } = fv_ifields_CS_type (instr_C);
@@ -562,7 +567,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FSW (MISA misa, Bit #(2) xl, Inst
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C0)
&& (funct3 == funct3_C_FSW));
&& (funct3 == funct3_C_FSW)
&& (xl == misa_mxl_32)
&& (! cap_enc));
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_FSW, op_STORE_FP);
@@ -573,7 +580,7 @@ endfunction
`ifdef ISA_D
// C_FSD: expands to FSD
function Tuple2 #(Bool, Instr) fv_decode_C_FSD (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_FSD (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CS-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_5, .rs2, .op } = fv_ifields_CS_type (instr_C);
@@ -581,7 +588,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FSD (MISA misa, Bit #(2) xl, Inst
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C0)
&& (funct3 == funct3_C_FSD));
&& (funct3 == funct3_C_FSD)
&& ( (xl == misa_mxl_32)
|| (! cap_enc)));
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_FSD, op_STORE_FP);
@@ -595,7 +604,7 @@ endfunction
// C.J, C.JAL, C.JR, C.JALR, C.BEQZ, C.BNEZ
// C.J: expands to JAL
function Tuple2 #(Bool, Instr) fv_decode_C_J (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_J (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CJ-type
match { .funct3, .imm_at_12_2, .op } = fv_ifields_CJ_type (instr_C);
@@ -622,7 +631,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_J (MISA misa, Bit #(2) xl, Instr_
endfunction
// C.JAL: expands to JAL
function Tuple2 #(Bool, Instr) fv_decode_C_JAL (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_JAL (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CJ-type
match { .funct3, .imm_at_12_2, .op } = fv_ifields_CJ_type (instr_C);
@@ -650,7 +659,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_JAL (MISA misa, Bit #(2) xl, Inst
endfunction
// C.JR: expands to JALR
function Tuple2 #(Bool, Instr) fv_decode_C_JR (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_JR (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CR-type
match { .funct4, .rs1, .rs2, .op } = fv_ifields_CR_type (instr_C);
@@ -669,7 +678,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_JR (MISA misa, Bit #(2) xl, Instr
endfunction
// C.JALR: expands to JALR
function Tuple2 #(Bool, Instr) fv_decode_C_JALR (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_JALR (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CR-type
match { .funct4, .rs1, .rs2, .op } = fv_ifields_CR_type (instr_C);
@@ -689,7 +698,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_JALR (MISA misa, Bit #(2) xl, Ins
endfunction
// C.BEQZ: expands to BEQ
function Tuple2 #(Bool, Instr) fv_decode_C_BEQZ (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_BEQZ (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CB-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_2, .op } = fv_ifields_CB_type (instr_C);
@@ -708,7 +717,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_BEQZ (MISA misa, Bit #(2) xl, Ins
endfunction
// C.BNEZ: expands to BNE
function Tuple2 #(Bool, Instr) fv_decode_C_BNEZ (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_BNEZ (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CB-type
match { .funct3, .imm_at_12_10, .rs1, .imm_at_6_2, .op } = fv_ifields_CB_type (instr_C);
@@ -730,7 +739,7 @@ endfunction
// 'C' Extension Integer Constant-Generation
// C.LI: expands to ADDI
function Tuple2 #(Bool, Instr) fv_decode_C_LI (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_LI (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CI-type
match { .funct3, .imm_at_12, .rd, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -750,7 +759,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LI (MISA misa, Bit #(2) xl, Instr
endfunction
// C.LUI: expands to LUI
function Tuple2 #(Bool, Instr) fv_decode_C_LUI (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_LUI (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CI-type
match { .funct3, .imm_at_12, .rd, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -774,7 +783,7 @@ endfunction
// 'C' Extension Integer Register-Immediate Operations
// C.ADDI: expands to ADDI
function Tuple2 #(Bool, Instr) fv_decode_C_ADDI (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_ADDI (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CI-type
match { .funct3, .imm_at_12, .rd_rs1, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -794,7 +803,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDI (MISA misa, Bit #(2) xl, Ins
endfunction
// C.NOP: expands to ADDI
function Tuple2 #(Bool, Instr) fv_decode_C_NOP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_NOP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CI-type
match { .funct3, .imm_at_12, .rd_rs1, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -814,7 +823,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_NOP (MISA misa, Bit #(2) xl, Inst
endfunction
// C.ADDIW: expands to ADDIW
function Tuple2 #(Bool, Instr) fv_decode_C_ADDIW (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_ADDIW (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CI-type
match { .funct3, .imm_at_12, .rd_rs1, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -824,8 +833,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDIW (MISA misa, Bit #(2) xl, In
&& (op == opcode_C1)
&& (funct3 == funct3_C_ADDIW)
&& (rd_rs1 != 0)
&& ( (xl == misa_mxl_64)
|| (xl == misa_mxl_128)));
&& (xl == misa_mxl_64));
Bit #(12) imm12 = signExtend (imm6);
let instr = mkInstr_I_type (imm12, rd_rs1, f3_ADDIW, rd_rs1, op_OP_IMM_32);
@@ -835,7 +843,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDIW (MISA misa, Bit #(2) xl, In
endfunction
// C.ADDI16SP: expands to ADDI
function Tuple2 #(Bool, Instr) fv_decode_C_ADDI16SP (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_ADDI16SP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CI-type
match { .funct3, .imm_at_12, .rd_rs1, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -845,7 +853,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDI16SP (MISA misa, Bit #(2) xl,
&& (op == opcode_C1)
&& (funct3 == funct3_C_ADDI16SP)
&& (rd_rs1 == reg_sp)
&& (nzimm10 != 0));
&& (nzimm10 != 0)
&& (! cap_enc));
Bit #(12) imm12 = signExtend (nzimm10);
let instr = mkInstr_I_type (imm12, rd_rs1, f3_ADDI, rd_rs1, op_OP_IMM);
@@ -854,8 +863,29 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDI16SP (MISA misa, Bit #(2) xl,
end
endfunction
// C.CIncOffsetImm16CSP: expands to CIncOffsetImm
function Tuple2 #(Bool, Instr) fv_decode_C_CIncOffsetImm16CSP (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CI-type
match { .funct3, .imm_at_12, .rd_rs1, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
Bit #(10) nzimm10 = { imm_at_12, imm_at_6_2 [2:1], imm_at_6_2 [3], imm_at_6_2 [0], imm_at_6_2 [4], 4'b0 };
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C1)
&& (funct3 == funct3_C_CIncOffsetImm16CSP)
&& (rd_rs1 == reg_sp)
&& (nzimm10 != 0)
&& (cap_enc));
Bit #(12) imm12 = signExtend (nzimm10);
let instr = mkInstr_I_type (imm12, rd_rs1, f3_cap_CIncOffsetImmediate, rd_rs1, op_cap_Manip);
return tuple2 (is_legal, instr);
end
endfunction
// C.ADDI4SPN: expands to ADDI
function Tuple2 #(Bool, Instr) fv_decode_C_ADDI4SPN (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_ADDI4SPN (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CIW-type
match { .funct3, .imm_at_12_5, .rd, .op } = fv_ifields_CIW_type (instr_C);
@@ -864,7 +894,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDI4SPN (MISA misa, Bit #(2) xl,
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C0)
&& (funct3 == funct3_C_ADDI4SPN)
&& (nzimm10 != 0));
&& (nzimm10 != 0)
&& (! cap_enc));
RegName rs1 = reg_sp;
Bit #(12) imm12 = zeroExtend (nzimm10);
@@ -874,8 +905,29 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDI4SPN (MISA misa, Bit #(2) xl,
end
endfunction
// C.CIncOffsetImm4CSPN: expands to CIncOffsetImm
function Tuple2 #(Bool, Instr) fv_decode_C_CIncOffsetImm4CSPN (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CIW-type
match { .funct3, .imm_at_12_5, .rd, .op } = fv_ifields_CIW_type (instr_C);
Bit #(10) nzimm10 = { imm_at_12_5 [5:2], imm_at_12_5 [7:6], imm_at_12_5 [0], imm_at_12_5 [1], 2'b0 };
Bool is_legal = ((misa.c == 1'b1)
&& (op == opcode_C0)
&& (funct3 == funct3_C_CIncOffsetImm4CSPN)
&& (nzimm10 != 0)
&& (cap_enc));
RegName rs1 = reg_sp;
Bit #(12) imm12 = zeroExtend (nzimm10);
let instr = mkInstr_I_type (imm12, rs1, f3_cap_CIncOffsetImmediate, rd, op_cap_Manip);
return tuple2 (is_legal, instr);
end
endfunction
// C.SLLI: expands to SLLI
function Tuple2 #(Bool, Instr) fv_decode_C_SLLI (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SLLI (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CI-type
match { .funct3, .imm_at_12, .rd_rs1, .imm_at_6_2, .op } = fv_ifields_CI_type (instr_C);
@@ -898,7 +950,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SLLI (MISA misa, Bit #(2) xl, Ins
endfunction
// C.SRLI: expands to SRLI
function Tuple2 #(Bool, Instr) fv_decode_C_SRLI (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SRLI (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CB-type
match { .funct3, .imm_at_12_10, .rd_rs1, .imm_at_6_2, .op } = fv_ifields_CB_type (instr_C);
@@ -924,7 +976,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SRLI (MISA misa, Bit #(2) xl, Ins
endfunction
// C.SRAI: expands to SRAI
function Tuple2 #(Bool, Instr) fv_decode_C_SRAI (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SRAI (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CB-type
match { .funct3, .imm_at_12_10, .rd_rs1, .imm_at_6_2, .op } = fv_ifields_CB_type (instr_C);
@@ -950,7 +1002,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SRAI (MISA misa, Bit #(2) xl, Ins
endfunction
// C.ANDI: expands to ANDI
function Tuple2 #(Bool, Instr) fv_decode_C_ANDI (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_ANDI (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CB-type
match { .funct3, .imm_at_12_10, .rd_rs1, .imm_at_6_2, .op } = fv_ifields_CB_type (instr_C);
@@ -974,7 +1026,7 @@ endfunction
// 'C' Extension Integer Register-Register Operations
// C.MV: expands to ADD
function Tuple2 #(Bool, Instr) fv_decode_C_MV (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_MV (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
match { .funct4, .rd_rs1, .rs2, .op } = fv_ifields_CR_type (instr_C);
@@ -992,7 +1044,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_MV (MISA misa, Bit #(2) xl, Instr
endfunction
// C.ADD: expands to ADD
function Tuple2 #(Bool, Instr) fv_decode_C_ADD (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_ADD (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
match { .funct4, .rd_rs1, .rs2, .op } = fv_ifields_CR_type (instr_C);
@@ -1009,7 +1061,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADD (MISA misa, Bit #(2) xl, Inst
endfunction
// C.AND: expands to AND
function Tuple2 #(Bool, Instr) fv_decode_C_AND (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_AND (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CA-type
match { .funct6, .rd_rs1, .funct2, .rs2, .op } = fv_ifields_CA_type (instr_C);
@@ -1026,7 +1078,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_AND (MISA misa, Bit #(2) xl, Inst
endfunction
// C.OR: expands to OR
function Tuple2 #(Bool, Instr) fv_decode_C_OR (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_OR (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CA-type
match { .funct6, .rd_rs1, .funct2, .rs2, .op } = fv_ifields_CA_type (instr_C);
@@ -1043,7 +1095,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_OR (MISA misa, Bit #(2) xl, Instr
endfunction
// C.XOR: expands to XOR
function Tuple2 #(Bool, Instr) fv_decode_C_XOR (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_XOR (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CA-type
match { .funct6, .rd_rs1, .funct2, .rs2, .op } = fv_ifields_CA_type (instr_C);
@@ -1060,7 +1112,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_XOR (MISA misa, Bit #(2) xl, Inst
endfunction
// C.SUB: expands to SUB
function Tuple2 #(Bool, Instr) fv_decode_C_SUB (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SUB (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CA-type
match { .funct6, .rd_rs1, .funct2, .rs2, .op } = fv_ifields_CA_type (instr_C);
@@ -1077,7 +1129,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SUB (MISA misa, Bit #(2) xl, Inst
endfunction
// C.ADDW: expands to ADDW
function Tuple2 #(Bool, Instr) fv_decode_C_ADDW (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_ADDW (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CA-type
match { .funct6, .rd_rs1, .funct2, .rs2, .op } = fv_ifields_CA_type (instr_C);
@@ -1086,8 +1138,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDW (MISA misa, Bit #(2) xl, Ins
&& (op == opcode_C1)
&& (funct6 == funct6_C_ADDW)
&& (funct2 == funct2_C_ADDW)
&& ( (xl == misa_mxl_64)
|| (xl == misa_mxl_128)));
&& (xl == misa_mxl_64));
let instr = mkInstr_R_type (funct7_ADDW, rs2, rd_rs1, funct3_ADDW, rd_rs1, op_OP_32);
@@ -1096,7 +1147,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDW (MISA misa, Bit #(2) xl, Ins
endfunction
// C.SUBW: expands to SUBW
function Tuple2 #(Bool, Instr) fv_decode_C_SUBW (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_SUBW (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CA-type
match { .funct6, .rd_rs1, .funct2, .rs2, .op } = fv_ifields_CA_type (instr_C);
@@ -1105,8 +1156,7 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SUBW (MISA misa, Bit #(2) xl, Ins
&& (op == opcode_C1)
&& (funct6 == funct6_C_SUBW)
&& (funct2 == funct2_C_SUBW)
&& ( (xl == misa_mxl_64)
|| (xl == misa_mxl_128)));
&& ((xl == misa_mxl_64)));
let instr = mkInstr_R_type (funct7_SUBW, rs2, rd_rs1, funct3_SUBW, rd_rs1, op_OP_32);
@@ -1118,7 +1168,7 @@ endfunction
// 'C' Extension EBREAK
// C.EBREAK: expands to EBREAK
function Tuple2 #(Bool, Instr) fv_decode_C_EBREAK (MISA misa, Bit #(2) xl, Instr_C instr_C);
function Tuple2 #(Bool, Instr) fv_decode_C_EBREAK (MISA misa, Bit #(2) xl, Bool cap_enc, Instr_C instr_C);
begin
// Instr fields: CR-type
match { .funct4, .rd_rs1, .rs2, .op } = fv_ifields_CR_type (instr_C);

View File

@@ -15,85 +15,87 @@ Bit #(2) opcode_C0 = 2'b00;
Bit #(2) opcode_C1 = 2'b01;
Bit #(2) opcode_C2 = 2'b10;
Bit #(3) funct3_C_LWSP = 3'b_010;
Bit #(3) funct3_C_LDSP = 3'b_011; // RV64 and RV128
Bit #(3) funct3_C_LQSP = 3'b_001; // RV128
Bit #(3) funct3_C_FLWSP = 3'b_011; // RV32FC
Bit #(3) funct3_C_FLDSP = 3'b_001; // RV32DC, RV64DC
Bit #(3) funct3_C_LWSP = 3'b_010;
Bit #(3) funct3_C_LDSP = 3'b_011; // RV64 and RV128
Bit #(3) funct3_C_LQSP = 3'b_001; // RV128
Bit #(3) funct3_C_FLWSP = 3'b_011; // RV32FC
Bit #(3) funct3_C_FLDSP = 3'b_001; // RV32DC, RV64DC
Bit #(3) funct3_C_SWSP = 3'b_110;
Bit #(3) funct3_C_SWSP = 3'b_110;
Bit #(3) funct3_C_SQSP = 3'b_101; // RV128
Bit #(3) funct3_C_FSDSP = 3'b_101; // RV32DC, RV64DC
Bit #(3) funct3_C_SQSP = 3'b_101; // RV128
Bit #(3) funct3_C_FSDSP = 3'b_101; // RV32DC, RV64DC
Bit #(3) funct3_C_SDSP = 3'b_111; // RV64 and RV128
Bit #(3) funct3_C_FSWSP = 3'b_111; // RV32FC
Bit #(3) funct3_C_SDSP = 3'b_111; // RV64 and RV128
Bit #(3) funct3_C_FSWSP = 3'b_111; // RV32FC
Bit #(3) funct3_C_LQ = 3'b_001; // RV128
Bit #(3) funct3_C_FLD = 3'b_001; // RV32DC, RV64DC
Bit #(3) funct3_C_LQ = 3'b_001; // RV128
Bit #(3) funct3_C_FLD = 3'b_001; // RV32DC, RV64DC
Bit #(3) funct3_C_LW = 3'b_010;
Bit #(3) funct3_C_LW = 3'b_010;
Bit #(3) funct3_C_LD = 3'b_011; // RV64 and RV128
Bit #(3) funct3_C_FLW = 3'b_011; // RV32FC
Bit #(3) funct3_C_LD = 3'b_011; // RV64 and RV128
Bit #(3) funct3_C_FLW = 3'b_011; // RV32FC
Bit #(3) funct3_C_FSD = 3'b_101; // RV32DC, RV64DC
Bit #(3) funct3_C_SQ = 3'b_101; // RV128
Bit #(3) funct3_C_FSD = 3'b_101; // RV32DC, RV64DC
Bit #(3) funct3_C_SQ = 3'b_101; // RV128
Bit #(3) funct3_C_SW = 3'b_110;
Bit #(3) funct3_C_SW = 3'b_110;
Bit #(3) funct3_C_SD = 3'b_111; // RV64 and RV128
Bit #(3) funct3_C_FSW = 3'b_111; // RV32FC
Bit #(3) funct3_C_SD = 3'b_111; // RV64 and RV128
Bit #(3) funct3_C_FSW = 3'b_111; // RV32FC
Bit #(3) funct3_C_JAL = 3'b_001; // RV32
Bit #(3) funct3_C_J = 3'b_101;
Bit #(3) funct3_C_BEQZ = 3'b_110;
Bit #(3) funct3_C_BNEZ = 3'b_111;
Bit #(3) funct3_C_JAL = 3'b_001; // RV32
Bit #(3) funct3_C_J = 3'b_101;
Bit #(3) funct3_C_BEQZ = 3'b_110;
Bit #(3) funct3_C_BNEZ = 3'b_111;
Bit #(4) funct4_C_JR = 4'b_1000;
Bit #(4) funct4_C_JALR = 4'b_1001;
Bit #(4) funct4_C_JR = 4'b_1000;
Bit #(4) funct4_C_JALR = 4'b_1001;
Bit #(3) funct3_C_LI = 3'b_010;
Bit #(3) funct3_C_LUI = 3'b_011; // RV64 and RV128
Bit #(3) funct3_C_LI = 3'b_010;
Bit #(3) funct3_C_LUI = 3'b_011; // RV64 and RV128
Bit #(3) funct3_C_NOP = 3'b_000;
Bit #(3) funct3_C_ADDI = 3'b_000;
Bit #(3) funct3_C_ADDIW = 3'b_001;
Bit #(3) funct3_C_ADDI16SP = 3'b_011;
Bit #(3) funct3_C_ADDI4SPN = 3'b_000;
Bit #(3) funct3_C_SLLI = 3'b_000;
Bit #(3) funct3_C_NOP = 3'b_000;
Bit #(3) funct3_C_ADDI = 3'b_000;
Bit #(3) funct3_C_ADDIW = 3'b_001;
Bit #(3) funct3_C_ADDI16SP = 3'b_011;
Bit #(3) funct3_C_CIncOffsetImm16CSP = 3'b_011;
Bit #(3) funct3_C_ADDI4SPN = 3'b_000;
Bit #(3) funct3_C_CIncOffsetImm4CSPN = 3'b_000;
Bit #(3) funct3_C_SLLI = 3'b_000;
Bit #(3) funct3_C_SRLI = 3'b_100;
Bit #(2) funct2_C_SRLI = 2'b_00;
Bit #(3) funct3_C_SRLI = 3'b_100;
Bit #(2) funct2_C_SRLI = 2'b_00;
Bit #(3) funct3_C_SRAI = 3'b_100;
Bit #(2) funct2_C_SRAI = 2'b_01;
Bit #(3) funct3_C_SRAI = 3'b_100;
Bit #(2) funct2_C_SRAI = 2'b_01;
Bit #(3) funct3_C_ANDI = 3'b_100;
Bit #(2) funct2_C_ANDI = 2'b_10;
Bit #(3) funct3_C_ANDI = 3'b_100;
Bit #(2) funct2_C_ANDI = 2'b_10;
Bit #(4) funct4_C_MV = 4'b_1000;
Bit #(4) funct4_C_ADD = 4'b_1001;
Bit #(4) funct4_C_MV = 4'b_1000;
Bit #(4) funct4_C_ADD = 4'b_1001;
Bit #(6) funct6_C_AND = 6'b_100_0_11;
Bit #(2) funct2_C_AND = 2'b_11;
Bit #(6) funct6_C_AND = 6'b_100_0_11;
Bit #(2) funct2_C_AND = 2'b_11;
Bit #(6) funct6_C_OR = 6'b_100_0_11;
Bit #(2) funct2_C_OR = 2'b_10;
Bit #(6) funct6_C_OR = 6'b_100_0_11;
Bit #(2) funct2_C_OR = 2'b_10;
Bit #(6) funct6_C_XOR = 6'b_100_0_11;
Bit #(2) funct2_C_XOR = 2'b_01;
Bit #(6) funct6_C_XOR = 6'b_100_0_11;
Bit #(2) funct2_C_XOR = 2'b_01;
Bit #(6) funct6_C_SUB = 6'b_100_0_11;
Bit #(2) funct2_C_SUB = 2'b_00;
Bit #(6) funct6_C_SUB = 6'b_100_0_11;
Bit #(2) funct2_C_SUB = 2'b_00;
Bit #(6) funct6_C_ADDW = 6'b_100_1_11;
Bit #(2) funct2_C_ADDW = 2'b_01;
Bit #(6) funct6_C_ADDW = 6'b_100_1_11;
Bit #(2) funct2_C_ADDW = 2'b_01;
Bit #(6) funct6_C_SUBW = 6'b_100_1_11;
Bit #(2) funct2_C_SUBW = 2'b_00;
Bit #(6) funct6_C_SUBW = 6'b_100_1_11;
Bit #(2) funct2_C_SUBW = 2'b_00;
Bit #(4) funct4_C_EBREAK = 4'b_1001;
Bit #(4) funct4_C_EBREAK = 4'b_1001;
// ================================================================
// Functions to extract instruction fields from 'C' (compressed) instructions

View File

@@ -626,7 +626,7 @@ module mkFetchStage(FetchStage);
end
end else if (is_16b_inst(frag.inst_frag)) begin // 16-bit instruction
new_pick = tagged Valid fetch3_2_instC(frag,
fv_decode_C (misa, misa_mxl_64, frag.inst_frag),
fv_decode_C (misa, misa_mxl_64, getFlags(decompressPc(frag.pc))==1, frag.inst_frag),
zeroExtend(frag.inst_frag));
end
end