diff --git a/src/asm-manual.adoc b/src/asm-manual.adoc index 558f7a2..2b98cbd 100644 --- a/src/asm-manual.adoc +++ b/src/asm-manual.adoc @@ -370,6 +370,75 @@ NOTE: `.option arch, +, -` is accepted and will result in enabling the extensions that depend on `ext`, e.g. `rv32i` + `.option arch, +v, -v` will result `rv32ifd_zve32x_zve32f_zve64x_zve64f_zve64d_zvl32b_zvl64b_zvl128b`. +=== `exact`/`noexact` + +In RISC-V, the assembler and linker can do several things to change the code +that a user writes into a different sequence of instructions. There are features +which help static code size in the final executable: + +- Compression turns longer instructions into shorter, equivalent instructions. + For example the assembler might turn `lw a0, 16(a1)` into `c.lw a0, 16(a1)` + when the C or Zca extensions are enabled. +- Linker Relaxation causes the linker to replace long symbol references with + shorter code sequences that can reference the same symbol (documented more + fully in the psABI document). + +And also a feature which allows users to write a sequence of code which doesn't +match what appears in the final executable, but avoids assembler errors in some +cases: + +- Branch Relaxation turns short branches of too long or unknown range into code + sequences with a longer range. For example `beq a0, a1, sym` will be turned + into `bne a0, a1, 4; j sym` because `j` has a longer range than `beq`. + +The aim of `.option exact` is to prevent the assembler and linker from modifying +the written instruction sequence into a different instruction sequence. This +primarily affects assembler behaviour, but the assembler also should not emit +`R_RISCV_RELAX` relocations for affected instructions, which prevents the linker +relaxing the instruction sequence too. + +`.option exact` can be seen as a version of `.option norelax` which also affects +the modifications made by the assembler as well as those made by the linker. + +Without this option, compression is only controllable with `.option norvc` -- +which turns off the C extension, so also prevents users from writing the shorter +instructions directly. There is no similar mechanism for preventing longer +instructions being compressed into 32-bit instructions from the base ISA, as the +base ISA cannot be turned off. + +This option does not change the currently enabled extensions, which allows +instructions of different lengths to still be used without error. + +For example: + +[source,asm] +---- + .option arch, +zca + +lw a0, 0(a0) # assembled as 'c.lw a0, 0(a0)' (2 bytes) +c.lw a0, 0(a0) # not changed + + .option exact + +lw a0, 0(a0) # not changed +c.lw a0, 0(a0) # not changed, no error + + .option noexact + +lw a0, 0(a0) # assembled as 'c.lw a0, 0(a0)' (2 bytes) +c.lw a0, 0(a0) # not changed +---- + +The default behaviour is `.option noexact`. + +Enabling `.option exact` implies `.option norelax` from that point onwards, so +this should be used with `.option push; .option exact; ... ; .option pop` to be +clear about when to re-enable relaxation. + +The default behaviour of some disassemblers is to reverse this process and show +`lw a0, 0(a0)` when `c.lw a0, 0(a0)` is in the binary. This can be disabled in +objdump-compatible disassemblers using the options `-M no-aliases`. + === `pic`/`nopic` Set the code model to PIC (position independent code) or non-PIC. This will