[[insns-vaesdm, Vector AES decrypt middle round]]
= vaesdm.[vv,vs]

Synopsis::
Vector AES middle-round decryption

Mnemonic::
vaesdm.vv vd, vs2 +
vaesdm.vs vd, vs2

Encoding (Vector-Vector)::
[wavedrom, , svg]
....
{reg:[
{bits: 7, name: 'OP-P'},
{bits: 5, name: 'vd'},
{bits: 3, name: 'OPMVV'},
{bits: 5, name: '00000'},
{bits: 5, name: 'vs2'},
{bits: 1, name: '1'},
{bits: 6, name: '101000'},
]}
....

Encoding (Vector-Scalar)::
[wavedrom, , svg]
....
{reg:[
{bits: 7, name: 'OP-P'},
{bits: 5, name: 'vd'},
{bits: 3, name: 'OPMVV'},
{bits: 5, name: '00000'},
{bits: 5, name: 'vs2'},
{bits: 1, name: '1'},
{bits: 6, name: '101001'},
]}
....
Reserved Encodings::
* `SEW` is any value other than 32
* Only for the `.vs` form: the `vd` register group overlaps the `vs2` scalar element group

Arguments::

[%autowidth]
[%header,cols="4,2,2,2,2,2"]
|===
|Register
|Direction
|EGW
|EGS 
|EEW
|Definition

| Vd  | input  | 128  | 4 | 32 | round state
| Vs2 | input  | 128  | 4 | 32 | round key
| Vd  | output | 128  | 4 | 32 | new round state
|===

Description::
A middle-round AES block cipher decryption is performed.

The InvShiftRows and InvSubBytes steps are applied to each round state element group from `vd`.
This is then XORed with the round key in either the corresponding element group in `vs2` (vector-vector
form) or the scalar element group in `vs2` (vector-scalar form). The result is then applied to the
InvMixColumns step.

This instruction must always be implemented such that its execution latency does not depend
on the data being operated upon.
//
// The number of element groups to be processed is `vl`/`EGS`.
// `vl` must be set to the number of `SEW=32` elements to be processed and 
// therefore must be a multiple of `EGS=4`. + 
// Likewise, `vstart` must be a multiple of `EGS=4`.

Operation::
[source,sail]
--
function clause execute (VAESDM(vs2, vd, suffix)) = {
  if(LMUL*VLEN < EGW)  then {
    handle_illegal();  // illegal instruction exception
    RETIRE_FAIL
  } else {

  eg_len = (vl/EGS)
  eg_start = (vstart/EGS)
  
  foreach (i from eg_start to eg_len-1) {
    let keyelem = if suffix == "vv" then i else 0;
    let state : bits(128) = get_velem(vd, EGW=128, i);
    let rkey  : bits(128) = get_velem(vs2, EGW=128, keyelem);
    let sr    : bits(128) = aes_shift_rows_inv(state);
    let sb    : bits(128) = aes_subbytes_inv(sr);
    let ark   : bits(128) = sb ^ rkey;
    let mix   : bits(128) = aes_mixcolumns_inv(ark);
    set_velem(vd, EGW=128, i, mix);
  }
  RETIRE_SUCCESS
  }
}
--

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

| <<zvkned>>
| v0.1.0
| In Development
|===
