diff --git a/riscv-elf.adoc b/riscv-elf.adoc index 9e341acb..5793d6bd 100644 --- a/riscv-elf.adoc +++ b/riscv-elf.adoc @@ -125,6 +125,59 @@ This model is similar to the medium any code model, but uses the l[w|d] a0, a0, %pcrel_lo(.Ltmp3) ---- +=== Large code model + +The `large` code model allows the code to address the whole RV64 address space. +Thus, this model is only available for RV64. By putting object addresses +into literal pools, a 64-bit address literal can be loaded from the pool. + +NOTE: Because calculating the pool entry address must use `aupic` and +`addi` or `ld`, each pool entry has to be located within the range +between -2GiB and +2GiB from its access intructions. In general, the pool +is appeneded in .text section or put into .rodata section. + +[,asm] +---- + # Get address of a symbol + # Literal pool +.LCPI0: + .8byte symbol + ... +.Ltmp0: auipc a0, %pcrel_hi(.LCPI0) + ld a0, %pcrel_lo(.Ltmp0)(a0) +---- + +This model also changes the function call patterns. An external function +address must be loaded from a literal pool entry, and use `jalr` to jump to +the target function. + + +NOTE: Same as getting address of symbol, each pool entry has to be located +within the range between -2GiB and +2GiB from its access intructions. The +function call can reach the whole 64-bit address space. + +NOTE: The code generation of function call may be changed after the range +extension thunk is implemented. The compiler can emit `call` directly, +and leave the model variation to the linker which could decide to jump +via the literal pool or not. + +[,asm] +---- + # Function call + # Literal pool +.LCPI1: + .8byte function + ... +.Ltmp1: auipc a0, %pcrel_hi(.LCPI1) + ld a0, %pcrel_lo(.Ltmp1)(a0) + jalr a0 +---- + +NOTE: Large code model is disallowed to be used with PIC code model. + +NOTE: There will be more different code generation strategies for different +usage purposes in the future. + == Dynamic Linking Any functions that use registers in a way that is incompatible with