sret

Supervisor Mode Return from Trap

Returns from supervisor mode after handling a trap.

When sret is allowed to execute, its behavior depends on whether or not the current privilege mode is virtualized.

When the current privilege mode is (H)S-mode or M-mode

sret sets hstatus = 0, mstatus.SPP = 0, mstatus.SIE = mstatus.SPIE, and mstatus.SPIE = 1, changes the privilege mode according to the table below, and then jumps to the address in sepc.

Table 1. Next privilege mode following an sret in (H)S-mode or M-mode
mstatus.SPP hstatus.SPV Mode after sret

0

0

U-mode

0

1

VU-mode

1

0

(H)S-mode

1

1

VS-mode

When the current privilege mode is VS-mode

sret sets vsstatus.SPP = 0, vsstatus.SIE = vstatus.SPIE, and vsstatus.SPIE = 1, changes the privilege mode according to the table below, and then jumps to the address in vsepc.

Table 2. Next privilege mode following an sret in (H)S-mode or M-mode
vsstatus.SPP Mode after sret

0

VU-mode

1

VS-mode

Assembly format

`sret `

Decode Variables

Execution

  • IDL

  • Sail

if (implemented?(ExtensionName::H)) {
  if (mstatus.TSR == 1'b0 && hstatus.VTSR == 1'b0) {
    if (mode() == PrivilegeMode::U) {
      raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
    } else if (mode() == PrivilegeMode::VU) {
      raise(ExceptionCode::VirtualInstruction, mode(), $encoding);
    }
  } else if (mstatus.TSR == 1'b0 && hstatus.VTSR == 1'b1) {
    if (mode() == PrivilegeMode::U) {
      raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
    } else if (mode() == PrivilegeMode::VU || mode() == PrivilegeMode::VS) {
      raise(ExceptionCode::VirtualInstruction, mode(), $encoding);
    }
  } else if (mstatus.TSR == 1'b1 && hstatus.VTSR == 1'b0) {
    if (mode() == PrivilegeMode::U || mode() == PrivilegeMode::S) {
      raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
    } else if (mode() == PrivilegeMode::VU) {
      raise(ExceptionCode::VirtualInstruction, mode(), $encoding);
    }
  } else if (mstatus.TSR == 1'b1 && hstatus.VTSR == 1'b1) {
    if (mode() == PrivilegeMode::U || mode() == PrivilegeMode::S) {
      raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
    } else if (mode() == PrivilegeMode::VU || mode() == PrivilegeMode::VS) {
      raise(ExceptionCode::VirtualInstruction, mode(), $encoding);
    }
  }
} else {
  if (mode() == PrivilegeMode::U) {
    raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
  }
}
if (!virtual_mode?()) {
  if (implemented?(ExtensionName::H)) {
    if (hstatus.SPV == 1'b1) {
      if (mstatus.SPP == 1'b1) {
        set_mode(PrivilegeMode::VS);
      } else {
        set_mode(PrivilegeMode::VU);
      }
    } else {
      if (mstatus.SPP == 1'b1) {
        set_mode(PrivilegeMode::S);
      } else {
        set_mode(PrivilegeMode::U);
      }
    }
    hstatus.SPV = 0;
  } else {
    if (mstatus.SPP == 1'b1) {
      set_mode(PrivilegeMode::S);
    } else {
      set_mode(PrivilegeMode::U);
    }
  }
  mstatus.SIE = mstatus.SPIE;
  mstatus.SPIE = 1;
  mstatus.SPP = 2'b00;
  $pc = $bits(sepc);
} else {
  if (mstatus.TSR == 1'b1) {
    raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
  }
  vsstatus.SPP = 0;
  vsstatus.SIE = vsstatus.SPIE;
  vsstatus.SPIE = 1;
  $pc = $bits(vsepc);
}
{
  let sret_illegal : bool = match cur_privilege {
    User       => true,
    Supervisor => not(haveSupMode ()) | mstatus.TSR() == 0b1,
    Machine    => not(haveSupMode ())
  };
  if   sret_illegal
  then { handle_illegal(); RETIRE_FAIL }
  else if not(ext_check_xret_priv (Supervisor))
  then { ext_fail_xret_priv(); RETIRE_FAIL }
  else {
    set_next_pc(exception_handler(cur_privilege, CTL_SRET(), PC));
    RETIRE_SUCCESS
  }
}

Exceptions

This instruction may result in the following synchronous exceptions:

  • IllegalInstruction

  • VirtualInstruction

Encoding

svg

Defining extension

S, version >= S@1.11.0

Access

M

Always

Access is determined as follows:

mstatus.TSR

hstatus.VTSR

Behavior when executed from:

M-mode

U-mode

(H)S-mode

VU-mode

VS-mode

0

0

executes

Illegal Instruction

executes

Virtual Instruction

executes

0

1

executes

Illegal Instruction

executes

Virtual Instruction

Virtual Instruction

1

0

executes

Illegal Instruction

Illegal Instruction

Virtual Instruction

executes

1

1

executes

Illegal Instruction

Illegal Instruction

Virtual Instruction

Virtual Instruction

Containing profiles

  • Mandatory: RVA20S64, RVA22S64, RVA23M64, RVA23S64, RVB23M64, RVB23S64

  • Optional: MockProfile 64-bit S-mode