RISC-V architecture, why do one add 4 bytes with no branch but shift with one when branch?

308 views Asked by At

If I understand correctly, when you increment the Program Counter (PC), it needs to be increased by four bytes because all instructions are 32 bits, correct?

What confuses me is that I thought the 'Shift Left 1' operation needed to be 'Shift Left 2.' I then realized that the RISC-V ISA has an extension that supports 16-bit instructions. In that case, it makes sense to multiply the immediate value by two ('Shift Left 1'). However, now it doesn't seem logical to increment the PC by four bytes.

I don't understand, does the assembler automatically handle this? If so how? I have attached the RISC-V architecture for reference.
RISC-V

2

There are 2 answers

0
Erik Eidt On BEST ANSWER

why add 4 bytes with no branch but shift by one when branch?

Simple answer is that is how the ISA defines things; however the motivation is for all RISC V instruction sets to be compatible with variable-sized instruction capabilities.

The encodings for RISC V allow for 32-bit, 16-bit, and larger in increments of 16 bits.  Because of this, branch offsets are encoded × 2 (instead of × 4 as is done on MIPS, which also has 4 byte instructions).

While this means that the range/reach of a branch instruction is reduced (for no benefit on processors that only support 32-bit instructions), the advantage is in tooling and binary machine code compatibility with processors that do support instruction sizes beyond 32 bits.

Currently, there is only one non-32-bit specification, RVC, aka the compressed instruction set profile, which defines 16-bit instructions, and can be added to base RV32 or RV64, meaning such processors have both 32-bit and 16-bit instructions.

FYI, RVC appears quite popular, it seems to me; compilers like GCC (example on Godbolt) default to targeting a RISC-V supporting them. But for students looking at CPU internals for the first time, simpler is better, keeping only the complexity necessary to have a CPU at all, then to pipeline it.

0
Markus helbæk On

Okay, I think I understand. Thanks to @Jester.

Instructions are 4 bytes: In the RISC-V architecture, each instruction takes up 4 bytes of memory.

PC is incremented by 4 to get to the next instruction: The Program Counter (PC) keeps track of the memory address of the next instruction to be fetched. Since each instruction is 4 bytes, incrementing the PC by 4 moves it to the address of the next instruction.

The offset encoded in B-type instruction is in units of 2 bytes: B-type instructions often involve branches, and the offset field in these instructions is encoded in units of 2 bytes (16 bits). This means that the offset specifies a certain number of 2-byte increments.

The shift is by 1: Because the offset is in units of 2 bytes, shifting it left by 1 (multiplying by 2) is necessary when calculating the target address. This adjustment aligns the offset with the 4-byte instruction size, ensuring that the branch takes place at the correct address.

@Jester, do you approve? Thanks @Jester for the help! :)