riscv / riscv-cfi

This specification is integrated into the Priv. and Unpriv. specifications. This repo is no longer maintained. Please refer to the Priv. and Unpriv. specifications at https://github.com/riscv/riscv-isa-manual

Home Page:https://lf-riscv.atlassian.net/browse/RVG-80

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Zimop/Zcmop - temporary non-official documentation

ved-rivos opened this issue · comments

This is not the official specification for these extensions.

Zimop:
The Zimop extension introduces the concept of instructions that may be operations (MOPs). MOPs are initially defined to perform no useful operation and raise no exceptions, but might be redefined by later extensions to perform some other action. The Zimop extension defines an encoding space for 40 MOPs.

NOTE: It is sometimes desirable to define instruction-set extensions whose instructions do not raise illegal-instruction exceptions when the extension is not implemented. For example, programs with control-flow integrity checks can execute correctly on implementations without the corresponding extension, provided the checks are simply ignored. Implementing these checks as MOPs allows the same programs to run on implementations with or without the corresponding extension.

NOTE: Although similar in some respects to HINTs, most MOPs cannot be encoded as HINTs, because MOPs might sometimes alter architectural state, which HINTs are forbidden from doing.

The Zimop extension defines 32 MOP instructions named mop.r.0 -- mop.r.31. Unless redefined by another extension, these instructions simply write 0 to x[rd]. Their encoding allows future extensions to define them to read x[rs1], as well as write x[rd]. They are encoded as 1-00--0111--sssss100ddddd1110011, where - denotes an available opcode bit, s denotes the rs1 field, and d denotes the rd field.

The Zimop extension additionally defines 8 MOP instructions named mop.rr.0 -- mop.rr.7. Unless redefined by another extension, these instructions simply write 0 to x[rd]. Their encoding allows future extensions to define them to read x[rs1] and x[rs2], as well as write x[rd]. They are encoded as 1-00--1tttttsssss100ddddd1110011, where t denotes the rs2 field.

NOTE: These MOPs are encoded in the SYSTEM major opcode in part because it is expected their behavior will be modulated by privileged CSR state.

NOTE: These MOPs are defined to write x[rd], rather than performing no operation, to simplify instruction decoding and to allow testing the presence of features by branching on the zeroness of the result.

The MOPs defined in the Zimop extension are not guaranteed to carry a syntactic dependency from source to destination.

NOTE: Not carrying a syntactic dependence relieves straightforward implementations of reading x[rs1] and x[rs2].

Zcmop
Eight code points in the 16-bit encoding space are provided for MOPs:
c.mop.0, encoded in the reserved encoding space where c.lui x1, 0 would be encoded
c.mop.1 (c.lui x3, 0)
c.mop.2 (c.lui x5, 0)
...
c.mop.7 (c.lui x15, 0)
These instructions are defined to not write rd. As with other MOPs, which registers they read is left up to the future definition of the op, but this encoding makes it convenient for these instructions to read x1, x3, ..., x15. Although we generally expect these MOPs to be equivalent to some 32-bit MOP, the expansion (if any) is left to the future definition of the op.

Official documentation posted here: riscv/riscv-isa-manual@2463e2a

Looking for help from someone in the TG conversant with binutils to provide an update to binutils for Zimop/Zcmop; including how we would have binutils comprehend a subset of codepoints being used later for Zicfiss and thus have a different mnemonic.

Looking for help from someone in the TG conversant with binutils to provide an update to binutils for Zimop/Zcmop; including how we would have binutils comprehend a subset of codepoints being used later for Zicfiss and thus have a different mnemonic.

Yeah, I think that can be implemented as alias in binutils, there is an example in F extension:

  • csrr a0, fcsr dissemble to frcsr a0 if F ext. is present.
  • csrr a0, fcsr dissemble to csrr a0, fcsr if F ext. is not present.
  • Assembler accept frcsr a0 only if F ext. is present.
  • Assembler accept csrr a0, fcsr if Zicsr or F ext. is present.

So, applying this kind of pattern to Zimop (the instruction mapping may not correct, but it should doesn't matter to demo this concept):

  • mop.r.0 dissemble to sspush x1 if Zicfiss ext. is present.
  • mop.r.0 dissemble to mop.r.0 if Zicfiss ext. is not present.
  • Assembler accept sspush x1 only if Zicfiss ext. is present.
  • Assembler accept mop.r.0 if Zicfiss or Zimop ext. is present.

Thanks. That makes sense. So for now the binutil update can be just to add mop.r, mop.rr, and c.mop and when we introduce the Zicfiss, some of these can be updated to have aliases.

FYI, here's a very rough binutils patch. It's my first ever binutils patch, so may have obvious errors, and I suspect it's not looking at ISA dependencies correctly (ie, making sure Zcmop requires C). That said, I can assemble and objdump with it.

Thank you @adlr ! Much appreciate!

Closing this issue since official documentation is now available and will provide a reference from the specification to the official documentation.