diff --git a/README.md b/README.md index eb9302f62..8dbe95abb 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,7 @@ For booting operating system images, see the information under the - Zvbb extension for vector basic bit-manipulation, v1.0 - Zvbc extension for vector carryless multiplication, v1.0 - Zvkb extension for vector cryptography bit-manipulation, v1.0 +- Zvkg extension for vector GCM/GMAC, v1.0 - Zvkned extension for vector cryptography NIST Suite: Vector AES Block Cipher, v1.0 - Zvknha and Zvknhb extensions for vector cryptography NIST Suite: Vector SHA-2 Secure Hash, v1.0 - Zvksh extension for vector cryptography ShangMi Suite: SM3 Secure Hash, v1.0 diff --git a/config/default.json b/config/default.json index 5c4ad0bf7..c694faa4b 100644 --- a/config/default.json +++ b/config/default.json @@ -184,10 +184,13 @@ "Zvbb": { "supported": true }, + "Zvbc": { + "supported": true + }, "Zvkb": { "supported": false }, - "Zvbc": { + "Zvkg": { "supported": true }, "Zvkned": { diff --git a/model/CMakeLists.txt b/model/CMakeLists.txt index f5ec12de6..fbcdb2886 100644 --- a/model/CMakeLists.txt +++ b/model/CMakeLists.txt @@ -86,6 +86,7 @@ foreach (xlen IN ITEMS 32 64) "riscv_insts_zawrs.sail" "riscv_insts_zvbb.sail" "riscv_insts_zvbc.sail" + "riscv_insts_zvkg.sail" "riscv_insts_zvkned.sail" "riscv_insts_zvknhab.sail" "riscv_insts_zvksh.sail" diff --git a/model/arithmetic.sail b/model/arithmetic.sail index a4a3c47f7..9105fad30 100644 --- a/model/arithmetic.sail +++ b/model/arithmetic.sail @@ -6,6 +6,15 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /*=======================================================================================*/ +/* Reverse bits in each byte */ +val brev8 : forall 'm, 'm >= 0 & mod('m, 8) == 0. (bits('m)) -> bits('m) +function brev8(input) = { + var output : bits('m) = zeros(); + foreach (i from 0 to ('m - 8) by 8) + output[i+7..i] = reverse_bits(input[i+7..i]); + output +} + /* Carry-less multiply. */ val carryless_mul : forall 'n, 'n > 0. (bits('n), bits('n)) -> bits(2 * 'n) function carryless_mul(a, b) = { diff --git a/model/riscv_extensions.sail b/model/riscv_extensions.sail index 462ef767e..eb8be97d5 100644 --- a/model/riscv_extensions.sail +++ b/model/riscv_extensions.sail @@ -185,6 +185,9 @@ function clause hartSupports(Ext_Zvkb) = config extensions.Zvkb.supported // Vector Carryless Multiplication enum clause extension = Ext_Zvbc function clause hartSupports(Ext_Zvbc) = config extensions.Zvbc.supported +// Vector GCM/GMAC +enum clause extension = Ext_Zvkg +function clause hartSupports(Ext_Zvkg) = config extensions.Zvkg.supported // NIST Suite: Vector AES Block Cipher enum clause extension = Ext_Zvkned function clause hartSupports(Ext_Zvkned) = config extensions.Zvkned.supported diff --git a/model/riscv_insts_zvkg.sail b/model/riscv_insts_zvkg.sail new file mode 100644 index 000000000..0b37653c7 --- /dev/null +++ b/model/riscv_insts_zvkg.sail @@ -0,0 +1,101 @@ +/*=======================================================================================*/ +/* This Sail RISC-V architecture model, comprising all files and */ +/* directories except where otherwise noted is subject the BSD */ +/* two-clause license in the LICENSE file. */ +/* */ +/* SPDX-License-Identifier: BSD-2-Clause */ +/*=======================================================================================*/ + +function clause currentlyEnabled(Ext_Zvkg) = hartSupports(Ext_Zvkg) & currentlyEnabled(Ext_V) + +union clause ast = VGHSH_VV : (vregidx, vregidx, vregidx) + +mapping clause encdec = VGHSH_VV(vs2, vs1, vd) + <-> 0b1011001 @ encdec_vreg(vs2) @ encdec_vreg(vs1) @ 0b010 @ encdec_vreg(vd) @ 0b1110111 + when currentlyEnabled(Ext_Zvkg) & get_sew() == 32 & zvk_check_encdec(128, 4) + +function clause execute (VGHSH_VV(vs2, vs1, vd)) = { + let SEW = get_sew(); + let LMUL_pow = get_lmul_pow(); + let num_elem = get_num_elem(LMUL_pow, SEW); + + assert(SEW == 32); + + let vs2_val = read_vreg(num_elem, SEW, LMUL_pow, vs2); + let vs1_val = read_vreg(num_elem, SEW, LMUL_pow, vs1); + let vd_val = read_vreg(num_elem, SEW, LMUL_pow, vd); + + let eg_len = (unsigned(vl) / 4); + let eg_start = (unsigned(vstart) / 4); + + foreach (i from eg_start to (eg_len - 1)) { + assert(i * 4 + 3 < num_elem); + + let Y : bits(128) = get_velem_quad(vd_val, i); + let X : bits(128) = get_velem_quad(vs1_val, i); + var H : bits(128) = brev8(get_velem_quad(vs2_val, i)); + + var Z : bits(128) = zeros(); + let S : bits(128) = brev8(Y ^ X); + + foreach (b from 0 to 127) { + if S[b] == bitone then Z = Z ^ H; + + let reduce = H[127] == bitone; + H = H << 1; + if reduce then H = H[127..8] @ (H[7..0] ^ 0x87); + }; + + write_velem_quad(vd, SEW, brev8(Z), i); + }; + + set_vstart(zeros()); + RETIRE_SUCCESS +} + +mapping clause assembly = VGHSH_VV(vs2, vs1, vd) + <-> "vghsh.vv" ^ spc() ^ vreg_name(vd) ^ sep() ^ vreg_name(vs2) ^ sep() ^ vreg_name(vs1) + +union clause ast = VGMUL_VV : (vregidx, vregidx) + +mapping clause encdec = VGMUL_VV(vs2, vd) + <-> 0b1010001 @ encdec_vreg(vs2) @ 0b10001 @ 0b010 @ encdec_vreg(vd) @ 0b1110111 + when currentlyEnabled(Ext_Zvkg) & get_sew() == 32 & zvk_check_encdec(128, 4) + +function clause execute (VGMUL_VV(vs2, vd)) = { + let SEW = get_sew(); + let LMUL_pow = get_lmul_pow(); + let num_elem = get_num_elem(LMUL_pow, SEW); + + assert(SEW == 32); + + let vs2_val = read_vreg(num_elem, SEW, LMUL_pow, vs2); + let vd_val = read_vreg(num_elem, SEW, LMUL_pow, vd); + + let eg_len = (unsigned(vl) / 4); + let eg_start = (unsigned(vstart) / 4); + + foreach (i from eg_start to (eg_len - 1)) { + assert(i * 4 + 3 < num_elem); + + let Y : bits(128) = brev8(get_velem_quad(vd_val, i)); + var H : bits(128) = brev8(get_velem_quad(vs2_val, i)); + var Z : bits(128) = zeros(); + + foreach (b from 0 to 127) { + if Y[b] == bitone then Z = Z ^ H; + + let reduce = H[127] == bitone; + H = H << 1; + if reduce then H = H[127..8] @ (H[7..0] ^ 0x87); + }; + + write_velem_quad(vd, SEW, brev8(Z), i); + }; + + set_vstart(zeros()); + RETIRE_SUCCESS +} + +mapping clause assembly = VGMUL_VV(vs2, vd) + <-> "vgmul.vv" ^ spc() ^ vreg_name(vd) ^ sep() ^ vreg_name(vs2)