[#insns-sm4ks, reftext="SM4 Key Schedule Instruction"]
=== sm4ks

Synopsis::
Accelerates the Key Schedule operation of the SM4 block cipher
cite:[gbt:sm4, iso:sm4].

Mnemonic::
sm4ks rd, rs1, rs2, bs

Encoding::
[wavedrom, , svg]
....
{reg:[
{bits: 7, name: 0x33},
{bits: 5, name: 'rd'},
{bits: 3, name: 0x0},
{bits: 5, name: 'rs1'},
{bits: 5, name: 'rs2'},
{bits: 5, name: 0x1a},
{bits: 2, name: 'bs'},
]}
....

Description:: 
Implements a T-tables in hardware style approach to accelerating the
SM4 Key Schedule.
A byte is extracted from `rs2` based on `bs`, to which the SBox and
linear layer transforms are applied, before the result is XOR'd with
`rs1` and written back to `rd`.
This instruction exists on RV32 and RV64 base architectures.
On RV64, the 32-bit result is sign extended to XLEN bits.
This instruction must _always_ be implemented such that its execution
latency does not depend on the data being operated on.

Operation::
[source,sail]
--
function clause execute (SM4KS (bs,rs2,rs1,rd)) = {
  let shamt : bits(5)  = (bs @ 0b000); /* shamt = bs*8 */
  let sb_in : bits(8)  = (X(rs2)[31..0] >> shamt)[7..0];
  let x     : bits(32) = 0x000000 @ sm4_sbox(sb_in);
  let y     : bits(32) = x ^ ((x & 0x00000007) << 29) ^ ((x & 0x000000FE) <<  7) ^
                             ((x & 0x00000001) << 23) ^ ((x & 0x000000F8) << 13) ;
  let z     : bits(32) = rol32(y, unsigned(shamt));
  let result: bits(32) = z ^ X(rs1)[31..0];
  X(rd) = EXTS(result);
  RETIRE_SUCCESS
}
--

Included in::
[%header,cols="4,2,2"]
|===
|Extension
|Minimum version
|Lifecycle state

| <<zksed>>
| v1.0.0
| Frozen
| <<zks>>
| v1.0.0
| Frozen
|===


