
= RISC-V Scalar Crypto GCC Implementation Tasks
Ben Marshall <ben.marshall@bristol.ac.uk>
:toc:

== Introduction & Purpose

This document describes the work necessary to implement support
the scalar crypto extension in GCC and Binutils.

We currently have experimental patches for Binutils in the same
directory as this file (link:patch-binutils.patch[`patch-binutils.patch`]).
This has been used to develop benchmarks and compliance tests, but
cannot be upstreamed because

1. The author (Ben) doesn't have an FSF copyright assignment and

2. has no experience contributing to GCC or Binutils, so the coding
   style might be off and

3. It is incomplete: it doesn't implement the feature groupings properly.

*The purpose of this document* is to describe the necessary work
for creating an upstream appropriate patch, in the hope that someone who
is well qualified to do so can follow it.

NOTE: This doc was written by someone with _very_ cursory experience
of hacking on GCC and Binutils. Please forgive any transgressions as
appropriate.

Broadly, the scalar crypto extension only needs Binutils and intrinsics
support for instructions exclusive to it.
It also _shares_ some instructions with Bitmanip, which should be available
to the compiler if _either_ the relevant Bitmanip _or_ scalar crypto
feature sets are enabled.

== Binutils Support

Instruction Opcodes can be generated by running

  make opcodes

From the root of this repository. The resulting C code files are placed
in the `build/` directory.
These files contain the `MATCH_` and `MASK_` macros for defining the
encodings:

 #ifndef RISCV_ENCODING_H
 #define RISCV_ENCODING_H
 #define MATCH_SM4ED 0x800302b
 #define MASK_SM4ED 0x3e00707f
 #define MATCH_SM4KS 0xa00302b
 [...]

These generated macros can be pasted directly into
`include/opcode/riscv-opc.h`
in the Binutils source tree.

They also contain _most_ of the code needed to describe the assembly code
syntax at the very end of the file. For example, it generates

 {"sm4ed"               , 0, INSN_CLASS_K,  "d,s,t,w", MATCH_SM4ED, MASK_SM4ED, match_opcode, 0},
 {"sm4ks"               , 0, INSN_CLASS_K,  "d,s,t,w", MATCH_SM4KS, MASK_SM4KS, match_opcode, 0},
 [...]

Which can be mostly just pasted into `opcodes/riscv-opc.c` in the
binutils source tree.
Modifications are needed to specify which instructions
are RV32/RV64 only and the feature groups they belong too, which is described
in section 2 of the 
https://github.com/riscv/riscv-crypto/releases[specification].

=== CSR Support

The scalar crypto extension adds two CSRs, detailed in the
Entropy Source section of the specification: `mnoise` and `mentropy`.
These need adding to the list of CSRs recognised by Binutils.

Additionally, there are two pseudo instructions defined, which alias
`csrr` instructions:

* `pollentropy rd` - Alias for `csrrs rd, mentropy, x0`.

* `getnoise    rd` - Alias for `csrrs rd, mnoise  , x0`.

=== Additional Immediate Fields

The scalar crypto extension introduces two new immediate fields:

* `bs` - used by the 32-bit AES instructions, and the SM4 instructions.
  It is 2 bits wide.

* `rcon` - Used by the `aes64ks1` instruction. 4-bits wide. The assembler
  should only allow values `0<=rcon<=0xA`.
  Values `rcon>0xA` are ignored by the instruction in hardware.

The link:patch-binutils.patch[patch] shows how these were added up to now.
Most of the modifications are in `gas/config/tc-riscv.c` of the
binutils source tree.
Constants to define their size and position were added in
`include/opcode/riscv.h`, and disassembly information
was added in `opcodes/riscv-dis.c`.

=== Feature Groups

Feature groups for the scalar crypto extension are described in
section 2 of the 
https://github.com/riscv/riscv-crypto/releases[specification].

These have not been implemented at all in the current patches.
It is expected that they can be added in a very similar way to the
existing Bitmanip feature groups.

The additional complexity comes from some instructions being _shared_
between Bitmanip and the scalar crypto extension.

== GCC Support

There are two components to the GCC support:

* Implementing the parsing for the `-march` string features, per
  the feature groups described in the specification.

* Making sure the compiler can use the set of Bitmanip instructions
  which are shared with the scalar crypto extension when _either_ of
  the extensions are enabled.

We do not expect the compiler to use the complex algorithm specific
instructions.

NOTE: It _might_ be possible to write a matching pattern for the
SHA2 and SM3 instructions, but this is not necessary for inital
support.

