step  R reset  Space run
PC 0x00000000 · step 0
ADDR INSTRUCTION
Registers show all
Current instruction · encoding
Select a program and press Step → or key to begin.

JAL — Jump and Link

UJ-format · opcode 1101111 · PC-relative offset · range ±1 MB · stores PC+4 in rd
immediate (scrambled) rd (dest register) opcode
i[20]
imm[10:1]
i[11]
imm[19:12]
rd
opcode
3130 · · 212019 · · · 1211 · 76 · · 0

Immediate bit reconstruction

inst[31]imm[20](sign bit — same position as B-type for shared sign-ext hardware)
inst[30:21]imm[10:1](main body, 10 bits)
inst[20]imm[11](swapped to reduce critical path in decode)
inst[19:12]imm[19:12](upper body)
final 21-bit signed offset · bit[0] always 0 (not stored) · range ±1 MB

Target: PC + sign_extend(imm) — always PC-relative, no dependency on upper address bits.

The scrambling is designed so that the sign bit (imm[20]) is always at inst[31], shared across J, B, I, and U formats — hardware sign-extension logic is reused.

Bit 0 of the immediate is never stored because RISC-V instructions are at minimum 2-byte aligned. The hardware always appends a 0.

JALR — Jump and Link Register

I-format · opcode 1100111 · funct3=000 · indirect jump: (rs1 + imm) AND ~1
imm[11:0] rs1 (base register) funct3 rd opcode
imm[11:0]
rs1
f3
rd
opcode
31 · · · 2019 · 1514 · 1211 · 76 · 0

Target: (rs1 + sign_extend(imm[11:0])) AND ~1

The AND ~1 operation clears bit 0 of the computed address — a hardware guarantee that PC remains 2-byte aligned, regardless of register contents. (Unlike MIPS JR, which can fault on odd addresses.)

The 12-bit signed immediate allows ±2 KB range around the base register. The register itself can hold any address — enabling arbitrary far jumps.

When rd = x0: return address is silently discarded (x0 is hardwired 0). This is how ret and jr pseudos work.

Instruction Mapping: MIPS → RISC-V

MIPSRISC-V canonicalABI pseudoKey difference
J target JAL x0, offset j offset RISC-V uses PC-relative offset; MIPS uses absolute region-relative. rd=x0 discards link.
JAL target JAL x1, offset call sym MIPS implicitly uses $31; RISC-V makes rd explicit. For far calls, assembler expands to AUIPC + JALR.
JR $rs JALR x0, rs, 0 jr rs RISC-V forces LSB=0 via AND~1. MIPS JR on odd address triggers Address Error exception.
JALR $rd, $rs JALR rd, rs1, imm RISC-V adds a 12-bit immediate offset. MIPS JALR implicitly uses $31 if $rd omitted.

Key Behavioral Differences

ADDR

MIPS J-type: Target = { PC[31:28], instr_index[25:0], 2'b00 }. The upper 4 bits come from the current PC — jumps cannot cross 256 MB boundaries.
RISC-V JAL: Target = PC + sign_extend(imm). Purely PC-relative, ±1 MB. No region dependency.

IMM

MIPS: 26-bit unsigned instr_index — only forward wrap-around is possible.
RISC-V JAL: 21-bit signed offset, bit-scrambled to share sign-extension logic with B-type branches. Bit 0 always 0 (not stored).

LSB

RISC-V JALR always clears bit 0 of the computed target (AND ~1) — enforced in hardware. The result is always 2-byte aligned regardless of register value.
MIPS JR does not mask the low bit; an odd rs value triggers a hardware exception.

x0

RISC-V's x0 is hardwired to 0 — writes are silently discarded. This enables JAL x0, offset (unconditional jump, no link) and JALR x0, rs, 0 (pure indirect jump). MIPS requires a separate opcode for each behavior.

FAR

Far calls beyond ±1 MB: Use AUIPC x1, hi20(sym−PC) + JALR x1, x1, lo12(sym−PC). The assembler pseudo call sym selects between plain JAL (near) and this two-instruction sequence (far) automatically.

Register Conventions (ABI)

RoleMIPSRISC-V
Return address$ra ($31), implicit in JALra (x1), explicit rd field
Stack pointer$sp ($29)sp (x2)
Args / return values$a0–$a3, $v0–$v1a0–a7 (x10–x17)
Temporaries (caller-saved)$t0–$t9t0–t6 (x5–x7, x28–x31)
Saved (callee-saved)$s0–$s7s0–s11 (x8–x9, x18–x27)
Zero (hardwired)$zero ($0)zero (x0)

Pseudo-instructions are assembler conveniences — they expand to one or two real RISC-V instructions at assembly time. Click any card to expand.

ret Return from a function call
ret
JALR x0, x1, 0

Jumps to the address stored in ra (x1) — placed there by the calling JAL x1, .... rd=x0 discards the new return address (x0 is hardwired 0 — the write is a no-op). The hardware AND ~1 clears the LSB for alignment.

call sym Far function call (beyond ±1 MB)
call sym
AUIPC x1, hi20(sym − PC)
JALR x1, x1, lo12(sym − PC)

AUIPC (Add Upper Immediate to PC) loads the upper 20 bits of the PC-relative offset into ra. JALR then adds the lower 12 bits and jumps. Together they cover the full 32-bit address space relative to PC. For near calls (±1 MB), the assembler emits plain JAL x1, sym instead.

jr rs Indirect jump via register (no link)
jr rs
JALR x0, rs, 0

Direct equivalent of MIPS JR. Jumps to address in register rs, offset 0. rd=x0 means no link is stored. Used for computed jumps: function pointers, jump tables, dynamic dispatch. The AND ~1 alignment guarantee is still applied.

j offset Unconditional direct jump (no link)
j offset
JAL x0, offset

MIPS J equivalent. Uses JAL with rd=x0 to discard the return address. PC-relative, ±1 MB range. Because x0 is hardwired to 0, the write is a true no-op — no architectural state changes except PC.

li rd, imm Load immediate — often used to set a jump target before jr
li rd, imm
ADDI rd, x0, imm  (if |imm| ≤ 2047)
LUI rd, hi20 + ADDI rd, rd, lo12  (larger values)

Not a jump instruction itself, but critical when paired with jr. For small addresses a single ADDI suffices. For full 32-bit addresses (like jump table entries or function pointers), LUI + ADDI are needed to fill all 32 bits.