anchor.diff:          endcase);
   endfunction
   
  -function Maybe#(ExecFunc) toExecFuncA(Instruction inst);
  -    return (case (inst) matches
  -            // RV32A
  +function Maybe#(ExecFunc) toExecFuncRV32A(Instruction inst);
  +    return (case (inst) matches
               `AMOADD_W:  tagged Valid (tagged Mem RVMemInst{op: tagged Amo Add,  size: W, isUnsigned: False});
               `AMOXOR_W:  tagged Valid (tagged Mem RVMemInst{op: tagged Amo Xor,  size: W, isUnsigned: False});
               `AMOOR_W:   tagged Valid (tagged Mem RVMemInst{op: tagged Amo Or,   size: W, isUnsigned: False});
  
positive.code:             `DIVU:      tagged Valid (tagged MulDiv MulDivInst{func: Div,  w: False, sign: Unsigned});
              `REM:       tagged Valid (tagged MulDiv MulDivInst{func: Rem,  w: False, sign: Signed});
              `REMU:      tagged Valid (tagged MulDiv MulDivInst{func: Rem,  w: False, sign: Unsigned});
              // RV64M Only
              `MULW:      tagged Valid (tagged MulDiv MulDivInst{func: Mul,  w: True,  sign: Signed});
              `DIVW:      tagged Valid (tagged MulDiv MulDivInst{func: Div,  w: True,  sign: Signed});
              `DIVUW:     tagged Valid (tagged MulDiv MulDivInst{func: Div,  w: True,  sign: Unsigned});
  
negative.code:         endcase);
  endfunction
  
  function Maybe#(ExecFunc) toExecFuncRV64D(Instruction inst);
      return (case (inst) matches
              `FCVT_L_D:  tagged Valid (tagged Fpu FpuInst{func: FCvt_LF,  precision: Double});
              `FCVT_LU_D: tagged Valid (tagged Fpu FpuInst{func: FCvt_LUF, precision: Double});
              `FMV_X_D:   tagged Valid (tagged Fpu FpuInst{func: FMv_XF,   precision: Double});
              `FCVT_D_L:  tagged Valid (tagged Fpu FpuInst{func: FCvt_FL,  precision: Double});
              `FCVT_D_LU: tagged Valid (tagged Fpu FpuInst{func: FCvt_FLU, precision: Double});
              `FMV_D_X:   tagged Valid (tagged Fpu FpuInst{func: FMv_FX,   precision: Double});
  
              default:    tagged Invalid;
          endcase);
  endfunction
  
  // This returns a valid result if the instruction is legal, otherwise it
  // returns a tagged invalid.
  (* noinline *)
  function Maybe#(RVDecodedInst) decodeInst(Instruction inst);
      // Construct a vector of all the results
      // We will apply a fold function on this vector to find the valid result
      let decoderResults = vec(
              toExecFuncRV32I(inst),
              toExecFuncRV64I(inst),
  `ifdef m
              toExecFuncRV32M(inst),
              toExecFuncRV64M(inst),
  `endif
  `ifdef a
              toExecFuncRV32A(inst),
              toExecFuncRV64A(inst),
  `endif
  `ifdef f
              toExecFuncRV32F(inst),
              toExecFuncRV64F(inst),
  `endif
  `ifdef d
              toExecFuncRV32D(inst),
              toExecFuncRV64D(inst),
  `endif
              toExecFuncPriv(inst)
          );
  
      // This fold is equivalent to going down the list of decoder results and
      // returning the first valid result
      function Maybe#(t) fold_op(Maybe#(t) x, Maybe#(t) y) provisos (Bits#(t, tSz));
          return isValid(x) ? x : y;
      endfunction
      let execFunc = fold(fold_op, decoderResults);
  
      if (execFunc matches tagged Valid .validExecFunc) begin
          InstType instType = toInstType(inst);
  