jalr
Jump and link register
This instruction is defined by:
-
I, version >= I@2.1.0
This instruction is included in the following profiles:
-
MockProfile 64-bit S-mode (Mandatory)
-
MockProfile 64-bit Unpriv (Mandatory)
-
RVA20S64 (Mandatory)
-
RVA20U64 (Mandatory)
-
RVA22S64 (Mandatory)
-
RVA22U64 (Mandatory)
-
RVA23S64 (Mandatory)
-
RVA23U64 (Mandatory)
-
RVB23S64 (Mandatory)
-
RVB23U64 (Mandatory)
-
RVI20U32 (Mandatory)
-
RVI20U64 (Mandatory)
Synopsis
Jump to an address formed by adding xs1 to a signed offset then clearing the least significant bit, and store the return address in xd.
Decode Variables
Bits<12> imm = $encoding[31:20];
Bits<5> xs1 = $encoding[19:15];
Bits<5> xd = $encoding[11:7];
Execution
-
IDL
-
Sail
XReg returnaddr;
returnaddr = $pc + 4;
jump((X[xs1] + $signed(imm)) & ~XLEN'1);
X[xd] = returnaddr;
{
/* For the sequential model, the memory-model definition doesn't work directly
* if xs1 = xd. We would effectively have to keep a regfile for reads and another for
* writes, and swap on instruction completion. This could perhaps be optimized in
* some manner, but for now, we just keep a reoxdered definition to improve simulator
* performance.
*/
let t : xlenbits = X(xs1) + sign_extend(imm);
/* Extensions get the first checks on the prospective target address. */
match ext_control_check_addr(t) {
Ext_ControlAddr_Error(e) => {
ext_handle_control_check_error(e);
RETIRE_FAIL
},
Ext_ControlAddr_OK(addr) => {
let target = [addr with 0 = bitzero]; /* clear addr[0] */
if bit_to_bool(target[1]) & not(extension("C")) then {
handle_mem_exception(target, E_Fetch_Addr_Align());
RETIRE_FAIL
} else {
X(xd) = get_next_pc();
set_next_pc(target);
RETIRE_SUCCESS
}
}
}
}