3

What happens on a RISC-V CPU when the program counter (PC) overflows?

For example, what happens on RV32G IALIGN = 32 after a (32-bit) NOP at 0xFFFF’FFFC has been executed? Or on RV32GC after a 16-bit NOP at 0xFFFF’FFFE has been executed? The easiest answer to both of these questions to be “nothing much, execution proceeds from 0x0000’0000”, but then what happens on RV32GC after a 16-bit NOP at 0xFFFF’FFFC has been executed? The same answer would imply the instruction fetch might then need to span the end of the address space, which doesn’t sound architecturally pleasant. (Then again, with IALIGN = 16 an instruction fetch might have to span a page boundary, which doesn’t sound all that pleasant either, and IIRC x86 implementations have caused plenty of hilarity for partially-faulting instruction fetches.)

A reference to the specPDF would be preferred, though I haven’t been able to find anything relevant there. Failing that, it’d be interesting to hear what actual hardware implementations do in this situation.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Alex Shpilkin
  • 776
  • 7
  • 17

1 Answers1

5

https://riscv.org/wp-content/uploads/2019/12/riscv-spec-20191213.pdf

1.4 Memory

A RISC-V hart has a single byte-addressable address space of 2XLEN bytes for all memory accesses. A word of memory is defined as 32 bits (4 bytes). Correspondingly, a halfword is 16 bits (2 bytes), a doubleword is 64 bits (8 bytes), and a quadword is 128 bits (16 bytes). The memory address space is circular, so that the byte at address 2XLEN−1 is adjacent to the byte at address zero. Accordingly, memory address computations done by the hardware ignore overflow and instead wrap around modulo 2XLEN.

This suggests to me that the PC wraps, since incrementing it is a memory address computation.

Erik Eidt
  • 23,049
  • 2
  • 29
  • 53
  • Which in most cases is going to cause a crash or a segfault anyway since you're reading into kernel space I believe. – puppydrum64 Jan 05 '23 at 11:22
  • 2
    @puppydrum64, that's certainly possible; a point to make being that it is not the wrapping itself that causes a fault but what may happen after. I assume the OP is writing or studying hardware or a software simulator and wants to know how to implement this what might seem to be a corner case, more in the abstract than in actually wanting to deploy use of the last address in some program. – Erik Eidt Jan 05 '23 at 16:58
  • It's certainly an interesting question, one that I don't know has a "real answer", since I doubt it's possible to write a program that wraps and doesn't fault in some way due to memory protection. It was difficult even on 8-bit micros since their vector tables are ROM and are either at the beginning of memory (Z80) or at the end (6502). – puppydrum64 Jan 06 '23 at 11:54
  • The PDP-8 has a 12-bit address space, 4k, and the PC wraps. Several of us had competition to write a program that zeroed all the memory including that of the program itself, and some used the PC wrap to eventually return to the last instruction that would wipe itself out. – Erik Eidt Jan 06 '23 at 15:16