jalr
Jump and link register
This instruction is defined by:
-
I, version >= 0
This instruction is included in the following profiles:
-
MockProfile 64-bit Unpriv (Mandatory)
-
MockProfile 64-bit S-mode (Mandatory)
-
RVA20U64 (Mandatory)
-
RVA22U64 (Mandatory)
-
RVI20U32 (Mandatory)
-
RVI20U64 (Mandatory)
Synopsis
Jump to an address formed by adding rs1 to a signed offset, and store the return address in rd.
Decode Variables
Bits<12> imm = $encoding[31:20];
Bits<5> rs1 = $encoding[19:15];
Bits<5> rd = $encoding[11:7];
Execution
-
IDL
-
Sail
XReg returnaddr;
returnaddr = $pc + 4;
jump(X[rs1] + imm);
X[rd] = returnaddr;
{
/* For the sequential model, the memory-model definition doesn't work directly
* if rs1 = rd. 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 reordered definition to improve simulator
* performance.
*/
let t : xlenbits = X(rs1) + 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(rd) = get_next_pc();
set_next_pc(target);
RETIRE_SUCCESS
}
}
}
}