mnret

Machine mode resume from the RNMI or Double Trap handler

This instruction is defined by:

Encoding

svg

Synopsis

MNRET is an M-mode-only instruction that uses the values in mnepc and mnstatus to return to the program counter, privilege mode, and virtualization mode of the interrupted context. This instruction also sets mnstatus.NMIE. If MNRET changes the privilege mode to a mode less privileged than M, it also sets mstatus.MPRV to 0. If the Zicfilp extension is implemented, then if the new privileged mode is y, MNRET sets ELP to the logical AND of yLPE (see Section 22.1.1) and mnstatus.MNPELP.

Access

M HS U VS VU

Always

Always

Always

Always

Always

Decode Variables

Execution

  • Pruned, XLEN == 64

  • Original

CSR[mstatus].MPRV = 0;

CSR[mnstatus].NMIE = 1'b1;
set_mode(PrivilegeMode::U);
CSR[mnstatus].MNPP = 2'd0;
$pc = $bits(CSR[CSR[mnepc]]);
if (CSR[mnstatus].MNPP != 2'b11) {
  if (implemented?(ExtensionName::U)) {
    CSR[mstatus].MPRV = 0;
  }
  if (implemented?(ExtensionName::Smdbltrp)) {
    if (xlen() == 64) {
      CSR[mstatus].MDT = 1'b0;
    } else {
      CSR[mstatush].MDT = 1'b0;
    }
  }
}
CSR[mnstatus].NMIE = 1'b1;
if (CSR[mnstatus].MNPP == 2'b00) {
  set_mode(PrivilegeMode::U);
} else if (CSR[mnstatus].MNPP == 2'b01) {
  set_mode(PrivilegeMode::S);
} else if (CSR[mnstatus].MNPP == 2'b11) {
  set_mode(PrivilegeMode::M);
}
CSR[mnstatus].MNPP = implemented?(ExtensionName::U) ? 2'b00 : 2'b11;
$pc = $bits(CSR[CSR[mnepc]]);