What is the definition of JAL in RISC-V and how does one use it?

winnie99 picture winnie99 · Oct 28, 2018 · Viewed 14.6k times · Source

I don't get how JAL works in RISC-V as I've been seeing multiple conflicting definitions. For example, if I refer to this website: https://rv8.io/isa.html

It says that: JAL rd,offset has the 3rd argument as the offset, but there are some cases that shows JAL rd, imm instead. What is the difference?

It seems that JAL is supposed to take a function and return its output in rd (which I don't know why some sources has called it ra and rd at the same time). But if that's the case, what is the subroutine or the function? rd seems to be defined as the register destination, and imm seems to be just an integer..

Really confused please help.

Answer

Bruce Hoult picture Bruce Hoult · Oct 29, 2018

In the jal instruction imm (or imm20) is a 20 bit binary number.

offset is the interpretation of imm by the jal instruction: the contents of imm are shifted left by 1 position and then sign-extended to the size of an address (32 or 64 bits, currently), thus making an integer with a value of -1 million (approximately) to +1 million.

This offset integer is added to the address of the jal instruction itself to get the address of the function you want to call. This new address is put into the PC and program execution resumes with whatever instruction is located at that address.

At the same time, the address of the instruction following the jal is stored into CPU register rd. The function being called will presumably later use this to return, using a jalr rn instruction.

The RISC-V hardware allows any of the 32 integer registers to be given as rd. If register 0 (x0) is given as rd then the return address is discarded and you effectively have a +/1 MB goto rather than a function call.

The standard RISC-V ABI (a software convention, nothing to do with hardware) specifies that for normal functions rd should be register 1 (x1), which is then commonly known as ra (Return Address). Register 5 (x5) is also commonly used for special runtime library functions, such as special functions to save and restore registers at the start and end of functions.

The RISC-V instruction set manual suggests that CPU designers might choose to add special hardware (a return address stack) to make strictly nested pairs of jal x1/x5,offset and `jalr x1/x5' run more quickly than would otherwise be expected, so there can be an advantage to following the standard ABI. However, the program will work correctly even if other registers are used.