[[insns-vaesdf, Vector AES decrypt final round]]
= vaesdf.[vv,vs]

Synopsis::
Vector AES final-round decryption

Mnemonic::
vaesdf.vv vd, vs2 + 
vaesdf.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: '00001'},
{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: '00001'},
{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 final-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 scalar element group in `vs2` (vector-scalar form).

This instruction must always be implemented such that its execution latency does not depend
on the data being operated upon.

//  if( ((vl%EGS)<>0) | ((vstart%EGS)<>0) | (LMUL*VLEN < EGW))  then {

Operation::
[source,sail]
--
function clause execute (VAESDF(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;
    set_velem(vd, EGW=128, i, ark);
  }
  RETIRE_SUCCESS
  }
}
--

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

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