Fix floating point illegal handling

As well as clarifying the logic in the main decode function (no
functionality change), this also fixes some cases that should be
illegal but weren't caught in the memory instructions.
This commit is contained in:
Peter Rugg
2025-01-15 09:56:45 +00:00
committed by PeterRugg
parent 3fd8f22f66
commit 6f30f2b703

View File

@@ -48,7 +48,7 @@ import ISA_Decls_CHERI::*;
Bit#(3) memWU = 3'b110;
// Smaller decode functions
function Maybe#(MemInst) decodeMemInst(Instruction inst, Bool cap_mode);
function Maybe#(MemInst) decodeMemInst(Instruction inst, Bool cap_mode, RiscVISASubset isa);
Bool illegalInst = False;
Opcode opcode = unpackOpcode(inst[6:0]);
let funct5 = inst[31:27];
@@ -95,6 +95,14 @@ function Maybe#(MemInst) decodeMemInst(Instruction inst, Bool cap_mode);
Bool capWidth = (mem_func != Ld && funct3 == f3_SQ)
|| (opcode == opcMiscMem && funct3 == f3_LQ);
Bool illegalFP = (opcode == opcStoreFp || opcode == opcLoadFp)
&& !( (funct3 == memW && isa.f)
|| (funct3 == memD && isa.d));
if (illegalFP) begin
illegalInst = True;
end
if (capWidth && amo_func != None && amo_func != Swap) begin
illegalInst = True; // Don't support atomic cap arithmetic
end
@@ -306,6 +314,9 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
// For "xCHERI" ISA extension
let funct5rs2 = inst[ 24 : 20 ];
// For floating point instructions: is the fmt field in the current isa
Bool fpFmtInISA = (isa.f && fmt == fmtS) || (isa.d && fmt == fmtD);
ImmData immI = signExtend(inst[31:20]);
ImmData immS = signExtend({ inst[31:25], inst[11:7] });
ImmData immB = signExtend({ inst[31], inst[7], inst[30:25], inst[11:8], 1'b0});
@@ -314,7 +325,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
ImmData immIunsigned = zeroExtend(inst[31:20]);
// Results of mini-decoders
Maybe#(MemInst) mem_inst = decodeMemInst(inst, cap_mode);
Maybe#(MemInst) mem_inst = decodeMemInst(inst, cap_mode, isa);
Maybe#(MemInst) exp_bnds_mem_inst = decodeExplicitBoundsMemInst(inst);
case (opcode)
@@ -661,7 +672,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
// Instructions for "F" and "D" ISA extensions - FPU
opcOpFp: begin
if (!((fmt == fmtS && !isa.f) || (fmt == fmtD && !isa.d) || (fmt != fmtS && fmt != fmtD))) begin
if (fpFmtInISA) begin
// Instruction is supported
dInst.iType = Fpu;
regs.dst = Valid(tagged Fpu rd);
@@ -730,7 +741,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
end
opcLoadFp: begin
// check if instruction is supported
// FIXME: Check more cases
if (isa.f || isa.d) begin
// Same decode logic as Int Ld
dInst.iType = Ld;
@@ -746,7 +756,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
end
opcStoreFp: begin
// check if instruction is supported
// FIXME: Check more cases
if (isa.f || isa.d) begin
// Same decode logic as Int St
dInst.iType = St;
@@ -761,11 +770,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
end
end
opcFmadd, opcFmsub, opcFnmsub, opcFnmadd: begin
// check if instruction is supported
if (!((fmt == fmtS && !isa.f) ||
(fmt == fmtD && !isa.d) ||
(fmt != fmtS && fmt != fmtD))) begin
// Instruction is supported
if (fpFmtInISA) begin
dInst.iType = Fpu;
Maybe#(FpuFunc) mFunc = case (opcode)
opcFmadd: Valid(FMAdd);