* [RFC 0/6] support subsets of scalar crypto extension @ 2021-11-02 3:11 ` liweiwei 0 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-02 3:11 UTC (permalink / raw) To: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, liweiwei, lazyparser, lustrew, luruibo2000 This patchset implements RISC-V K-extension v1.0.0.rc5 version instructions. Partial instructions are reused from B-extension. Specification: https://github.com/riscv/riscv-crypto The port is available here: https://github.com/plctlab/plct-qemu/tree/plct-k-upstream To test rvk implementation, specify cpu argument with 'x-zks=true,x-zkn=true' or "x-zbkb=true,x-zbkc=true,x-zbkx=true,x-zknd=true,x-zkne=true,x-zknh=true,x-zksed=true,x-zksh=true,x-zkr=true" to enable K-extension support. This implementation can pass the ACT tests for K with our extended act support for qemu (available at https://github.com/plctlab/plct-qemu/tree/plct-k-upstream-with-act) liweiwei (6): target/riscv: rvk: add flag support for Zbk[bcx] target/riscv: rvk: add implementation of instructions for Zbk* - reuse partial instructions of Zbb/Zbc extensions - add brev8 packh, unzip, zip, etc. target/riscv: rvk: add flag support for Zk/Zkn/Zknd/Zknd/Zkne/Zknh/Zks/Zksed/Zksh/Zkr target/riscv: rvk: add implementation of instructions for Zk* target/riscv: rvk: add CSR support for Zkr: - add SEED CSR - add USEED, SSEED fields for MSECCFG CSR disas/riscv.c: rvk: add disas support for Zbk* and Zk* instructions disas/riscv.c | 171 +++++++- target/riscv/bitmanip_helper.c | 94 +++++ target/riscv/cpu.c | 45 +- target/riscv/cpu.h | 12 + target/riscv/cpu_bits.h | 9 + target/riscv/crypto_helper.c | 540 ++++++++++++++++++++++++ target/riscv/csr.c | 66 +++ target/riscv/helper.h | 47 +++ target/riscv/insn32.decode | 94 ++++- target/riscv/insn_trans/trans_rvb.c.inc | 91 +++- target/riscv/insn_trans/trans_rvk.c.inc | 467 ++++++++++++++++++++ target/riscv/meson.build | 1 + target/riscv/pmp.h | 8 +- target/riscv/translate.c | 83 ++++ 14 files changed, 1690 insertions(+), 38 deletions(-) create mode 100644 target/riscv/crypto_helper.c create mode 100644 target/riscv/insn_trans/trans_rvk.c.inc -- 2.17.1 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [RFC 0/6] support subsets of scalar crypto extension @ 2021-11-02 3:11 ` liweiwei 0 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-02 3:11 UTC (permalink / raw) To: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: luruibo2000, lustrew, wangjunqiang, lazyparser, liweiwei This patchset implements RISC-V K-extension v1.0.0.rc5 version instructions. Partial instructions are reused from B-extension. Specification: https://github.com/riscv/riscv-crypto The port is available here: https://github.com/plctlab/plct-qemu/tree/plct-k-upstream To test rvk implementation, specify cpu argument with 'x-zks=true,x-zkn=true' or "x-zbkb=true,x-zbkc=true,x-zbkx=true,x-zknd=true,x-zkne=true,x-zknh=true,x-zksed=true,x-zksh=true,x-zkr=true" to enable K-extension support. This implementation can pass the ACT tests for K with our extended act support for qemu (available at https://github.com/plctlab/plct-qemu/tree/plct-k-upstream-with-act) liweiwei (6): target/riscv: rvk: add flag support for Zbk[bcx] target/riscv: rvk: add implementation of instructions for Zbk* - reuse partial instructions of Zbb/Zbc extensions - add brev8 packh, unzip, zip, etc. target/riscv: rvk: add flag support for Zk/Zkn/Zknd/Zknd/Zkne/Zknh/Zks/Zksed/Zksh/Zkr target/riscv: rvk: add implementation of instructions for Zk* target/riscv: rvk: add CSR support for Zkr: - add SEED CSR - add USEED, SSEED fields for MSECCFG CSR disas/riscv.c: rvk: add disas support for Zbk* and Zk* instructions disas/riscv.c | 171 +++++++- target/riscv/bitmanip_helper.c | 94 +++++ target/riscv/cpu.c | 45 +- target/riscv/cpu.h | 12 + target/riscv/cpu_bits.h | 9 + target/riscv/crypto_helper.c | 540 ++++++++++++++++++++++++ target/riscv/csr.c | 66 +++ target/riscv/helper.h | 47 +++ target/riscv/insn32.decode | 94 ++++- target/riscv/insn_trans/trans_rvb.c.inc | 91 +++- target/riscv/insn_trans/trans_rvk.c.inc | 467 ++++++++++++++++++++ target/riscv/meson.build | 1 + target/riscv/pmp.h | 8 +- target/riscv/translate.c | 83 ++++ 14 files changed, 1690 insertions(+), 38 deletions(-) create mode 100644 target/riscv/crypto_helper.c create mode 100644 target/riscv/insn_trans/trans_rvk.c.inc -- 2.17.1 ^ permalink raw reply [flat|nested] 34+ messages in thread
* [RFC 1/6] target/riscv: rvk: add flag support for Zbk[bcx] 2021-11-02 3:11 ` liweiwei @ 2021-11-02 3:11 ` liweiwei -1 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-02 3:11 UTC (permalink / raw) To: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, liweiwei, lazyparser, lustrew, luruibo2000 Signed-off-by: liweiwei <liweiwei@iscas.ac.cn> Signed-off-by: wangjunqiang <wangjunqiang@iscas.ac.cn> --- target/riscv/cpu.c | 9 ++++++--- target/riscv/cpu.h | 3 +++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 7d53125dbc..0f03d3efba 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -472,15 +472,15 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) error_setg(errp, "I and E extensions are incompatible"); return; - } + } if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) { error_setg(errp, "Either I or E extension must be set"); return; - } + } - if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m & + if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m & cpu->cfg.ext_a & cpu->cfg.ext_f & cpu->cfg.ext_d)) { warn_report("Setting G will also set IMAFD"); @@ -639,6 +639,9 @@ static Property riscv_cpu_properties[] = { DEFINE_PROP_BOOL("x-zbb", RISCVCPU, cfg.ext_zbb, false), DEFINE_PROP_BOOL("x-zbc", RISCVCPU, cfg.ext_zbc, false), DEFINE_PROP_BOOL("x-zbs", RISCVCPU, cfg.ext_zbs, false), + DEFINE_PROP_BOOL("x-zbkb", RISCVCPU, cfg.ext_zbkb, false), + DEFINE_PROP_BOOL("x-zbkc", RISCVCPU, cfg.ext_zbkc, false), + DEFINE_PROP_BOOL("x-zbkx", RISCVCPU, cfg.ext_zbkx, false), DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false), DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false), DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false), diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 0760c0af93..f9f4437efc 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -309,6 +309,9 @@ struct RISCVCPU { bool ext_zbb; bool ext_zbc; bool ext_zbs; + bool ext_zbkb; + bool ext_zbkc; + bool ext_zbkx; bool ext_counters; bool ext_ifencei; bool ext_icsr; -- 2.17.1 ^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC 1/6] target/riscv: rvk: add flag support for Zbk[bcx] @ 2021-11-02 3:11 ` liweiwei 0 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-02 3:11 UTC (permalink / raw) To: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: luruibo2000, lustrew, wangjunqiang, lazyparser, liweiwei Signed-off-by: liweiwei <liweiwei@iscas.ac.cn> Signed-off-by: wangjunqiang <wangjunqiang@iscas.ac.cn> --- target/riscv/cpu.c | 9 ++++++--- target/riscv/cpu.h | 3 +++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 7d53125dbc..0f03d3efba 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -472,15 +472,15 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) error_setg(errp, "I and E extensions are incompatible"); return; - } + } if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) { error_setg(errp, "Either I or E extension must be set"); return; - } + } - if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m & + if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m & cpu->cfg.ext_a & cpu->cfg.ext_f & cpu->cfg.ext_d)) { warn_report("Setting G will also set IMAFD"); @@ -639,6 +639,9 @@ static Property riscv_cpu_properties[] = { DEFINE_PROP_BOOL("x-zbb", RISCVCPU, cfg.ext_zbb, false), DEFINE_PROP_BOOL("x-zbc", RISCVCPU, cfg.ext_zbc, false), DEFINE_PROP_BOOL("x-zbs", RISCVCPU, cfg.ext_zbs, false), + DEFINE_PROP_BOOL("x-zbkb", RISCVCPU, cfg.ext_zbkb, false), + DEFINE_PROP_BOOL("x-zbkc", RISCVCPU, cfg.ext_zbkc, false), + DEFINE_PROP_BOOL("x-zbkx", RISCVCPU, cfg.ext_zbkx, false), DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false), DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false), DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false), diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 0760c0af93..f9f4437efc 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -309,6 +309,9 @@ struct RISCVCPU { bool ext_zbb; bool ext_zbc; bool ext_zbs; + bool ext_zbkb; + bool ext_zbkc; + bool ext_zbkx; bool ext_counters; bool ext_ifencei; bool ext_icsr; -- 2.17.1 ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [RFC 1/6] target/riscv: rvk: add flag support for Zbk[bcx] 2021-11-02 3:11 ` liweiwei @ 2021-11-02 14:18 ` Richard Henderson -1 siblings, 0 replies; 34+ messages in thread From: Richard Henderson @ 2021-11-02 14:18 UTC (permalink / raw) To: liweiwei, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, luruibo2000, lustrew On 11/1/21 11:11 PM, liweiwei wrote: > +++ b/target/riscv/cpu.c > @@ -472,15 +472,15 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) > error_setg(errp, > "I and E extensions are incompatible"); > return; > - } > + } > > if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) { > error_setg(errp, > "Either I or E extension must be set"); > return; > - } > + } > > - if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m & > + if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m & > cpu->cfg.ext_a & cpu->cfg.ext_f & > cpu->cfg.ext_d)) { > warn_report("Setting G will also set IMAFD"); This re-indentation should not be happening. > + DEFINE_PROP_BOOL("x-zbkb", RISCVCPU, cfg.ext_zbkb, false), > + DEFINE_PROP_BOOL("x-zbkc", RISCVCPU, cfg.ext_zbkc, false), > + DEFINE_PROP_BOOL("x-zbkx", RISCVCPU, cfg.ext_zbkx, false), The properties cannot be exposed until the end. > bool ext_zbb; > bool ext_zbc; > bool ext_zbs; > + bool ext_zbkb; > + bool ext_zbkc; > + bool ext_zbkx; Better to keep them alphabetical: zbk* < zbs. r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [RFC 1/6] target/riscv: rvk: add flag support for Zbk[bcx] @ 2021-11-02 14:18 ` Richard Henderson 0 siblings, 0 replies; 34+ messages in thread From: Richard Henderson @ 2021-11-02 14:18 UTC (permalink / raw) To: liweiwei, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, lustrew, luruibo2000 On 11/1/21 11:11 PM, liweiwei wrote: > +++ b/target/riscv/cpu.c > @@ -472,15 +472,15 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) > error_setg(errp, > "I and E extensions are incompatible"); > return; > - } > + } > > if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) { > error_setg(errp, > "Either I or E extension must be set"); > return; > - } > + } > > - if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m & > + if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m & > cpu->cfg.ext_a & cpu->cfg.ext_f & > cpu->cfg.ext_d)) { > warn_report("Setting G will also set IMAFD"); This re-indentation should not be happening. > + DEFINE_PROP_BOOL("x-zbkb", RISCVCPU, cfg.ext_zbkb, false), > + DEFINE_PROP_BOOL("x-zbkc", RISCVCPU, cfg.ext_zbkc, false), > + DEFINE_PROP_BOOL("x-zbkx", RISCVCPU, cfg.ext_zbkx, false), The properties cannot be exposed until the end. > bool ext_zbb; > bool ext_zbc; > bool ext_zbs; > + bool ext_zbkb; > + bool ext_zbkc; > + bool ext_zbkx; Better to keep them alphabetical: zbk* < zbs. r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [RFC 1/6] target/riscv: rvk: add flag support for Zbk[bcx] 2021-11-02 14:18 ` Richard Henderson @ 2021-11-02 15:00 ` liweiwei -1 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-02 15:00 UTC (permalink / raw) To: Richard Henderson, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, luruibo2000, lustrew 在 2021/11/2 下午10:18, Richard Henderson 写道: > On 11/1/21 11:11 PM, liweiwei wrote: >> +++ b/target/riscv/cpu.c >> @@ -472,15 +472,15 @@ static void riscv_cpu_realize(DeviceState *dev, >> Error **errp) >> error_setg(errp, >> "I and E extensions are incompatible"); >> return; >> - } >> + } >> if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) { >> error_setg(errp, >> "Either I or E extension must be set"); >> return; >> - } >> + } >> - if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m & >> + if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m & >> cpu->cfg.ext_a & cpu->cfg.ext_f & >> cpu->cfg.ext_d)) { >> warn_report("Setting G will also set IMAFD"); > > This re-indentation should not be happening. > Thanks for your comments. I'll restore them later. By the way, the reason I changed these is that they don't align with other code. >> + DEFINE_PROP_BOOL("x-zbkb", RISCVCPU, cfg.ext_zbkb, false), >> + DEFINE_PROP_BOOL("x-zbkc", RISCVCPU, cfg.ext_zbkc, false), >> + DEFINE_PROP_BOOL("x-zbkx", RISCVCPU, cfg.ext_zbkx, false), > > The properties cannot be exposed until the end. > Ok. I'll move these to the end of the patchset. >> bool ext_zbb; >> bool ext_zbc; >> bool ext_zbs; >> + bool ext_zbkb; >> + bool ext_zbkc; >> + bool ext_zbkx; > > Better to keep them alphabetical: zbk* < zbs. > Ok. I'll move them before zbs. > > r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [RFC 1/6] target/riscv: rvk: add flag support for Zbk[bcx] @ 2021-11-02 15:00 ` liweiwei 0 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-02 15:00 UTC (permalink / raw) To: Richard Henderson, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, lustrew, luruibo2000 在 2021/11/2 下午10:18, Richard Henderson 写道: > On 11/1/21 11:11 PM, liweiwei wrote: >> +++ b/target/riscv/cpu.c >> @@ -472,15 +472,15 @@ static void riscv_cpu_realize(DeviceState *dev, >> Error **errp) >> error_setg(errp, >> "I and E extensions are incompatible"); >> return; >> - } >> + } >> if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) { >> error_setg(errp, >> "Either I or E extension must be set"); >> return; >> - } >> + } >> - if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m & >> + if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m & >> cpu->cfg.ext_a & cpu->cfg.ext_f & >> cpu->cfg.ext_d)) { >> warn_report("Setting G will also set IMAFD"); > > This re-indentation should not be happening. > Thanks for your comments. I'll restore them later. By the way, the reason I changed these is that they don't align with other code. >> + DEFINE_PROP_BOOL("x-zbkb", RISCVCPU, cfg.ext_zbkb, false), >> + DEFINE_PROP_BOOL("x-zbkc", RISCVCPU, cfg.ext_zbkc, false), >> + DEFINE_PROP_BOOL("x-zbkx", RISCVCPU, cfg.ext_zbkx, false), > > The properties cannot be exposed until the end. > Ok. I'll move these to the end of the patchset. >> bool ext_zbb; >> bool ext_zbc; >> bool ext_zbs; >> + bool ext_zbkb; >> + bool ext_zbkc; >> + bool ext_zbkx; > > Better to keep them alphabetical: zbk* < zbs. > Ok. I'll move them before zbs. > > r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* [RFC 2/6] target/riscv: rvk: add implementation of instructions for Zbk* - reuse partial instructions of Zbb/Zbc extensions - add brev8 packh, unzip, zip, etc. 2021-11-02 3:11 ` liweiwei @ 2021-11-02 3:11 ` liweiwei -1 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-02 3:11 UTC (permalink / raw) To: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, liweiwei, lazyparser, lustrew, luruibo2000 Signed-off-by: liweiwei <liweiwei@iscas.ac.cn> Signed-off-by: wangjunqiang <wangjunqiang@iscas.ac.cn> --- target/riscv/bitmanip_helper.c | 94 +++++++++++++++++++++++++ target/riscv/helper.h | 4 ++ target/riscv/insn32.decode | 52 +++++++++----- target/riscv/insn_trans/trans_rvb.c.inc | 91 ++++++++++++++++++++---- target/riscv/translate.c | 82 +++++++++++++++++++++ 5 files changed, 292 insertions(+), 31 deletions(-) diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c index f1b5e5549f..1c6beb8216 100644 --- a/target/riscv/bitmanip_helper.c +++ b/target/riscv/bitmanip_helper.c @@ -49,3 +49,97 @@ target_ulong HELPER(clmulr)(target_ulong rs1, target_ulong rs2) return result; } + +static const uint64_t adjacent_masks[] = { + dup_const(MO_8, 0x55), + dup_const(MO_8, 0x33), + dup_const(MO_8, 0x0f), + dup_const(MO_16, 0xff), + dup_const(MO_32, 0xffff), + UINT32_MAX +}; + +static inline target_ulong do_swap(target_ulong x, uint64_t mask, int shift) +{ + return ((x & mask) << shift) | ((x & ~mask) >> shift); +} + +static target_ulong do_grev(target_ulong rs1, + target_ulong rs2, + int bits) +{ + target_ulong x = rs1; + int i, shift; + + for (i = 0, shift = 1; shift < bits; i++, shift <<= 1) { + if (rs2 & shift) { + x = do_swap(x, adjacent_masks[i], shift); + } + } + + return x; +} + +target_ulong HELPER(grev)(target_ulong rs1, target_ulong rs2) +{ + return do_grev(rs1, rs2, TARGET_LONG_BITS); +} + +target_ulong HELPER(xperm)(target_ulong rs1, target_ulong rs2, uint32_t sz_log2) +{ + target_ulong r = 0; + target_ulong sz = 1LL << sz_log2; + target_ulong mask = (1LL << sz) - 1; + for (int i = 0; i < TARGET_LONG_BITS; i += sz) { + target_ulong pos = ((rs2 >> i) & mask) << sz_log2; + if (pos < sizeof(target_ulong) * 8) { + r |= ((rs1 >> pos) & mask) << i; + } + } + return r; +} + +static const uint64_t shuf_masks[] = { + dup_const(MO_8, 0x44), + dup_const(MO_8, 0x30), + dup_const(MO_16, 0x0f00), + dup_const(MO_32, 0xff0000), + dup_const(MO_64, 0xffff00000000) +}; + +static inline target_ulong do_shuf_stage(target_ulong src, uint64_t maskL, + uint64_t maskR, int shift) +{ + target_ulong x = src & ~(maskL | maskR); + x |= ((src << shift) & maskL) | ((src >> shift) & maskR); + return x; +} + +target_ulong HELPER(unshfl)(target_ulong rs1, + target_ulong rs2) +{ + target_ulong x = rs1; + int i, shift; + int bits = TARGET_LONG_BITS >> 1; + for (i = 0, shift = 1; shift < bits; i++, shift <<= 1) { + if (rs2 & shift) { + x = do_shuf_stage(x, shuf_masks[i], shuf_masks[i] >> shift, shift); + } + } + return x; +} + +target_ulong HELPER(shfl)(target_ulong rs1, + target_ulong rs2) +{ + target_ulong x = rs1; + int i, shift; + shift = TARGET_LONG_BITS >> 2; + i = (shift == 8) ? 3 : 4; + for (; i >= 0; i--, shift >>= 1) { + if (rs2 & shift) { + x = do_shuf_stage(x, shuf_masks[i], shuf_masks[i] >> shift, shift); + } + } + return x; +} diff --git a/target/riscv/helper.h b/target/riscv/helper.h index c7a5376227..216aa4193b 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -61,6 +61,10 @@ DEF_HELPER_FLAGS_1(fclass_d, TCG_CALL_NO_RWG_SE, tl, i64) /* Bitmanip */ DEF_HELPER_FLAGS_2(clmul, TCG_CALL_NO_RWG_SE, tl, tl, tl) DEF_HELPER_FLAGS_2(clmulr, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(grev, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_3(xperm, TCG_CALL_NO_RWG_SE, tl, tl, tl, i32) +DEF_HELPER_FLAGS_2(shfl, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(unshfl, TCG_CALL_NO_RWG_SE, tl, tl, tl) /* Special functions */ DEF_HELPER_2(csrr, tl, env, int) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 2f251dac1b..a5333c4533 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -672,8 +672,22 @@ sh2add_uw 0010000 .......... 100 ..... 0111011 @r sh3add_uw 0010000 .......... 110 ..... 0111011 @r slli_uw 00001 ............ 001 ..... 0011011 @sh -# *** RV32 Zbb Standard Extension *** +# *** RV32 Zbb/Zbkb Standard Extension *** andn 0100000 .......... 111 ..... 0110011 @r +rol 0110000 .......... 001 ..... 0110011 @r +ror 0110000 .......... 101 ..... 0110011 @r +rori 01100 ............ 101 ..... 0010011 @sh +# The encoding for rev8 differs between RV32 and RV64. +# rev8_32 denotes the RV32 variant. +rev8_32 011010 011000 ..... 101 ..... 0010011 @r2 +# The encoding for zext.h differs between RV32 and RV64. +# zext_h_32 denotes the RV32 variant. +{ + zext_h_32 0000100 00000 ..... 100 ..... 0110011 @r2 + pack 0000100 ..... ..... 100 ..... 0110011 @r +} +xnor 0100000 .......... 100 ..... 0110011 @r +# *** RV32 extra Zbb Standard Extension *** clz 011000 000000 ..... 001 ..... 0010011 @r2 cpop 011000 000010 ..... 001 ..... 0010011 @r2 ctz 011000 000001 ..... 001 ..... 0010011 @r2 @@ -683,23 +697,15 @@ min 0000101 .......... 100 ..... 0110011 @r minu 0000101 .......... 101 ..... 0110011 @r orc_b 001010 000111 ..... 101 ..... 0010011 @r2 orn 0100000 .......... 110 ..... 0110011 @r -# The encoding for rev8 differs between RV32 and RV64. -# rev8_32 denotes the RV32 variant. -rev8_32 011010 011000 ..... 101 ..... 0010011 @r2 -rol 0110000 .......... 001 ..... 0110011 @r -ror 0110000 .......... 101 ..... 0110011 @r -rori 01100 ............ 101 ..... 0010011 @sh sext_b 011000 000100 ..... 001 ..... 0010011 @r2 sext_h 011000 000101 ..... 001 ..... 0010011 @r2 -xnor 0100000 .......... 100 ..... 0110011 @r -# The encoding for zext.h differs between RV32 and RV64. -# zext_h_32 denotes the RV32 variant. -zext_h_32 0000100 00000 ..... 100 ..... 0110011 @r2 +# *** RV32 extra Zbkb Standard Extension *** +brev8 0110100 00111 ..... 101 ..... 0010011 @r2 #grevi +packh 0000100 .......... 111 ..... 0110011 @r +unzip 0000100 01111 ..... 101 ..... 0010011 @r2 #unshfl +zip 0000100 01111 ..... 001 ..... 0010011 @r2 #shfl -# *** RV64 Zbb Standard Extension (in addition to RV32 Zbb) *** -clzw 0110000 00000 ..... 001 ..... 0011011 @r2 -ctzw 0110000 00001 ..... 001 ..... 0011011 @r2 -cpopw 0110000 00010 ..... 001 ..... 0011011 @r2 +# *** RV64 Zbb/Zbkb Standard Extension (in addition to RV32 Zbb/Zbkb) *** # The encoding for rev8 differs between RV32 and RV64. # When executing on RV64, the encoding used in RV32 is an illegal # instruction, so we use different handler functions to differentiate. @@ -710,13 +716,25 @@ rorw 0110000 .......... 101 ..... 0111011 @r # The encoding for zext.h differs between RV32 and RV64. # When executing on RV64, the encoding used in RV32 is an illegal # instruction, so we use different handler functions to differentiate. -zext_h_64 0000100 00000 ..... 100 ..... 0111011 @r2 +{ + zext_h_64 0000100 00000 ..... 100 ..... 0111011 @r2 + packw 0000100 ..... ..... 100 ..... 0111011 @r +} +# *** RV64 extra Zbb Standard Extension (in addition to RV32 Zbb) *** +clzw 0110000 00000 ..... 001 ..... 0011011 @r2 +ctzw 0110000 00001 ..... 001 ..... 0011011 @r2 +cpopw 0110000 00010 ..... 001 ..... 0011011 @r2 -# *** RV32 Zbc Standard Extension *** +# *** RV32 Zbc/Zbkc Standard Extension *** clmul 0000101 .......... 001 ..... 0110011 @r clmulh 0000101 .......... 011 ..... 0110011 @r +# *** RV32 extra Zbc Standard Extension *** clmulr 0000101 .......... 010 ..... 0110011 @r +# *** RV32 Zbkx Standard Extension *** +xperm4 0010100 .......... 010 ..... 0110011 @r +xperm8 0010100 .......... 100 ..... 0110011 @r + # *** RV32 Zbs Standard Extension *** bclr 0100100 .......... 001 ..... 0110011 @r bclri 01001. ........... 001 ..... 0010011 @sh diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc index c8d31907c5..2b09d13b10 100644 --- a/target/riscv/insn_trans/trans_rvb.c.inc +++ b/target/riscv/insn_trans/trans_rvb.c.inc @@ -1,5 +1,5 @@ /* - * RISC-V translation routines for the Zb[abcs] Standard Extension. + * RISC-V translation routines for the Zb[abcs] and Zbk[bcx] Standard Extension. * * Copyright (c) 2020 Kito Cheng, kito.cheng@sifive.com * Copyright (c) 2020 Frank Chang, frank.chang@sifive.com @@ -42,6 +42,18 @@ } \ } while (0) +#define REQUIRE_ZBKB(ctx) do { \ + if (!RISCV_CPU(ctx->cs)->cfg.ext_zbkb) { \ + return false; \ + } \ +} while (0) + +#define REQUIRE_ZBKX(ctx) do { \ + if (!RISCV_CPU(ctx->cs)->cfg.ext_zbkx) { \ + return false; \ + } \ +} while (0) + static void gen_clz(TCGv ret, TCGv arg1) { tcg_gen_clzi_tl(ret, arg1, TARGET_LONG_BITS); @@ -85,19 +97,19 @@ static bool trans_cpop(DisasContext *ctx, arg_cpop *a) static bool trans_andn(DisasContext *ctx, arg_andn *a) { - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); return gen_arith(ctx, a, EXT_NONE, tcg_gen_andc_tl); } static bool trans_orn(DisasContext *ctx, arg_orn *a) { - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); return gen_arith(ctx, a, EXT_NONE, tcg_gen_orc_tl); } static bool trans_xnor(DisasContext *ctx, arg_xnor *a) { - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); return gen_arith(ctx, a, EXT_NONE, tcg_gen_eqv_tl); } @@ -247,7 +259,7 @@ static void gen_rorw(TCGv ret, TCGv arg1, TCGv arg2) static bool trans_ror(DisasContext *ctx, arg_ror *a) { - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); return gen_shift_per_ol(ctx, a, EXT_NONE, tcg_gen_rotr_tl, gen_rorw); } @@ -264,7 +276,7 @@ static void gen_roriw(TCGv ret, TCGv arg1, target_long shamt) static bool trans_rori(DisasContext *ctx, arg_rori *a) { - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); return gen_shift_imm_fn_per_ol(ctx, a, EXT_NONE, tcg_gen_rotri_tl, gen_roriw); } @@ -289,7 +301,7 @@ static void gen_rolw(TCGv ret, TCGv arg1, TCGv arg2) static bool trans_rol(DisasContext *ctx, arg_rol *a) { - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); return gen_shift_per_ol(ctx, a, EXT_NONE, tcg_gen_rotl_tl, gen_rolw); } @@ -301,14 +313,14 @@ static void gen_rev8_32(TCGv ret, TCGv src1) static bool trans_rev8_32(DisasContext *ctx, arg_rev8_32 *a) { REQUIRE_32BIT(ctx); - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); return gen_unary(ctx, a, EXT_NONE, gen_rev8_32); } static bool trans_rev8_64(DisasContext *ctx, arg_rev8_64 *a) { REQUIRE_64BIT(ctx); - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); return gen_unary(ctx, a, EXT_NONE, tcg_gen_bswap_tl); } @@ -403,7 +415,7 @@ static bool trans_cpopw(DisasContext *ctx, arg_cpopw *a) static bool trans_rorw(DisasContext *ctx, arg_rorw *a) { REQUIRE_64BIT(ctx); - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); ctx->ol = MXL_RV32; return gen_shift(ctx, a, EXT_NONE, gen_rorw); } @@ -411,7 +423,7 @@ static bool trans_rorw(DisasContext *ctx, arg_rorw *a) static bool trans_roriw(DisasContext *ctx, arg_roriw *a) { REQUIRE_64BIT(ctx); - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); ctx->ol = MXL_RV32; return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_roriw); } @@ -419,7 +431,7 @@ static bool trans_roriw(DisasContext *ctx, arg_roriw *a) static bool trans_rolw(DisasContext *ctx, arg_rolw *a) { REQUIRE_64BIT(ctx); - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); ctx->ol = MXL_RV32; return gen_shift(ctx, a, EXT_NONE, gen_rolw); } @@ -483,7 +495,7 @@ static bool trans_slli_uw(DisasContext *ctx, arg_slli_uw *a) static bool trans_clmul(DisasContext *ctx, arg_clmul *a) { - REQUIRE_ZBC(ctx); + REQUIRE_EITHER_EXT(ctx, zbc, zbkc); return gen_arith(ctx, a, EXT_NONE, gen_helper_clmul); } @@ -495,7 +507,7 @@ static void gen_clmulh(TCGv dst, TCGv src1, TCGv src2) static bool trans_clmulh(DisasContext *ctx, arg_clmulr *a) { - REQUIRE_ZBC(ctx); + REQUIRE_EITHER_EXT(ctx, zbc, zbkc); return gen_arith(ctx, a, EXT_NONE, gen_clmulh); } @@ -504,3 +516,54 @@ static bool trans_clmulr(DisasContext *ctx, arg_clmulh *a) REQUIRE_ZBC(ctx); return gen_arith(ctx, a, EXT_NONE, gen_helper_clmulr); } + +static bool trans_brev8(DisasContext *ctx, arg_brev8 *a) +{ + REQUIRE_ZBKB(ctx); + return gen_grevi(ctx, a, 0x7); +} + +static bool trans_pack(DisasContext *ctx, arg_pack *a) +{ + REQUIRE_ZBKB(ctx); + return gen_arith(ctx, a, EXT_NONE, gen_pack); +} + +static bool trans_packh(DisasContext *ctx, arg_packh *a) +{ + REQUIRE_ZBKB(ctx); + return gen_arith(ctx, a, EXT_NONE, gen_packh); +} + +static bool trans_packw(DisasContext *ctx, arg_packw *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_ZBKB(ctx); + return gen_arith(ctx, a, EXT_NONE, gen_packw); +} + +static bool trans_unzip(DisasContext *ctx, arg_unzip *a) +{ + REQUIRE_ZBKB(ctx); + REQUIRE_32BIT(ctx); + return gen_shufi(ctx, a, 0xf, gen_helper_unshfl); +} + +static bool trans_zip(DisasContext *ctx, arg_zip *a) +{ + REQUIRE_ZBKB(ctx); + REQUIRE_32BIT(ctx); + return gen_shufi(ctx, a, 0xf, gen_helper_shfl); +} + +static bool trans_xperm4(DisasContext *ctx, arg_xperm4 *a) +{ + REQUIRE_ZBKX(ctx); + return gen_xperm(ctx, a, 2); +} + +static bool trans_xperm8(DisasContext *ctx, arg_xperm8 *a) +{ + REQUIRE_ZBKX(ctx); + return gen_xperm(ctx, a, 3); +} diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 1d57bc97b5..5b868cd53f 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -374,6 +374,13 @@ EX_SH(12) } \ } while (0) +#define REQUIRE_EITHER_EXT(ctx, A, B) do { \ + if (!RISCV_CPU(ctx->cs)->cfg.ext_##A && \ + !RISCV_CPU(ctx->cs)->cfg.ext_##B) { \ + return false; \ + } \ +} while (0) + static int ex_rvc_register(DisasContext *ctx, int reg) { return 8 + reg; @@ -556,6 +563,81 @@ static bool gen_unary_per_ol(DisasContext *ctx, arg_r2 *a, DisasExtend ext, return gen_unary(ctx, a, ext, f_tl); } +static bool gen_xperm(DisasContext *ctx, arg_r *a, int32_t size) +{ + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + TCGv_i32 sz = tcg_const_i32(size); + gen_helper_xperm(dest, src1, src2, sz); + + gen_set_gpr(ctx, a->rd, dest); + tcg_temp_free_i32(sz); + return true; +} + +static bool gen_grevi(DisasContext *ctx, arg_r2 *a, int shamt) +{ + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + if (shamt == (TARGET_LONG_BITS - 8)) { + /* rev8, byte swaps */ + tcg_gen_bswap_tl(dest, src1); + } else { + TCGv src2 = tcg_temp_new(); + tcg_gen_movi_tl(src2, shamt); + gen_helper_grev(dest, src1, src2); + tcg_temp_free(src2); + } + + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static void gen_pack(TCGv ret, TCGv src1, TCGv src2) +{ + tcg_gen_deposit_tl(ret, src1, src2, + TARGET_LONG_BITS / 2, + TARGET_LONG_BITS / 2); +} + +static void gen_packh(TCGv ret, TCGv src1, TCGv src2) +{ + TCGv t = tcg_temp_new(); + tcg_gen_ext8u_tl(t, src2); + tcg_gen_deposit_tl(ret, src1, t, 8, TARGET_LONG_BITS - 8); + tcg_temp_free(t); +} + +static void gen_packw(TCGv ret, TCGv src1, TCGv src2) +{ + TCGv t = tcg_temp_new(); + tcg_gen_ext16s_tl(t, src2); + tcg_gen_deposit_tl(ret, src1, t, 16, 48); + tcg_temp_free(t); +} + +static bool gen_shufi(DisasContext *ctx, arg_r2 *a, int shamt, + void(*func)(TCGv, TCGv, TCGv)) +{ + if (shamt >= TARGET_LONG_BITS / 2) { + return false; + } + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = tcg_temp_new(); + + tcg_gen_movi_tl(src2, shamt); + (*func)(dest, src1, src2); + + gen_set_gpr(ctx, a->rd, dest); + tcg_temp_free(src2); + return true; +} + static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc) { DisasContext *ctx = container_of(dcbase, DisasContext, base); -- 2.17.1 ^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC 2/6] target/riscv: rvk: add implementation of instructions for Zbk* - reuse partial instructions of Zbb/Zbc extensions - add brev8 packh, unzip, zip, etc. @ 2021-11-02 3:11 ` liweiwei 0 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-02 3:11 UTC (permalink / raw) To: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: luruibo2000, lustrew, wangjunqiang, lazyparser, liweiwei Signed-off-by: liweiwei <liweiwei@iscas.ac.cn> Signed-off-by: wangjunqiang <wangjunqiang@iscas.ac.cn> --- target/riscv/bitmanip_helper.c | 94 +++++++++++++++++++++++++ target/riscv/helper.h | 4 ++ target/riscv/insn32.decode | 52 +++++++++----- target/riscv/insn_trans/trans_rvb.c.inc | 91 ++++++++++++++++++++---- target/riscv/translate.c | 82 +++++++++++++++++++++ 5 files changed, 292 insertions(+), 31 deletions(-) diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c index f1b5e5549f..1c6beb8216 100644 --- a/target/riscv/bitmanip_helper.c +++ b/target/riscv/bitmanip_helper.c @@ -49,3 +49,97 @@ target_ulong HELPER(clmulr)(target_ulong rs1, target_ulong rs2) return result; } + +static const uint64_t adjacent_masks[] = { + dup_const(MO_8, 0x55), + dup_const(MO_8, 0x33), + dup_const(MO_8, 0x0f), + dup_const(MO_16, 0xff), + dup_const(MO_32, 0xffff), + UINT32_MAX +}; + +static inline target_ulong do_swap(target_ulong x, uint64_t mask, int shift) +{ + return ((x & mask) << shift) | ((x & ~mask) >> shift); +} + +static target_ulong do_grev(target_ulong rs1, + target_ulong rs2, + int bits) +{ + target_ulong x = rs1; + int i, shift; + + for (i = 0, shift = 1; shift < bits; i++, shift <<= 1) { + if (rs2 & shift) { + x = do_swap(x, adjacent_masks[i], shift); + } + } + + return x; +} + +target_ulong HELPER(grev)(target_ulong rs1, target_ulong rs2) +{ + return do_grev(rs1, rs2, TARGET_LONG_BITS); +} + +target_ulong HELPER(xperm)(target_ulong rs1, target_ulong rs2, uint32_t sz_log2) +{ + target_ulong r = 0; + target_ulong sz = 1LL << sz_log2; + target_ulong mask = (1LL << sz) - 1; + for (int i = 0; i < TARGET_LONG_BITS; i += sz) { + target_ulong pos = ((rs2 >> i) & mask) << sz_log2; + if (pos < sizeof(target_ulong) * 8) { + r |= ((rs1 >> pos) & mask) << i; + } + } + return r; +} + +static const uint64_t shuf_masks[] = { + dup_const(MO_8, 0x44), + dup_const(MO_8, 0x30), + dup_const(MO_16, 0x0f00), + dup_const(MO_32, 0xff0000), + dup_const(MO_64, 0xffff00000000) +}; + +static inline target_ulong do_shuf_stage(target_ulong src, uint64_t maskL, + uint64_t maskR, int shift) +{ + target_ulong x = src & ~(maskL | maskR); + x |= ((src << shift) & maskL) | ((src >> shift) & maskR); + return x; +} + +target_ulong HELPER(unshfl)(target_ulong rs1, + target_ulong rs2) +{ + target_ulong x = rs1; + int i, shift; + int bits = TARGET_LONG_BITS >> 1; + for (i = 0, shift = 1; shift < bits; i++, shift <<= 1) { + if (rs2 & shift) { + x = do_shuf_stage(x, shuf_masks[i], shuf_masks[i] >> shift, shift); + } + } + return x; +} + +target_ulong HELPER(shfl)(target_ulong rs1, + target_ulong rs2) +{ + target_ulong x = rs1; + int i, shift; + shift = TARGET_LONG_BITS >> 2; + i = (shift == 8) ? 3 : 4; + for (; i >= 0; i--, shift >>= 1) { + if (rs2 & shift) { + x = do_shuf_stage(x, shuf_masks[i], shuf_masks[i] >> shift, shift); + } + } + return x; +} diff --git a/target/riscv/helper.h b/target/riscv/helper.h index c7a5376227..216aa4193b 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -61,6 +61,10 @@ DEF_HELPER_FLAGS_1(fclass_d, TCG_CALL_NO_RWG_SE, tl, i64) /* Bitmanip */ DEF_HELPER_FLAGS_2(clmul, TCG_CALL_NO_RWG_SE, tl, tl, tl) DEF_HELPER_FLAGS_2(clmulr, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(grev, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_3(xperm, TCG_CALL_NO_RWG_SE, tl, tl, tl, i32) +DEF_HELPER_FLAGS_2(shfl, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(unshfl, TCG_CALL_NO_RWG_SE, tl, tl, tl) /* Special functions */ DEF_HELPER_2(csrr, tl, env, int) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 2f251dac1b..a5333c4533 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -672,8 +672,22 @@ sh2add_uw 0010000 .......... 100 ..... 0111011 @r sh3add_uw 0010000 .......... 110 ..... 0111011 @r slli_uw 00001 ............ 001 ..... 0011011 @sh -# *** RV32 Zbb Standard Extension *** +# *** RV32 Zbb/Zbkb Standard Extension *** andn 0100000 .......... 111 ..... 0110011 @r +rol 0110000 .......... 001 ..... 0110011 @r +ror 0110000 .......... 101 ..... 0110011 @r +rori 01100 ............ 101 ..... 0010011 @sh +# The encoding for rev8 differs between RV32 and RV64. +# rev8_32 denotes the RV32 variant. +rev8_32 011010 011000 ..... 101 ..... 0010011 @r2 +# The encoding for zext.h differs between RV32 and RV64. +# zext_h_32 denotes the RV32 variant. +{ + zext_h_32 0000100 00000 ..... 100 ..... 0110011 @r2 + pack 0000100 ..... ..... 100 ..... 0110011 @r +} +xnor 0100000 .......... 100 ..... 0110011 @r +# *** RV32 extra Zbb Standard Extension *** clz 011000 000000 ..... 001 ..... 0010011 @r2 cpop 011000 000010 ..... 001 ..... 0010011 @r2 ctz 011000 000001 ..... 001 ..... 0010011 @r2 @@ -683,23 +697,15 @@ min 0000101 .......... 100 ..... 0110011 @r minu 0000101 .......... 101 ..... 0110011 @r orc_b 001010 000111 ..... 101 ..... 0010011 @r2 orn 0100000 .......... 110 ..... 0110011 @r -# The encoding for rev8 differs between RV32 and RV64. -# rev8_32 denotes the RV32 variant. -rev8_32 011010 011000 ..... 101 ..... 0010011 @r2 -rol 0110000 .......... 001 ..... 0110011 @r -ror 0110000 .......... 101 ..... 0110011 @r -rori 01100 ............ 101 ..... 0010011 @sh sext_b 011000 000100 ..... 001 ..... 0010011 @r2 sext_h 011000 000101 ..... 001 ..... 0010011 @r2 -xnor 0100000 .......... 100 ..... 0110011 @r -# The encoding for zext.h differs between RV32 and RV64. -# zext_h_32 denotes the RV32 variant. -zext_h_32 0000100 00000 ..... 100 ..... 0110011 @r2 +# *** RV32 extra Zbkb Standard Extension *** +brev8 0110100 00111 ..... 101 ..... 0010011 @r2 #grevi +packh 0000100 .......... 111 ..... 0110011 @r +unzip 0000100 01111 ..... 101 ..... 0010011 @r2 #unshfl +zip 0000100 01111 ..... 001 ..... 0010011 @r2 #shfl -# *** RV64 Zbb Standard Extension (in addition to RV32 Zbb) *** -clzw 0110000 00000 ..... 001 ..... 0011011 @r2 -ctzw 0110000 00001 ..... 001 ..... 0011011 @r2 -cpopw 0110000 00010 ..... 001 ..... 0011011 @r2 +# *** RV64 Zbb/Zbkb Standard Extension (in addition to RV32 Zbb/Zbkb) *** # The encoding for rev8 differs between RV32 and RV64. # When executing on RV64, the encoding used in RV32 is an illegal # instruction, so we use different handler functions to differentiate. @@ -710,13 +716,25 @@ rorw 0110000 .......... 101 ..... 0111011 @r # The encoding for zext.h differs between RV32 and RV64. # When executing on RV64, the encoding used in RV32 is an illegal # instruction, so we use different handler functions to differentiate. -zext_h_64 0000100 00000 ..... 100 ..... 0111011 @r2 +{ + zext_h_64 0000100 00000 ..... 100 ..... 0111011 @r2 + packw 0000100 ..... ..... 100 ..... 0111011 @r +} +# *** RV64 extra Zbb Standard Extension (in addition to RV32 Zbb) *** +clzw 0110000 00000 ..... 001 ..... 0011011 @r2 +ctzw 0110000 00001 ..... 001 ..... 0011011 @r2 +cpopw 0110000 00010 ..... 001 ..... 0011011 @r2 -# *** RV32 Zbc Standard Extension *** +# *** RV32 Zbc/Zbkc Standard Extension *** clmul 0000101 .......... 001 ..... 0110011 @r clmulh 0000101 .......... 011 ..... 0110011 @r +# *** RV32 extra Zbc Standard Extension *** clmulr 0000101 .......... 010 ..... 0110011 @r +# *** RV32 Zbkx Standard Extension *** +xperm4 0010100 .......... 010 ..... 0110011 @r +xperm8 0010100 .......... 100 ..... 0110011 @r + # *** RV32 Zbs Standard Extension *** bclr 0100100 .......... 001 ..... 0110011 @r bclri 01001. ........... 001 ..... 0010011 @sh diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc index c8d31907c5..2b09d13b10 100644 --- a/target/riscv/insn_trans/trans_rvb.c.inc +++ b/target/riscv/insn_trans/trans_rvb.c.inc @@ -1,5 +1,5 @@ /* - * RISC-V translation routines for the Zb[abcs] Standard Extension. + * RISC-V translation routines for the Zb[abcs] and Zbk[bcx] Standard Extension. * * Copyright (c) 2020 Kito Cheng, kito.cheng@sifive.com * Copyright (c) 2020 Frank Chang, frank.chang@sifive.com @@ -42,6 +42,18 @@ } \ } while (0) +#define REQUIRE_ZBKB(ctx) do { \ + if (!RISCV_CPU(ctx->cs)->cfg.ext_zbkb) { \ + return false; \ + } \ +} while (0) + +#define REQUIRE_ZBKX(ctx) do { \ + if (!RISCV_CPU(ctx->cs)->cfg.ext_zbkx) { \ + return false; \ + } \ +} while (0) + static void gen_clz(TCGv ret, TCGv arg1) { tcg_gen_clzi_tl(ret, arg1, TARGET_LONG_BITS); @@ -85,19 +97,19 @@ static bool trans_cpop(DisasContext *ctx, arg_cpop *a) static bool trans_andn(DisasContext *ctx, arg_andn *a) { - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); return gen_arith(ctx, a, EXT_NONE, tcg_gen_andc_tl); } static bool trans_orn(DisasContext *ctx, arg_orn *a) { - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); return gen_arith(ctx, a, EXT_NONE, tcg_gen_orc_tl); } static bool trans_xnor(DisasContext *ctx, arg_xnor *a) { - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); return gen_arith(ctx, a, EXT_NONE, tcg_gen_eqv_tl); } @@ -247,7 +259,7 @@ static void gen_rorw(TCGv ret, TCGv arg1, TCGv arg2) static bool trans_ror(DisasContext *ctx, arg_ror *a) { - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); return gen_shift_per_ol(ctx, a, EXT_NONE, tcg_gen_rotr_tl, gen_rorw); } @@ -264,7 +276,7 @@ static void gen_roriw(TCGv ret, TCGv arg1, target_long shamt) static bool trans_rori(DisasContext *ctx, arg_rori *a) { - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); return gen_shift_imm_fn_per_ol(ctx, a, EXT_NONE, tcg_gen_rotri_tl, gen_roriw); } @@ -289,7 +301,7 @@ static void gen_rolw(TCGv ret, TCGv arg1, TCGv arg2) static bool trans_rol(DisasContext *ctx, arg_rol *a) { - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); return gen_shift_per_ol(ctx, a, EXT_NONE, tcg_gen_rotl_tl, gen_rolw); } @@ -301,14 +313,14 @@ static void gen_rev8_32(TCGv ret, TCGv src1) static bool trans_rev8_32(DisasContext *ctx, arg_rev8_32 *a) { REQUIRE_32BIT(ctx); - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); return gen_unary(ctx, a, EXT_NONE, gen_rev8_32); } static bool trans_rev8_64(DisasContext *ctx, arg_rev8_64 *a) { REQUIRE_64BIT(ctx); - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); return gen_unary(ctx, a, EXT_NONE, tcg_gen_bswap_tl); } @@ -403,7 +415,7 @@ static bool trans_cpopw(DisasContext *ctx, arg_cpopw *a) static bool trans_rorw(DisasContext *ctx, arg_rorw *a) { REQUIRE_64BIT(ctx); - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); ctx->ol = MXL_RV32; return gen_shift(ctx, a, EXT_NONE, gen_rorw); } @@ -411,7 +423,7 @@ static bool trans_rorw(DisasContext *ctx, arg_rorw *a) static bool trans_roriw(DisasContext *ctx, arg_roriw *a) { REQUIRE_64BIT(ctx); - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); ctx->ol = MXL_RV32; return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_roriw); } @@ -419,7 +431,7 @@ static bool trans_roriw(DisasContext *ctx, arg_roriw *a) static bool trans_rolw(DisasContext *ctx, arg_rolw *a) { REQUIRE_64BIT(ctx); - REQUIRE_ZBB(ctx); + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); ctx->ol = MXL_RV32; return gen_shift(ctx, a, EXT_NONE, gen_rolw); } @@ -483,7 +495,7 @@ static bool trans_slli_uw(DisasContext *ctx, arg_slli_uw *a) static bool trans_clmul(DisasContext *ctx, arg_clmul *a) { - REQUIRE_ZBC(ctx); + REQUIRE_EITHER_EXT(ctx, zbc, zbkc); return gen_arith(ctx, a, EXT_NONE, gen_helper_clmul); } @@ -495,7 +507,7 @@ static void gen_clmulh(TCGv dst, TCGv src1, TCGv src2) static bool trans_clmulh(DisasContext *ctx, arg_clmulr *a) { - REQUIRE_ZBC(ctx); + REQUIRE_EITHER_EXT(ctx, zbc, zbkc); return gen_arith(ctx, a, EXT_NONE, gen_clmulh); } @@ -504,3 +516,54 @@ static bool trans_clmulr(DisasContext *ctx, arg_clmulh *a) REQUIRE_ZBC(ctx); return gen_arith(ctx, a, EXT_NONE, gen_helper_clmulr); } + +static bool trans_brev8(DisasContext *ctx, arg_brev8 *a) +{ + REQUIRE_ZBKB(ctx); + return gen_grevi(ctx, a, 0x7); +} + +static bool trans_pack(DisasContext *ctx, arg_pack *a) +{ + REQUIRE_ZBKB(ctx); + return gen_arith(ctx, a, EXT_NONE, gen_pack); +} + +static bool trans_packh(DisasContext *ctx, arg_packh *a) +{ + REQUIRE_ZBKB(ctx); + return gen_arith(ctx, a, EXT_NONE, gen_packh); +} + +static bool trans_packw(DisasContext *ctx, arg_packw *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_ZBKB(ctx); + return gen_arith(ctx, a, EXT_NONE, gen_packw); +} + +static bool trans_unzip(DisasContext *ctx, arg_unzip *a) +{ + REQUIRE_ZBKB(ctx); + REQUIRE_32BIT(ctx); + return gen_shufi(ctx, a, 0xf, gen_helper_unshfl); +} + +static bool trans_zip(DisasContext *ctx, arg_zip *a) +{ + REQUIRE_ZBKB(ctx); + REQUIRE_32BIT(ctx); + return gen_shufi(ctx, a, 0xf, gen_helper_shfl); +} + +static bool trans_xperm4(DisasContext *ctx, arg_xperm4 *a) +{ + REQUIRE_ZBKX(ctx); + return gen_xperm(ctx, a, 2); +} + +static bool trans_xperm8(DisasContext *ctx, arg_xperm8 *a) +{ + REQUIRE_ZBKX(ctx); + return gen_xperm(ctx, a, 3); +} diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 1d57bc97b5..5b868cd53f 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -374,6 +374,13 @@ EX_SH(12) } \ } while (0) +#define REQUIRE_EITHER_EXT(ctx, A, B) do { \ + if (!RISCV_CPU(ctx->cs)->cfg.ext_##A && \ + !RISCV_CPU(ctx->cs)->cfg.ext_##B) { \ + return false; \ + } \ +} while (0) + static int ex_rvc_register(DisasContext *ctx, int reg) { return 8 + reg; @@ -556,6 +563,81 @@ static bool gen_unary_per_ol(DisasContext *ctx, arg_r2 *a, DisasExtend ext, return gen_unary(ctx, a, ext, f_tl); } +static bool gen_xperm(DisasContext *ctx, arg_r *a, int32_t size) +{ + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + TCGv_i32 sz = tcg_const_i32(size); + gen_helper_xperm(dest, src1, src2, sz); + + gen_set_gpr(ctx, a->rd, dest); + tcg_temp_free_i32(sz); + return true; +} + +static bool gen_grevi(DisasContext *ctx, arg_r2 *a, int shamt) +{ + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + if (shamt == (TARGET_LONG_BITS - 8)) { + /* rev8, byte swaps */ + tcg_gen_bswap_tl(dest, src1); + } else { + TCGv src2 = tcg_temp_new(); + tcg_gen_movi_tl(src2, shamt); + gen_helper_grev(dest, src1, src2); + tcg_temp_free(src2); + } + + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static void gen_pack(TCGv ret, TCGv src1, TCGv src2) +{ + tcg_gen_deposit_tl(ret, src1, src2, + TARGET_LONG_BITS / 2, + TARGET_LONG_BITS / 2); +} + +static void gen_packh(TCGv ret, TCGv src1, TCGv src2) +{ + TCGv t = tcg_temp_new(); + tcg_gen_ext8u_tl(t, src2); + tcg_gen_deposit_tl(ret, src1, t, 8, TARGET_LONG_BITS - 8); + tcg_temp_free(t); +} + +static void gen_packw(TCGv ret, TCGv src1, TCGv src2) +{ + TCGv t = tcg_temp_new(); + tcg_gen_ext16s_tl(t, src2); + tcg_gen_deposit_tl(ret, src1, t, 16, 48); + tcg_temp_free(t); +} + +static bool gen_shufi(DisasContext *ctx, arg_r2 *a, int shamt, + void(*func)(TCGv, TCGv, TCGv)) +{ + if (shamt >= TARGET_LONG_BITS / 2) { + return false; + } + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = tcg_temp_new(); + + tcg_gen_movi_tl(src2, shamt); + (*func)(dest, src1, src2); + + gen_set_gpr(ctx, a->rd, dest); + tcg_temp_free(src2); + return true; +} + static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc) { DisasContext *ctx = container_of(dcbase, DisasContext, base); -- 2.17.1 ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [RFC 2/6] target/riscv: rvk: add implementation of instructions for Zbk* - reuse partial instructions of Zbb/Zbc extensions - add brev8 packh, unzip, zip, etc. 2021-11-02 3:11 ` liweiwei @ 2021-11-02 15:44 ` Richard Henderson -1 siblings, 0 replies; 34+ messages in thread From: Richard Henderson @ 2021-11-02 15:44 UTC (permalink / raw) To: liweiwei, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, luruibo2000, lustrew On 11/1/21 11:11 PM, liweiwei wrote: > Signed-off-by: liweiwei <liweiwei@iscas.ac.cn> > Signed-off-by: wangjunqiang <wangjunqiang@iscas.ac.cn> You managed to get the whole patch description into the subject line. Please break it up. > +target_ulong HELPER(grev)(target_ulong rs1, target_ulong rs2) > +{ > + return do_grev(rs1, rs2, TARGET_LONG_BITS); > +} Are we expecting to see the full grev instruction at any point? If not, we can certainly implement Zbk with a simpler implementation. > +target_ulong HELPER(xperm)(target_ulong rs1, target_ulong rs2, uint32_t sz_log2) > +{ > + target_ulong r = 0; > + target_ulong sz = 1LL << sz_log2; > + target_ulong mask = (1LL << sz) - 1; > + for (int i = 0; i < TARGET_LONG_BITS; i += sz) { > + target_ulong pos = ((rs2 >> i) & mask) << sz_log2; > + if (pos < sizeof(target_ulong) * 8) { > + r |= ((rs1 >> pos) & mask) << i; > + } > + } > + return r; > +} This could become a static inline do_xperm, and provide two specific xperm4 and xperm8 helpers; the compiler would fold all of the sz_log2 stuff into a more efficient implementation. > +target_ulong HELPER(unshfl)(target_ulong rs1, > + target_ulong rs2) > +{ > + target_ulong x = rs1; > + int i, shift; > + int bits = TARGET_LONG_BITS >> 1; > + for (i = 0, shift = 1; shift < bits; i++, shift <<= 1) { > + if (rs2 & shift) { > + x = do_shuf_stage(x, shuf_masks[i], shuf_masks[i] >> shift, shift); > + } > + } > + return x; > +} > + > +target_ulong HELPER(shfl)(target_ulong rs1, > + target_ulong rs2) > +{ > + target_ulong x = rs1; > + int i, shift; > + shift = TARGET_LONG_BITS >> 2; > + i = (shift == 8) ? 3 : 4; > + for (; i >= 0; i--, shift >>= 1) { > + if (rs2 & shift) { > + x = do_shuf_stage(x, shuf_masks[i], shuf_masks[i] >> shift, shift); > + } > + } > + return x; > +} Similar comment as for grev. > +# The encoding for zext.h differs between RV32 and RV64. > +# zext_h_32 denotes the RV32 variant. > +{ > + zext_h_32 0000100 00000 ..... 100 ..... 0110011 @r2 > + pack 0000100 ..... ..... 100 ..... 0110011 @r > +} Note to self: improve tcg_gen_deposit to notice zeros, so that the more general pack compiles to zero-extension. > @@ -556,6 +563,81 @@ static bool gen_unary_per_ol(DisasContext *ctx, arg_r2 *a, DisasExtend ext, > return gen_unary(ctx, a, ext, f_tl); > } > > +static bool gen_xperm(DisasContext *ctx, arg_r *a, int32_t size) > +{ > + TCGv dest = dest_gpr(ctx, a->rd); > + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); > + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); > + > + TCGv_i32 sz = tcg_const_i32(size); > + gen_helper_xperm(dest, src1, src2, sz); > + > + gen_set_gpr(ctx, a->rd, dest); > + tcg_temp_free_i32(sz); > + return true; > +} > + > +static bool gen_grevi(DisasContext *ctx, arg_r2 *a, int shamt) > +{ > + TCGv dest = dest_gpr(ctx, a->rd); > + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); > + > + if (shamt == (TARGET_LONG_BITS - 8)) { > + /* rev8, byte swaps */ > + tcg_gen_bswap_tl(dest, src1); > + } else { > + TCGv src2 = tcg_temp_new(); > + tcg_gen_movi_tl(src2, shamt); > + gen_helper_grev(dest, src1, src2); > + tcg_temp_free(src2); > + } > + > + gen_set_gpr(ctx, a->rd, dest); > + return true; > +} > + > +static void gen_pack(TCGv ret, TCGv src1, TCGv src2) > +{ > + tcg_gen_deposit_tl(ret, src1, src2, > + TARGET_LONG_BITS / 2, > + TARGET_LONG_BITS / 2); > +} > + > +static void gen_packh(TCGv ret, TCGv src1, TCGv src2) > +{ > + TCGv t = tcg_temp_new(); > + tcg_gen_ext8u_tl(t, src2); > + tcg_gen_deposit_tl(ret, src1, t, 8, TARGET_LONG_BITS - 8); > + tcg_temp_free(t); > +} > + > +static void gen_packw(TCGv ret, TCGv src1, TCGv src2) > +{ > + TCGv t = tcg_temp_new(); > + tcg_gen_ext16s_tl(t, src2); > + tcg_gen_deposit_tl(ret, src1, t, 16, 48); > + tcg_temp_free(t); > +} > + > +static bool gen_shufi(DisasContext *ctx, arg_r2 *a, int shamt, > + void(*func)(TCGv, TCGv, TCGv)) > +{ > + if (shamt >= TARGET_LONG_BITS / 2) { > + return false; > + } > + > + TCGv dest = dest_gpr(ctx, a->rd); > + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); > + TCGv src2 = tcg_temp_new(); > + > + tcg_gen_movi_tl(src2, shamt); > + (*func)(dest, src1, src2); > + > + gen_set_gpr(ctx, a->rd, dest); > + tcg_temp_free(src2); > + return true; > +} All of the gen functions belong in insn_trans/trans_rvb.c.inc. r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [RFC 2/6] target/riscv: rvk: add implementation of instructions for Zbk* - reuse partial instructions of Zbb/Zbc extensions - add brev8 packh, unzip, zip, etc. @ 2021-11-02 15:44 ` Richard Henderson 0 siblings, 0 replies; 34+ messages in thread From: Richard Henderson @ 2021-11-02 15:44 UTC (permalink / raw) To: liweiwei, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, lustrew, luruibo2000 On 11/1/21 11:11 PM, liweiwei wrote: > Signed-off-by: liweiwei <liweiwei@iscas.ac.cn> > Signed-off-by: wangjunqiang <wangjunqiang@iscas.ac.cn> You managed to get the whole patch description into the subject line. Please break it up. > +target_ulong HELPER(grev)(target_ulong rs1, target_ulong rs2) > +{ > + return do_grev(rs1, rs2, TARGET_LONG_BITS); > +} Are we expecting to see the full grev instruction at any point? If not, we can certainly implement Zbk with a simpler implementation. > +target_ulong HELPER(xperm)(target_ulong rs1, target_ulong rs2, uint32_t sz_log2) > +{ > + target_ulong r = 0; > + target_ulong sz = 1LL << sz_log2; > + target_ulong mask = (1LL << sz) - 1; > + for (int i = 0; i < TARGET_LONG_BITS; i += sz) { > + target_ulong pos = ((rs2 >> i) & mask) << sz_log2; > + if (pos < sizeof(target_ulong) * 8) { > + r |= ((rs1 >> pos) & mask) << i; > + } > + } > + return r; > +} This could become a static inline do_xperm, and provide two specific xperm4 and xperm8 helpers; the compiler would fold all of the sz_log2 stuff into a more efficient implementation. > +target_ulong HELPER(unshfl)(target_ulong rs1, > + target_ulong rs2) > +{ > + target_ulong x = rs1; > + int i, shift; > + int bits = TARGET_LONG_BITS >> 1; > + for (i = 0, shift = 1; shift < bits; i++, shift <<= 1) { > + if (rs2 & shift) { > + x = do_shuf_stage(x, shuf_masks[i], shuf_masks[i] >> shift, shift); > + } > + } > + return x; > +} > + > +target_ulong HELPER(shfl)(target_ulong rs1, > + target_ulong rs2) > +{ > + target_ulong x = rs1; > + int i, shift; > + shift = TARGET_LONG_BITS >> 2; > + i = (shift == 8) ? 3 : 4; > + for (; i >= 0; i--, shift >>= 1) { > + if (rs2 & shift) { > + x = do_shuf_stage(x, shuf_masks[i], shuf_masks[i] >> shift, shift); > + } > + } > + return x; > +} Similar comment as for grev. > +# The encoding for zext.h differs between RV32 and RV64. > +# zext_h_32 denotes the RV32 variant. > +{ > + zext_h_32 0000100 00000 ..... 100 ..... 0110011 @r2 > + pack 0000100 ..... ..... 100 ..... 0110011 @r > +} Note to self: improve tcg_gen_deposit to notice zeros, so that the more general pack compiles to zero-extension. > @@ -556,6 +563,81 @@ static bool gen_unary_per_ol(DisasContext *ctx, arg_r2 *a, DisasExtend ext, > return gen_unary(ctx, a, ext, f_tl); > } > > +static bool gen_xperm(DisasContext *ctx, arg_r *a, int32_t size) > +{ > + TCGv dest = dest_gpr(ctx, a->rd); > + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); > + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); > + > + TCGv_i32 sz = tcg_const_i32(size); > + gen_helper_xperm(dest, src1, src2, sz); > + > + gen_set_gpr(ctx, a->rd, dest); > + tcg_temp_free_i32(sz); > + return true; > +} > + > +static bool gen_grevi(DisasContext *ctx, arg_r2 *a, int shamt) > +{ > + TCGv dest = dest_gpr(ctx, a->rd); > + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); > + > + if (shamt == (TARGET_LONG_BITS - 8)) { > + /* rev8, byte swaps */ > + tcg_gen_bswap_tl(dest, src1); > + } else { > + TCGv src2 = tcg_temp_new(); > + tcg_gen_movi_tl(src2, shamt); > + gen_helper_grev(dest, src1, src2); > + tcg_temp_free(src2); > + } > + > + gen_set_gpr(ctx, a->rd, dest); > + return true; > +} > + > +static void gen_pack(TCGv ret, TCGv src1, TCGv src2) > +{ > + tcg_gen_deposit_tl(ret, src1, src2, > + TARGET_LONG_BITS / 2, > + TARGET_LONG_BITS / 2); > +} > + > +static void gen_packh(TCGv ret, TCGv src1, TCGv src2) > +{ > + TCGv t = tcg_temp_new(); > + tcg_gen_ext8u_tl(t, src2); > + tcg_gen_deposit_tl(ret, src1, t, 8, TARGET_LONG_BITS - 8); > + tcg_temp_free(t); > +} > + > +static void gen_packw(TCGv ret, TCGv src1, TCGv src2) > +{ > + TCGv t = tcg_temp_new(); > + tcg_gen_ext16s_tl(t, src2); > + tcg_gen_deposit_tl(ret, src1, t, 16, 48); > + tcg_temp_free(t); > +} > + > +static bool gen_shufi(DisasContext *ctx, arg_r2 *a, int shamt, > + void(*func)(TCGv, TCGv, TCGv)) > +{ > + if (shamt >= TARGET_LONG_BITS / 2) { > + return false; > + } > + > + TCGv dest = dest_gpr(ctx, a->rd); > + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); > + TCGv src2 = tcg_temp_new(); > + > + tcg_gen_movi_tl(src2, shamt); > + (*func)(dest, src1, src2); > + > + gen_set_gpr(ctx, a->rd, dest); > + tcg_temp_free(src2); > + return true; > +} All of the gen functions belong in insn_trans/trans_rvb.c.inc. r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [RFC 2/6] target/riscv: rvk: add implementation of instructions for Zbk* - reuse partial instructions of Zbb/Zbc extensions - add brev8 packh, unzip, zip, etc. 2021-11-02 15:44 ` Richard Henderson @ 2021-11-03 0:56 ` liweiwei -1 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-03 0:56 UTC (permalink / raw) To: Richard Henderson, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, luruibo2000, lustrew Thanks for your suggestions. 在 2021/11/2 下午11:44, Richard Henderson 写道: > On 11/1/21 11:11 PM, liweiwei wrote: >> Signed-off-by: liweiwei <liweiwei@iscas.ac.cn> >> Signed-off-by: wangjunqiang <wangjunqiang@iscas.ac.cn> > > You managed to get the whole patch description into the subject line. > Please break it up. > OK. >> +target_ulong HELPER(grev)(target_ulong rs1, target_ulong rs2) >> +{ >> + return do_grev(rs1, rs2, TARGET_LONG_BITS); >> +} > > Are we expecting to see the full grev instruction at any point? If > not, we can certainly implement Zbk with a simpler implementation. The main idea that I add this helper is that grev may be added to B-extension later and it can be reused. However, it have no effect currently. I'll replace this with a simpler implementation. > >> +target_ulong HELPER(xperm)(target_ulong rs1, target_ulong rs2, >> uint32_t sz_log2) >> +{ >> + target_ulong r = 0; >> + target_ulong sz = 1LL << sz_log2; >> + target_ulong mask = (1LL << sz) - 1; >> + for (int i = 0; i < TARGET_LONG_BITS; i += sz) { >> + target_ulong pos = ((rs2 >> i) & mask) << sz_log2; >> + if (pos < sizeof(target_ulong) * 8) { >> + r |= ((rs1 >> pos) & mask) << i; >> + } >> + } >> + return r; >> +} > > This could become a static inline do_xperm, and provide two specific > xperm4 and xperm8 helpers; the compiler would fold all of the sz_log2 > stuff into a more efficient implementation. OK. > >> +target_ulong HELPER(unshfl)(target_ulong rs1, >> + target_ulong rs2) >> +{ >> + target_ulong x = rs1; >> + int i, shift; >> + int bits = TARGET_LONG_BITS >> 1; >> + for (i = 0, shift = 1; shift < bits; i++, shift <<= 1) { >> + if (rs2 & shift) { >> + x = do_shuf_stage(x, shuf_masks[i], shuf_masks[i] >> >> shift, shift); >> + } >> + } >> + return x; >> +} >> + >> +target_ulong HELPER(shfl)(target_ulong rs1, >> + target_ulong rs2) >> +{ >> + target_ulong x = rs1; >> + int i, shift; >> + shift = TARGET_LONG_BITS >> 2; >> + i = (shift == 8) ? 3 : 4; >> + for (; i >= 0; i--, shift >>= 1) { >> + if (rs2 & shift) { >> + x = do_shuf_stage(x, shuf_masks[i], shuf_masks[i] >> >> shift, shift); >> + } >> + } >> + return x; >> +} > > Similar comment as for grev. > >> +# The encoding for zext.h differs between RV32 and RV64. >> +# zext_h_32 denotes the RV32 variant. >> +{ >> + zext_h_32 0000100 00000 ..... 100 ..... 0110011 @r2 >> + pack 0000100 ..... ..... 100 ..... 0110011 @r >> +} > > Note to self: improve tcg_gen_deposit to notice zeros, so that the > more general pack compiles to zero-extension. > >> @@ -556,6 +563,81 @@ static bool gen_unary_per_ol(DisasContext *ctx, >> arg_r2 *a, DisasExtend ext, >> return gen_unary(ctx, a, ext, f_tl); >> } >> +static bool gen_xperm(DisasContext *ctx, arg_r *a, int32_t size) >> +{ >> + TCGv dest = dest_gpr(ctx, a->rd); >> + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); >> + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); >> + >> + TCGv_i32 sz = tcg_const_i32(size); >> + gen_helper_xperm(dest, src1, src2, sz); >> + >> + gen_set_gpr(ctx, a->rd, dest); >> + tcg_temp_free_i32(sz); >> + return true; >> +} >> + >> +static bool gen_grevi(DisasContext *ctx, arg_r2 *a, int shamt) >> +{ >> + TCGv dest = dest_gpr(ctx, a->rd); >> + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); >> + >> + if (shamt == (TARGET_LONG_BITS - 8)) { >> + /* rev8, byte swaps */ >> + tcg_gen_bswap_tl(dest, src1); >> + } else { >> + TCGv src2 = tcg_temp_new(); >> + tcg_gen_movi_tl(src2, shamt); >> + gen_helper_grev(dest, src1, src2); >> + tcg_temp_free(src2); >> + } >> + >> + gen_set_gpr(ctx, a->rd, dest); >> + return true; >> +} >> + >> +static void gen_pack(TCGv ret, TCGv src1, TCGv src2) >> +{ >> + tcg_gen_deposit_tl(ret, src1, src2, >> + TARGET_LONG_BITS / 2, >> + TARGET_LONG_BITS / 2); >> +} >> + >> +static void gen_packh(TCGv ret, TCGv src1, TCGv src2) >> +{ >> + TCGv t = tcg_temp_new(); >> + tcg_gen_ext8u_tl(t, src2); >> + tcg_gen_deposit_tl(ret, src1, t, 8, TARGET_LONG_BITS - 8); >> + tcg_temp_free(t); >> +} >> + >> +static void gen_packw(TCGv ret, TCGv src1, TCGv src2) >> +{ >> + TCGv t = tcg_temp_new(); >> + tcg_gen_ext16s_tl(t, src2); >> + tcg_gen_deposit_tl(ret, src1, t, 16, 48); >> + tcg_temp_free(t); >> +} >> + >> +static bool gen_shufi(DisasContext *ctx, arg_r2 *a, int shamt, >> + void(*func)(TCGv, TCGv, TCGv)) >> +{ >> + if (shamt >= TARGET_LONG_BITS / 2) { >> + return false; >> + } >> + >> + TCGv dest = dest_gpr(ctx, a->rd); >> + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); >> + TCGv src2 = tcg_temp_new(); >> + >> + tcg_gen_movi_tl(src2, shamt); >> + (*func)(dest, src1, src2); >> + >> + gen_set_gpr(ctx, a->rd, dest); >> + tcg_temp_free(src2); >> + return true; >> +} > > All of the gen functions belong in insn_trans/trans_rvb.c.inc. OK. I'll move them to insn_trans/trans_rvb.c.inc. > > > r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [RFC 2/6] target/riscv: rvk: add implementation of instructions for Zbk* - reuse partial instructions of Zbb/Zbc extensions - add brev8 packh, unzip, zip, etc. @ 2021-11-03 0:56 ` liweiwei 0 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-03 0:56 UTC (permalink / raw) To: Richard Henderson, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, lustrew, luruibo2000 Thanks for your suggestions. 在 2021/11/2 下午11:44, Richard Henderson 写道: > On 11/1/21 11:11 PM, liweiwei wrote: >> Signed-off-by: liweiwei <liweiwei@iscas.ac.cn> >> Signed-off-by: wangjunqiang <wangjunqiang@iscas.ac.cn> > > You managed to get the whole patch description into the subject line. > Please break it up. > OK. >> +target_ulong HELPER(grev)(target_ulong rs1, target_ulong rs2) >> +{ >> + return do_grev(rs1, rs2, TARGET_LONG_BITS); >> +} > > Are we expecting to see the full grev instruction at any point? If > not, we can certainly implement Zbk with a simpler implementation. The main idea that I add this helper is that grev may be added to B-extension later and it can be reused. However, it have no effect currently. I'll replace this with a simpler implementation. > >> +target_ulong HELPER(xperm)(target_ulong rs1, target_ulong rs2, >> uint32_t sz_log2) >> +{ >> + target_ulong r = 0; >> + target_ulong sz = 1LL << sz_log2; >> + target_ulong mask = (1LL << sz) - 1; >> + for (int i = 0; i < TARGET_LONG_BITS; i += sz) { >> + target_ulong pos = ((rs2 >> i) & mask) << sz_log2; >> + if (pos < sizeof(target_ulong) * 8) { >> + r |= ((rs1 >> pos) & mask) << i; >> + } >> + } >> + return r; >> +} > > This could become a static inline do_xperm, and provide two specific > xperm4 and xperm8 helpers; the compiler would fold all of the sz_log2 > stuff into a more efficient implementation. OK. > >> +target_ulong HELPER(unshfl)(target_ulong rs1, >> + target_ulong rs2) >> +{ >> + target_ulong x = rs1; >> + int i, shift; >> + int bits = TARGET_LONG_BITS >> 1; >> + for (i = 0, shift = 1; shift < bits; i++, shift <<= 1) { >> + if (rs2 & shift) { >> + x = do_shuf_stage(x, shuf_masks[i], shuf_masks[i] >> >> shift, shift); >> + } >> + } >> + return x; >> +} >> + >> +target_ulong HELPER(shfl)(target_ulong rs1, >> + target_ulong rs2) >> +{ >> + target_ulong x = rs1; >> + int i, shift; >> + shift = TARGET_LONG_BITS >> 2; >> + i = (shift == 8) ? 3 : 4; >> + for (; i >= 0; i--, shift >>= 1) { >> + if (rs2 & shift) { >> + x = do_shuf_stage(x, shuf_masks[i], shuf_masks[i] >> >> shift, shift); >> + } >> + } >> + return x; >> +} > > Similar comment as for grev. > >> +# The encoding for zext.h differs between RV32 and RV64. >> +# zext_h_32 denotes the RV32 variant. >> +{ >> + zext_h_32 0000100 00000 ..... 100 ..... 0110011 @r2 >> + pack 0000100 ..... ..... 100 ..... 0110011 @r >> +} > > Note to self: improve tcg_gen_deposit to notice zeros, so that the > more general pack compiles to zero-extension. > >> @@ -556,6 +563,81 @@ static bool gen_unary_per_ol(DisasContext *ctx, >> arg_r2 *a, DisasExtend ext, >> return gen_unary(ctx, a, ext, f_tl); >> } >> +static bool gen_xperm(DisasContext *ctx, arg_r *a, int32_t size) >> +{ >> + TCGv dest = dest_gpr(ctx, a->rd); >> + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); >> + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); >> + >> + TCGv_i32 sz = tcg_const_i32(size); >> + gen_helper_xperm(dest, src1, src2, sz); >> + >> + gen_set_gpr(ctx, a->rd, dest); >> + tcg_temp_free_i32(sz); >> + return true; >> +} >> + >> +static bool gen_grevi(DisasContext *ctx, arg_r2 *a, int shamt) >> +{ >> + TCGv dest = dest_gpr(ctx, a->rd); >> + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); >> + >> + if (shamt == (TARGET_LONG_BITS - 8)) { >> + /* rev8, byte swaps */ >> + tcg_gen_bswap_tl(dest, src1); >> + } else { >> + TCGv src2 = tcg_temp_new(); >> + tcg_gen_movi_tl(src2, shamt); >> + gen_helper_grev(dest, src1, src2); >> + tcg_temp_free(src2); >> + } >> + >> + gen_set_gpr(ctx, a->rd, dest); >> + return true; >> +} >> + >> +static void gen_pack(TCGv ret, TCGv src1, TCGv src2) >> +{ >> + tcg_gen_deposit_tl(ret, src1, src2, >> + TARGET_LONG_BITS / 2, >> + TARGET_LONG_BITS / 2); >> +} >> + >> +static void gen_packh(TCGv ret, TCGv src1, TCGv src2) >> +{ >> + TCGv t = tcg_temp_new(); >> + tcg_gen_ext8u_tl(t, src2); >> + tcg_gen_deposit_tl(ret, src1, t, 8, TARGET_LONG_BITS - 8); >> + tcg_temp_free(t); >> +} >> + >> +static void gen_packw(TCGv ret, TCGv src1, TCGv src2) >> +{ >> + TCGv t = tcg_temp_new(); >> + tcg_gen_ext16s_tl(t, src2); >> + tcg_gen_deposit_tl(ret, src1, t, 16, 48); >> + tcg_temp_free(t); >> +} >> + >> +static bool gen_shufi(DisasContext *ctx, arg_r2 *a, int shamt, >> + void(*func)(TCGv, TCGv, TCGv)) >> +{ >> + if (shamt >= TARGET_LONG_BITS / 2) { >> + return false; >> + } >> + >> + TCGv dest = dest_gpr(ctx, a->rd); >> + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); >> + TCGv src2 = tcg_temp_new(); >> + >> + tcg_gen_movi_tl(src2, shamt); >> + (*func)(dest, src1, src2); >> + >> + gen_set_gpr(ctx, a->rd, dest); >> + tcg_temp_free(src2); >> + return true; >> +} > > All of the gen functions belong in insn_trans/trans_rvb.c.inc. OK. I'll move them to insn_trans/trans_rvb.c.inc. > > > r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* [RFC 3/6] target/riscv: rvk: add flag support for Zk/Zkn/Zknd/Zknd/Zkne/Zknh/Zks/Zksed/Zksh/Zkr 2021-11-02 3:11 ` liweiwei @ 2021-11-02 3:11 ` liweiwei -1 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-02 3:11 UTC (permalink / raw) To: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, liweiwei, lazyparser, lustrew, luruibo2000 Signed-off-by: liweiwei <liweiwei@iscas.ac.cn> Signed-off-by: wangjunqiang <wangjunqiang@iscas.ac.cn> --- target/riscv/cpu.c | 36 ++++++++++++++++++++++++++++++++++++ target/riscv/cpu.h | 9 +++++++++ 2 files changed, 45 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 0f03d3efba..d7e026df36 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -491,6 +491,33 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) cpu->cfg.ext_d = true; } + if (cpu->cfg.ext_zk) { + cpu->cfg.ext_zbkb = true; + cpu->cfg.ext_zbkc = true; + cpu->cfg.ext_zbkx = true; + cpu->cfg.ext_zknd = true; + cpu->cfg.ext_zkne = true; + cpu->cfg.ext_zknh = true; + cpu->cfg.ext_zkr = true; + } + + if (cpu->cfg.ext_zkn) { + cpu->cfg.ext_zbkb = true; + cpu->cfg.ext_zbkc = true; + cpu->cfg.ext_zbkx = true; + cpu->cfg.ext_zknd = true; + cpu->cfg.ext_zkne = true; + cpu->cfg.ext_zknh = true; + } + + if (cpu->cfg.ext_zks) { + cpu->cfg.ext_zbkb = true; + cpu->cfg.ext_zbkc = true; + cpu->cfg.ext_zbkx = true; + cpu->cfg.ext_zksed = true; + cpu->cfg.ext_zksh = true; + } + /* Set the ISA extensions, checks should have happened above */ if (cpu->cfg.ext_i) { ext |= RVI; @@ -642,6 +669,15 @@ static Property riscv_cpu_properties[] = { DEFINE_PROP_BOOL("x-zbkb", RISCVCPU, cfg.ext_zbkb, false), DEFINE_PROP_BOOL("x-zbkc", RISCVCPU, cfg.ext_zbkc, false), DEFINE_PROP_BOOL("x-zbkx", RISCVCPU, cfg.ext_zbkx, false), + DEFINE_PROP_BOOL("x-zk", RISCVCPU, cfg.ext_zk, false), + DEFINE_PROP_BOOL("x-zkn", RISCVCPU, cfg.ext_zkn, false), + DEFINE_PROP_BOOL("x-zknd", RISCVCPU, cfg.ext_zknd, false), + DEFINE_PROP_BOOL("x-zkne", RISCVCPU, cfg.ext_zkne, false), + DEFINE_PROP_BOOL("x-zknh", RISCVCPU, cfg.ext_zknh, false), + DEFINE_PROP_BOOL("x-zks", RISCVCPU, cfg.ext_zks, false), + DEFINE_PROP_BOOL("x-zksed", RISCVCPU, cfg.ext_zksed, false), + DEFINE_PROP_BOOL("x-zksh", RISCVCPU, cfg.ext_zksh, false), + DEFINE_PROP_BOOL("x-zkr", RISCVCPU, cfg.ext_zkr, false), DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false), DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false), DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false), diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index f9f4437efc..de706a7d18 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -312,6 +312,15 @@ struct RISCVCPU { bool ext_zbkb; bool ext_zbkc; bool ext_zbkx; + bool ext_zk; + bool ext_zkn; + bool ext_zknd; + bool ext_zkne; + bool ext_zknh; + bool ext_zks; + bool ext_zksed; + bool ext_zksh; + bool ext_zkr; bool ext_counters; bool ext_ifencei; bool ext_icsr; -- 2.17.1 ^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC 3/6] target/riscv: rvk: add flag support for Zk/Zkn/Zknd/Zknd/Zkne/Zknh/Zks/Zksed/Zksh/Zkr @ 2021-11-02 3:11 ` liweiwei 0 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-02 3:11 UTC (permalink / raw) To: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: luruibo2000, lustrew, wangjunqiang, lazyparser, liweiwei Signed-off-by: liweiwei <liweiwei@iscas.ac.cn> Signed-off-by: wangjunqiang <wangjunqiang@iscas.ac.cn> --- target/riscv/cpu.c | 36 ++++++++++++++++++++++++++++++++++++ target/riscv/cpu.h | 9 +++++++++ 2 files changed, 45 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 0f03d3efba..d7e026df36 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -491,6 +491,33 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) cpu->cfg.ext_d = true; } + if (cpu->cfg.ext_zk) { + cpu->cfg.ext_zbkb = true; + cpu->cfg.ext_zbkc = true; + cpu->cfg.ext_zbkx = true; + cpu->cfg.ext_zknd = true; + cpu->cfg.ext_zkne = true; + cpu->cfg.ext_zknh = true; + cpu->cfg.ext_zkr = true; + } + + if (cpu->cfg.ext_zkn) { + cpu->cfg.ext_zbkb = true; + cpu->cfg.ext_zbkc = true; + cpu->cfg.ext_zbkx = true; + cpu->cfg.ext_zknd = true; + cpu->cfg.ext_zkne = true; + cpu->cfg.ext_zknh = true; + } + + if (cpu->cfg.ext_zks) { + cpu->cfg.ext_zbkb = true; + cpu->cfg.ext_zbkc = true; + cpu->cfg.ext_zbkx = true; + cpu->cfg.ext_zksed = true; + cpu->cfg.ext_zksh = true; + } + /* Set the ISA extensions, checks should have happened above */ if (cpu->cfg.ext_i) { ext |= RVI; @@ -642,6 +669,15 @@ static Property riscv_cpu_properties[] = { DEFINE_PROP_BOOL("x-zbkb", RISCVCPU, cfg.ext_zbkb, false), DEFINE_PROP_BOOL("x-zbkc", RISCVCPU, cfg.ext_zbkc, false), DEFINE_PROP_BOOL("x-zbkx", RISCVCPU, cfg.ext_zbkx, false), + DEFINE_PROP_BOOL("x-zk", RISCVCPU, cfg.ext_zk, false), + DEFINE_PROP_BOOL("x-zkn", RISCVCPU, cfg.ext_zkn, false), + DEFINE_PROP_BOOL("x-zknd", RISCVCPU, cfg.ext_zknd, false), + DEFINE_PROP_BOOL("x-zkne", RISCVCPU, cfg.ext_zkne, false), + DEFINE_PROP_BOOL("x-zknh", RISCVCPU, cfg.ext_zknh, false), + DEFINE_PROP_BOOL("x-zks", RISCVCPU, cfg.ext_zks, false), + DEFINE_PROP_BOOL("x-zksed", RISCVCPU, cfg.ext_zksed, false), + DEFINE_PROP_BOOL("x-zksh", RISCVCPU, cfg.ext_zksh, false), + DEFINE_PROP_BOOL("x-zkr", RISCVCPU, cfg.ext_zkr, false), DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false), DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false), DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false), diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index f9f4437efc..de706a7d18 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -312,6 +312,15 @@ struct RISCVCPU { bool ext_zbkb; bool ext_zbkc; bool ext_zbkx; + bool ext_zk; + bool ext_zkn; + bool ext_zknd; + bool ext_zkne; + bool ext_zknh; + bool ext_zks; + bool ext_zksed; + bool ext_zksh; + bool ext_zkr; bool ext_counters; bool ext_ifencei; bool ext_icsr; -- 2.17.1 ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [RFC 3/6] target/riscv: rvk: add flag support for Zk/Zkn/Zknd/Zknd/Zkne/Zknh/Zks/Zksed/Zksh/Zkr 2021-11-02 3:11 ` liweiwei @ 2021-11-02 17:56 ` Richard Henderson -1 siblings, 0 replies; 34+ messages in thread From: Richard Henderson @ 2021-11-02 17:56 UTC (permalink / raw) To: liweiwei, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, luruibo2000, lustrew On 11/1/21 11:11 PM, liweiwei wrote: > + if (cpu->cfg.ext_zk) { > + cpu->cfg.ext_zbkb = true; > + cpu->cfg.ext_zbkc = true; > + cpu->cfg.ext_zbkx = true; > + cpu->cfg.ext_zknd = true; > + cpu->cfg.ext_zkne = true; > + cpu->cfg.ext_zknh = true; > + cpu->cfg.ext_zkr = true; > + } Section 2.12 lists instead the larger Zkn, Zks, Zkt extensions. I think it's better to follow that. r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [RFC 3/6] target/riscv: rvk: add flag support for Zk/Zkn/Zknd/Zknd/Zkne/Zknh/Zks/Zksed/Zksh/Zkr @ 2021-11-02 17:56 ` Richard Henderson 0 siblings, 0 replies; 34+ messages in thread From: Richard Henderson @ 2021-11-02 17:56 UTC (permalink / raw) To: liweiwei, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, lustrew, luruibo2000 On 11/1/21 11:11 PM, liweiwei wrote: > + if (cpu->cfg.ext_zk) { > + cpu->cfg.ext_zbkb = true; > + cpu->cfg.ext_zbkc = true; > + cpu->cfg.ext_zbkx = true; > + cpu->cfg.ext_zknd = true; > + cpu->cfg.ext_zkne = true; > + cpu->cfg.ext_zknh = true; > + cpu->cfg.ext_zkr = true; > + } Section 2.12 lists instead the larger Zkn, Zks, Zkt extensions. I think it's better to follow that. r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [RFC 3/6] target/riscv: rvk: add flag support for Zk/Zkn/Zknd/Zknd/Zkne/Zknh/Zks/Zksed/Zksh/Zkr 2021-11-02 17:56 ` Richard Henderson @ 2021-11-03 1:06 ` liweiwei -1 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-03 1:06 UTC (permalink / raw) To: Richard Henderson, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, luruibo2000, lustrew 在 2021/11/3 上午1:56, Richard Henderson 写道: > On 11/1/21 11:11 PM, liweiwei wrote: >> + if (cpu->cfg.ext_zk) { >> + cpu->cfg.ext_zbkb = true; >> + cpu->cfg.ext_zbkc = true; >> + cpu->cfg.ext_zbkx = true; >> + cpu->cfg.ext_zknd = true; >> + cpu->cfg.ext_zkne = true; >> + cpu->cfg.ext_zknh = true; >> + cpu->cfg.ext_zkr = true; >> + } > > Section 2.12 lists instead the larger Zkn, Zks, Zkt extensions. > I think it's better to follow that. > OK. I'll replace this with setting ext_zkn, ext_zks, ext_zkt true. By the way, Zkt only includes partial RVI/M/C instructions. Is it neccessary to distinguish them? > > r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [RFC 3/6] target/riscv: rvk: add flag support for Zk/Zkn/Zknd/Zknd/Zkne/Zknh/Zks/Zksed/Zksh/Zkr @ 2021-11-03 1:06 ` liweiwei 0 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-03 1:06 UTC (permalink / raw) To: Richard Henderson, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, lustrew, luruibo2000 在 2021/11/3 上午1:56, Richard Henderson 写道: > On 11/1/21 11:11 PM, liweiwei wrote: >> + if (cpu->cfg.ext_zk) { >> + cpu->cfg.ext_zbkb = true; >> + cpu->cfg.ext_zbkc = true; >> + cpu->cfg.ext_zbkx = true; >> + cpu->cfg.ext_zknd = true; >> + cpu->cfg.ext_zkne = true; >> + cpu->cfg.ext_zknh = true; >> + cpu->cfg.ext_zkr = true; >> + } > > Section 2.12 lists instead the larger Zkn, Zks, Zkt extensions. > I think it's better to follow that. > OK. I'll replace this with setting ext_zkn, ext_zks, ext_zkt true. By the way, Zkt only includes partial RVI/M/C instructions. Is it neccessary to distinguish them? > > r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [RFC 3/6] target/riscv: rvk: add flag support for Zk/Zkn/Zknd/Zknd/Zkne/Zknh/Zks/Zksed/Zksh/Zkr 2021-11-03 1:06 ` liweiwei @ 2021-11-03 1:21 ` Richard Henderson -1 siblings, 0 replies; 34+ messages in thread From: Richard Henderson @ 2021-11-03 1:21 UTC (permalink / raw) To: liweiwei, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, luruibo2000, lustrew On 11/2/21 9:06 PM, liweiwei wrote: > > 在 2021/11/3 上午1:56, Richard Henderson 写道: >> On 11/1/21 11:11 PM, liweiwei wrote: >>> + if (cpu->cfg.ext_zk) { >>> + cpu->cfg.ext_zbkb = true; >>> + cpu->cfg.ext_zbkc = true; >>> + cpu->cfg.ext_zbkx = true; >>> + cpu->cfg.ext_zknd = true; >>> + cpu->cfg.ext_zkne = true; >>> + cpu->cfg.ext_zknh = true; >>> + cpu->cfg.ext_zkr = true; >>> + } >> >> Section 2.12 lists instead the larger Zkn, Zks, Zkt extensions. >> I think it's better to follow that. >> > OK. I'll replace this with setting ext_zkn, ext_zks, ext_zkt true. By the way, Zkt only > includes partial RVI/M/C instructions. Is it neccessary to distinguish them? I don't know if Zkt needs to be called out; it probably depends on whether it is exposed to the guest via some MISA csr extension. r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [RFC 3/6] target/riscv: rvk: add flag support for Zk/Zkn/Zknd/Zknd/Zkne/Zknh/Zks/Zksed/Zksh/Zkr @ 2021-11-03 1:21 ` Richard Henderson 0 siblings, 0 replies; 34+ messages in thread From: Richard Henderson @ 2021-11-03 1:21 UTC (permalink / raw) To: liweiwei, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, lustrew, luruibo2000 On 11/2/21 9:06 PM, liweiwei wrote: > > 在 2021/11/3 上午1:56, Richard Henderson 写道: >> On 11/1/21 11:11 PM, liweiwei wrote: >>> + if (cpu->cfg.ext_zk) { >>> + cpu->cfg.ext_zbkb = true; >>> + cpu->cfg.ext_zbkc = true; >>> + cpu->cfg.ext_zbkx = true; >>> + cpu->cfg.ext_zknd = true; >>> + cpu->cfg.ext_zkne = true; >>> + cpu->cfg.ext_zknh = true; >>> + cpu->cfg.ext_zkr = true; >>> + } >> >> Section 2.12 lists instead the larger Zkn, Zks, Zkt extensions. >> I think it's better to follow that. >> > OK. I'll replace this with setting ext_zkn, ext_zks, ext_zkt true. By the way, Zkt only > includes partial RVI/M/C instructions. Is it neccessary to distinguish them? I don't know if Zkt needs to be called out; it probably depends on whether it is exposed to the guest via some MISA csr extension. r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [RFC 3/6] target/riscv: rvk: add flag support for Zk/Zkn/Zknd/Zknd/Zkne/Zknh/Zks/Zksed/Zksh/Zkr 2021-11-03 1:21 ` Richard Henderson @ 2021-11-03 7:22 ` liweiwei -1 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-03 7:22 UTC (permalink / raw) To: Richard Henderson, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, luruibo2000, lustrew 在 2021/11/3 上午9:21, Richard Henderson 写道: > On 11/2/21 9:06 PM, liweiwei wrote: >> >> 在 2021/11/3 上午1:56, Richard Henderson 写道: >>> On 11/1/21 11:11 PM, liweiwei wrote: >>>> + if (cpu->cfg.ext_zk) { >>>> + cpu->cfg.ext_zbkb = true; >>>> + cpu->cfg.ext_zbkc = true; >>>> + cpu->cfg.ext_zbkx = true; >>>> + cpu->cfg.ext_zknd = true; >>>> + cpu->cfg.ext_zkne = true; >>>> + cpu->cfg.ext_zknh = true; >>>> + cpu->cfg.ext_zkr = true; >>>> + } >>> >>> Section 2.12 lists instead the larger Zkn, Zks, Zkt extensions. >>> I think it's better to follow that. >>> >> OK. I'll replace this with setting ext_zkn, ext_zks, ext_zkt true. By >> the way, Zkt only includes partial RVI/M/C instructions. Is it >> neccessary to distinguish them? > > I don't know if Zkt needs to be called out; it probably depends on > whether it is exposed to the guest via some MISA csr extension. It seems not exposed to the guest via some MISA csr extension. And it also doesn't define a set of instructions available in the core. It just restricts the set of instructions to have 'data-independent execution time'. > > > r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [RFC 3/6] target/riscv: rvk: add flag support for Zk/Zkn/Zknd/Zknd/Zkne/Zknh/Zks/Zksed/Zksh/Zkr @ 2021-11-03 7:22 ` liweiwei 0 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-03 7:22 UTC (permalink / raw) To: Richard Henderson, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, lustrew, luruibo2000 在 2021/11/3 上午9:21, Richard Henderson 写道: > On 11/2/21 9:06 PM, liweiwei wrote: >> >> 在 2021/11/3 上午1:56, Richard Henderson 写道: >>> On 11/1/21 11:11 PM, liweiwei wrote: >>>> + if (cpu->cfg.ext_zk) { >>>> + cpu->cfg.ext_zbkb = true; >>>> + cpu->cfg.ext_zbkc = true; >>>> + cpu->cfg.ext_zbkx = true; >>>> + cpu->cfg.ext_zknd = true; >>>> + cpu->cfg.ext_zkne = true; >>>> + cpu->cfg.ext_zknh = true; >>>> + cpu->cfg.ext_zkr = true; >>>> + } >>> >>> Section 2.12 lists instead the larger Zkn, Zks, Zkt extensions. >>> I think it's better to follow that. >>> >> OK. I'll replace this with setting ext_zkn, ext_zks, ext_zkt true. By >> the way, Zkt only includes partial RVI/M/C instructions. Is it >> neccessary to distinguish them? > > I don't know if Zkt needs to be called out; it probably depends on > whether it is exposed to the guest via some MISA csr extension. It seems not exposed to the guest via some MISA csr extension. And it also doesn't define a set of instructions available in the core. It just restricts the set of instructions to have 'data-independent execution time'. > > > r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* [RFC 4/6] target/riscv: rvk: add implementation of instructions for Zk* 2021-11-02 3:11 ` liweiwei @ 2021-11-02 3:11 ` liweiwei -1 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-02 3:11 UTC (permalink / raw) To: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, liweiwei, lazyparser, lustrew, luruibo2000 Signed-off-by: liweiwei <liweiwei@iscas.ac.cn> Signed-off-by: wangjunqiang <wangjunqiang@iscas.ac.cn> --- target/riscv/crypto_helper.c | 540 ++++++++++++++++++++++++ target/riscv/helper.h | 43 ++ target/riscv/insn32.decode | 42 ++ target/riscv/insn_trans/trans_rvk.c.inc | 467 ++++++++++++++++++++ target/riscv/meson.build | 1 + target/riscv/translate.c | 1 + 6 files changed, 1094 insertions(+) create mode 100644 target/riscv/crypto_helper.c create mode 100644 target/riscv/insn_trans/trans_rvk.c.inc diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c new file mode 100644 index 0000000000..0390d2ebc0 --- /dev/null +++ b/target/riscv/crypto_helper.c @@ -0,0 +1,540 @@ +/* + * RISC-V Crypto Emulation Helpers for QEMU. + * + * Copyright (c) 2021 Ruibo Lu, luruibo2000@163.com + * Copyright (c) 2021 Zewen Ye, lustrew@foxmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/exec-all.h" +#include "exec/helper-proto.h" + +uint8_t AES_ENC_SBOX[] = { + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, + 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, + 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, + 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, + 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, + 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, + 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, + 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, + 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, + 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, + 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, + 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, + 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, + 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, + 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, + 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, + 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 +}; + +uint8_t AES_DEC_SBOX[] = { + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, + 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, + 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, + 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, + 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, + 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, + 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, + 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, + 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, + 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, + 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, + 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, + 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, + 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, + 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, + 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D +}; + +/* SM4 forward SBox. SM4 has no inverse sbox. */ +static const uint8_t sm4_sbox[256] = { + 0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2, + 0x28, 0xFB, 0x2C, 0x05, 0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3, + 0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9C, 0x42, 0x50, 0xF4, + 0x91, 0xEF, 0x98, 0x7A, 0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62, + 0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95, 0x80, 0xDF, 0x94, 0xFA, + 0x75, 0x8F, 0x3F, 0xA6, 0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA, + 0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8, 0x68, 0x6B, 0x81, 0xB2, + 0x71, 0x64, 0xDA, 0x8B, 0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35, + 0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2, 0x25, 0x22, 0x7C, 0x3B, + 0x01, 0x21, 0x78, 0x87, 0xD4, 0x00, 0x46, 0x57, 0x9F, 0xD3, 0x27, 0x52, + 0x4C, 0x36, 0x02, 0xE7, 0xA0, 0xC4, 0xC8, 0x9E, 0xEA, 0xBF, 0x8A, 0xD2, + 0x40, 0xC7, 0x38, 0xB5, 0xA3, 0xF7, 0xF2, 0xCE, 0xF9, 0x61, 0x15, 0xA1, + 0xE0, 0xAE, 0x5D, 0xA4, 0x9B, 0x34, 0x1A, 0x55, 0xAD, 0x93, 0x32, 0x30, + 0xF5, 0x8C, 0xB1, 0xE3, 0x1D, 0xF6, 0xE2, 0x2E, 0x82, 0x66, 0xCA, 0x60, + 0xC0, 0x29, 0x23, 0xAB, 0x0D, 0x53, 0x4E, 0x6F, 0xD5, 0xDB, 0x37, 0x45, + 0xDE, 0xFD, 0x8E, 0x2F, 0x03, 0xFF, 0x6A, 0x72, 0x6D, 0x6C, 0x5B, 0x51, + 0x8D, 0x1B, 0xAF, 0x92, 0xBB, 0xDD, 0xBC, 0x7F, 0x11, 0xD9, 0x5C, 0x41, + 0x1F, 0x10, 0x5A, 0xD8, 0x0A, 0xC1, 0x31, 0x88, 0xA5, 0xCD, 0x7B, 0xBD, + 0x2D, 0x74, 0xD0, 0x12, 0xB8, 0xE5, 0xB4, 0xB0, 0x89, 0x69, 0x97, 0x4A, + 0x0C, 0x96, 0x77, 0x7E, 0x65, 0xB9, 0xF1, 0x09, 0xC5, 0x6E, 0xC6, 0x84, + 0x18, 0xF0, 0x7D, 0xEC, 0x3A, 0xDC, 0x4D, 0x20, 0x79, 0xEE, 0x5F, 0x3E, + 0xD7, 0xCB, 0x39, 0x48 +}; + +#define AES_XTIME(a) \ + ((a << 1) ^ ((a & 0x80) ? 0x1b : 0)) + +#define AES_GFMUL(a, b) (( \ + (((b) & 0x1) ? (a) : 0) ^ \ + (((b) & 0x2) ? AES_XTIME(a) : 0) ^ \ + (((b) & 0x4) ? AES_XTIME(AES_XTIME(a)) : 0) ^ \ + (((b) & 0x8) ? AES_XTIME(AES_XTIME(AES_XTIME(a))) : 0)) & 0xFF) + +#define BY(X, I) ((X >> (8 * I)) & 0xFF) + +#define AES_SHIFROWS_LO(RS1, RS2) ( \ + (((RS1 >> 24) & 0xFF) << 56) | \ + (((RS2 >> 48) & 0xFF) << 48) | \ + (((RS2 >> 8) & 0xFF) << 40) | \ + (((RS1 >> 32) & 0xFF) << 32) | \ + (((RS2 >> 56) & 0xFF) << 24) | \ + (((RS2 >> 16) & 0xFF) << 16) | \ + (((RS1 >> 40) & 0xFF) << 8) | \ + (((RS1 >> 0) & 0xFF) << 0)) + +#define AES_INVSHIFROWS_LO(RS1, RS2) ( \ + (((RS2 >> 24) & 0xFF) << 56) | \ + (((RS2 >> 48) & 0xFF) << 48) | \ + (((RS1 >> 8) & 0xFF) << 40) | \ + (((RS1 >> 32) & 0xFF) << 32) | \ + (((RS1 >> 56) & 0xFF) << 24) | \ + (((RS2 >> 16) & 0xFF) << 16) | \ + (((RS2 >> 40) & 0xFF) << 8) | \ + (((RS1 >> 0) & 0xFF) << 0)) + +#define AES_MIXBYTE(COL, B0, B1, B2, B3) ( \ + BY(COL, B3) ^ \ + BY(COL, B2) ^ \ + AES_GFMUL(BY(COL, B1), 3) ^ \ + AES_GFMUL(BY(COL, B0), 2) \ +) + +#define AES_MIXCOLUMN(COL) ( \ + AES_MIXBYTE(COL, 3, 0, 1, 2) << 24 | \ + AES_MIXBYTE(COL, 2, 3, 0, 1) << 16 | \ + AES_MIXBYTE(COL, 1, 2, 3, 0) << 8 | \ + AES_MIXBYTE(COL, 0, 1, 2, 3) << 0 \ +) + +#define AES_INVMIXBYTE(COL, B0, B1, B2, B3) ( \ + AES_GFMUL(BY(COL, B3), 0x9) ^ \ + AES_GFMUL(BY(COL, B2), 0xd) ^ \ + AES_GFMUL(BY(COL, B1), 0xb) ^ \ + AES_GFMUL(BY(COL, B0), 0xe) \ +) + +#define AES_INVMIXCOLUMN(COL) ( \ + AES_INVMIXBYTE(COL, 3, 0, 1, 2) << 24 | \ + AES_INVMIXBYTE(COL, 2, 3, 0, 1) << 16 | \ + AES_INVMIXBYTE(COL, 1, 2, 3, 0) << 8 | \ + AES_INVMIXBYTE(COL, 0, 1, 2, 3) << 0 \ +) + +static inline uint32_t aes_mixcolumn_byte(uint8_t x, bool fwd) +{ + uint32_t u; + if (fwd) { + u = (AES_GFMUL(x, 3) << 24) | + (x << 16) | + (x << 8) | + (AES_GFMUL(x, 2) << 0); + } else { + u = (AES_GFMUL(x, 0xb) << 24) | + (AES_GFMUL(x, 0xd) << 16) | + (AES_GFMUL(x, 0x9) << 8) | + (AES_GFMUL(x, 0xe) << 0); + } + return u; +} + +#define XLEN (8 * sizeof(target_ulong)) +#define zext32(x) ((uint64_t)(uint32_t)(x)) +#define sext_xlen(x) (((int64_t)(x) << (XLEN - 32)) >> (XLEN - 32)) + +static inline target_ulong aes32_operation(target_ulong bs, target_ulong rs1, + target_ulong rs2, bool enc, + bool mix) +{ + uint8_t shamt = bs << 3; + uint8_t si = rs2 >> shamt; + uint8_t so; + uint32_t mixed; + if (enc) { + so = AES_ENC_SBOX[si]; + if (mix) { + mixed = aes_mixcolumn_byte(so, true); + } else { + mixed = so; + } + + } else { + so = AES_DEC_SBOX[si]; + if (mix) { + mixed = aes_mixcolumn_byte(so, false); + } else { + mixed = so; + } + } + mixed = (mixed << shamt) | (mixed >> (32 - shamt)); + target_ulong res = rs1 ^ mixed; + return sext_xlen(res); +} + +target_ulong HELPER(aes32esmi)(target_ulong rs1, target_ulong rs2, + target_ulong bs) +{ + return aes32_operation(bs, rs1, rs2, true, true); +} + +target_ulong HELPER(aes32esi)(target_ulong rs1, target_ulong rs2, + target_ulong bs) +{ + return aes32_operation(bs, rs1, rs2, true, false); +} + +target_ulong HELPER(aes32dsmi)(target_ulong rs1, target_ulong rs2, + target_ulong bs) +{ + return aes32_operation(bs, rs1, rs2, false, true); +} + +target_ulong HELPER(aes32dsi)(target_ulong rs1, target_ulong rs2, + target_ulong bs) +{ + return aes32_operation(bs, rs1, rs2, false, false); +} + +static inline target_ulong aes64_operation(target_ulong rs1, target_ulong rs2, + bool enc, bool mix) +{ + uint64_t RS1 = rs1; + uint64_t RS2 = rs2; + uint64_t result; + uint64_t temp; + uint32_t col_0; + uint32_t col_1; + if (enc) { + temp = AES_SHIFROWS_LO(RS1, RS2); + temp = ( + ((uint64_t)AES_ENC_SBOX[(temp >> 0) & 0xFF] << 0) | + ((uint64_t)AES_ENC_SBOX[(temp >> 8) & 0xFF] << 8) | + ((uint64_t)AES_ENC_SBOX[(temp >> 16) & 0xFF] << 16) | + ((uint64_t)AES_ENC_SBOX[(temp >> 24) & 0xFF] << 24) | + ((uint64_t)AES_ENC_SBOX[(temp >> 32) & 0xFF] << 32) | + ((uint64_t)AES_ENC_SBOX[(temp >> 40) & 0xFF] << 40) | + ((uint64_t)AES_ENC_SBOX[(temp >> 48) & 0xFF] << 48) | + ((uint64_t)AES_ENC_SBOX[(temp >> 56) & 0xFF] << 56) + ); + if (mix) { + col_0 = temp & 0xFFFFFFFF; + col_1 = temp >> 32 ; + + col_0 = AES_MIXCOLUMN(col_0); + col_1 = AES_MIXCOLUMN(col_1); + + result = ((uint64_t)col_1 << 32) | col_0; + } else { + result = temp; + } + } else { + temp = AES_INVSHIFROWS_LO(RS1, RS2); + temp = ( + ((uint64_t)AES_DEC_SBOX[(temp >> 0) & 0xFF] << 0) | + ((uint64_t)AES_DEC_SBOX[(temp >> 8) & 0xFF] << 8) | + ((uint64_t)AES_DEC_SBOX[(temp >> 16) & 0xFF] << 16) | + ((uint64_t)AES_DEC_SBOX[(temp >> 24) & 0xFF] << 24) | + ((uint64_t)AES_DEC_SBOX[(temp >> 32) & 0xFF] << 32) | + ((uint64_t)AES_DEC_SBOX[(temp >> 40) & 0xFF] << 40) | + ((uint64_t)AES_DEC_SBOX[(temp >> 48) & 0xFF] << 48) | + ((uint64_t)AES_DEC_SBOX[(temp >> 56) & 0xFF] << 56) + ); + if (mix) { + col_0 = temp & 0xFFFFFFFF; + col_1 = temp >> 32 ; + + col_0 = AES_INVMIXCOLUMN(col_0); + col_1 = AES_INVMIXCOLUMN(col_1); + + result = ((uint64_t)col_1 << 32) | col_0; + } else { + result = temp; + } + } + return result; +} + +target_ulong HELPER(aes64esm)(target_ulong rs1, target_ulong rs2) +{ + return aes64_operation(rs1, rs2, true, true); +} + +target_ulong HELPER(aes64es)(target_ulong rs1, target_ulong rs2) +{ + return aes64_operation(rs1, rs2, true, false); +} + +target_ulong HELPER(aes64ds)(target_ulong rs1, target_ulong rs2) +{ + return aes64_operation(rs1, rs2, false, false); +} + +target_ulong HELPER(aes64dsm)(target_ulong rs1, target_ulong rs2) +{ + return aes64_operation(rs1, rs2, false, true); +} + +target_ulong HELPER(aes64ks2)(target_ulong rs1, target_ulong rs2) +{ + uint64_t RS1 = rs1; + uint64_t RS2 = rs2; + uint32_t rs1_hi = RS1 >> 32; + uint32_t rs2_lo = RS2 ; + uint32_t rs2_hi = RS2 >> 32; + + uint32_t r_lo = (rs1_hi ^ rs2_lo) ; + uint32_t r_hi = (rs1_hi ^ rs2_lo ^ rs2_hi) ; + target_ulong result = ((uint64_t)r_hi << 32) | r_lo ; + return result; +} + +target_ulong HELPER(aes64ks1i)(target_ulong rs1, target_ulong rnum) +{ + uint64_t RS1 = rs1; + uint8_t round_consts[10] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 + }; + + uint8_t enc_rnum = rnum; + uint32_t temp = (RS1 >> 32) & 0xFFFFFFFF; + uint8_t rcon_ = 0; + target_ulong result; + + if (enc_rnum != 0xA) { + temp = (temp >> 8) | (temp << 24); /* Rotate right by 8 */ + rcon_ = round_consts[enc_rnum]; + } + + temp = + ((uint32_t)AES_ENC_SBOX[(temp >> 24) & 0xFF] << 24) | + ((uint32_t)AES_ENC_SBOX[(temp >> 16) & 0xFF] << 16) | + ((uint32_t)AES_ENC_SBOX[(temp >> 8) & 0xFF] << 8) | + ((uint32_t)AES_ENC_SBOX[(temp >> 0) & 0xFF] << 0) ; + + temp ^= rcon_; + + result = ((uint64_t)temp << 32) | temp; + return result; +} + +target_ulong HELPER(aes64im)(target_ulong rs1) +{ + uint64_t RS1 = rs1; + uint32_t col_0 = RS1 & 0xFFFFFFFF; + uint32_t col_1 = RS1 >> 32 ; + + col_0 = AES_INVMIXCOLUMN(col_0); + col_1 = AES_INVMIXCOLUMN(col_1); + + target_ulong result = ((uint64_t)col_1 << 32) | col_0; + return result; +} + +#define ROR32(a, amt) ((a << (-amt & 31)) | (a >> (amt & 31))) +target_ulong HELPER(sha256sig0)(target_ulong rs1) +{ + uint32_t a = rs1; + return sext_xlen(ROR32(a, 7) ^ ROR32(a, 18) ^ (a >> 3)); +} + +target_ulong HELPER(sha256sig1)(target_ulong rs1) +{ + uint32_t a = rs1; + return sext_xlen(ROR32(a, 17) ^ ROR32(a, 19) ^ (a >> 10)); +} + +target_ulong HELPER(sha256sum0)(target_ulong rs1) +{ + uint32_t a = rs1; + return sext_xlen(ROR32(a, 2) ^ ROR32(a, 13) ^ ROR32(a, 22)); +} + +target_ulong HELPER(sha256sum1)(target_ulong rs1) +{ + uint32_t a = rs1; + return sext_xlen(ROR32(a, 6) ^ ROR32(a, 11) ^ ROR32(a, 25)); +} +#undef ROR32 + +target_ulong HELPER(sha512sum0r)(target_ulong RS1, target_ulong RS2) +{ + uint64_t result = + (zext32(RS1) << 25) ^ (zext32(RS1) << 30) ^ (zext32(RS1) >> 28) ^ + (zext32(RS2) >> 7) ^ (zext32(RS2) >> 2) ^ (zext32(RS2) << 4); + return sext_xlen(result); +} + +target_ulong HELPER(sha512sum1r)(target_ulong RS1, target_ulong RS2) +{ + uint64_t result = + (zext32(RS1) << 23) ^ (zext32(RS1) >> 14) ^ (zext32(RS1) >> 18) ^ + (zext32(RS2) >> 9) ^ (zext32(RS2) << 18) ^ (zext32(RS2) << 14); + return sext_xlen(result); +} + +target_ulong HELPER(sha512sig0l)(target_ulong RS1, target_ulong RS2) +{ + uint64_t result = + (zext32(RS1) >> 1) ^ (zext32(RS1) >> 7) ^ (zext32(RS1) >> 8) ^ + (zext32(RS2) << 31) ^ (zext32(RS2) << 25) ^ (zext32(RS2) << 24); + return sext_xlen(result); +} + +target_ulong HELPER(sha512sig0h)(target_ulong RS1, target_ulong RS2) +{ + uint64_t result = + (zext32(RS1) >> 1) ^ (zext32(RS1) >> 7) ^ (zext32(RS1) >> 8) ^ + (zext32(RS2) << 31) ^ (zext32(RS2) << 24); + return sext_xlen(result); +} + +target_ulong HELPER(sha512sig1l)(target_ulong RS1, target_ulong RS2) +{ + uint64_t result = + (zext32(RS1) << 3) ^ (zext32(RS1) >> 6) ^ (zext32(RS1) >> 19) ^ + (zext32(RS2) >> 29) ^ (zext32(RS2) << 26) ^ (zext32(RS2) << 13); + return sext_xlen(result); +} + +target_ulong HELPER(sha512sig1h)(target_ulong RS1, target_ulong RS2) +{ + uint64_t result = + (zext32(RS1) << 3) ^ (zext32(RS1) >> 6) ^ (zext32(RS1) >> 19) ^ + (zext32(RS2) >> 29) ^ (zext32(RS2) << 13); + return sext_xlen(result); +} + +#define ROR64(a, amt) ((a << (-amt & 63)) | (a >> (amt & 63))) +target_ulong HELPER(sha512sig0)(target_ulong rs1) +{ + uint64_t a = rs1; + return ROR64(a, 1) ^ ROR64(a, 8) ^ (a >> 7); +} + +target_ulong HELPER(sha512sig1)(target_ulong rs1) +{ + uint64_t a = rs1; + return ROR64(a, 19) ^ ROR64(a, 61) ^ (a >> 6); +} + +target_ulong HELPER(sha512sum0)(target_ulong rs1) +{ + uint64_t a = rs1; + return ROR64(a, 28) ^ ROR64(a, 34) ^ ROR64(a, 39); +} + +target_ulong HELPER(sha512sum1)(target_ulong rs1) +{ + uint64_t a = rs1; + return ROR64(a, 14) ^ ROR64(a, 18) ^ ROR64(a, 41); +} +#undef ROR64 + +#define ROL32(a, amt) ((a >> (-amt & 31)) | (a << (amt & 31))) +target_ulong HELPER(sm3p0)(target_ulong rs1) +{ + uint32_t src = rs1; + uint32_t result = src ^ ROL32(src, 9) ^ ROL32(src, 17); + return sext_xlen(result); +} +target_ulong HELPER(sm3p1)(target_ulong rs1) +{ + uint32_t src = rs1; + uint32_t result = src ^ ROL32(src, 15) ^ ROL32(src, 23); + return sext_xlen(result); +} +#undef ROL32 + + +target_ulong HELPER(sm4ed)(target_ulong rs2, target_ulong rt, target_ulong bs) +{ + uint8_t bs_t = bs; + + uint32_t sb_in = (uint8_t)(rs2 >> (8 * bs_t)); + uint32_t sb_out = (uint32_t)sm4_sbox[sb_in]; + + uint32_t linear = sb_out ^ (sb_out << 8) ^ + (sb_out << 2) ^ + (sb_out << 18) ^ + ((sb_out & 0x3f) << 26) ^ + ((sb_out & 0xC0) << 10) ; + + uint32_t rotl = (linear << (8 * bs_t)) | (linear >> (32 - 8 * bs_t)); + + return sext_xlen(rotl ^ (uint32_t)rt); +} + +target_ulong HELPER(sm4ks)(target_ulong rs2, target_ulong rs1, target_ulong bs) +{ + uint8_t bs_t = bs; + + uint32_t sb_in = (uint8_t)(rs2 >> (8 * bs_t)); + uint32_t sb_out = sm4_sbox[sb_in]; + + uint32_t x = sb_out ^ + ((sb_out & 0x07) << 29) ^ ((sb_out & 0xFE) << 7) ^ + ((sb_out & 0x01) << 23) ^ ((sb_out & 0xF8) << 13) ; + + uint32_t rotl = (x << (8 * bs_t)) | (x >> (32 - 8 * bs_t)); + + return sext_xlen(rotl ^ (uint32_t)rs1); +} +#undef XLEN +#undef zext32 +#undef sext_xlen diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 216aa4193b..444505be8e 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1151,3 +1151,46 @@ DEF_HELPER_6(vcompress_vm_b, void, ptr, ptr, ptr, ptr, env, i32) DEF_HELPER_6(vcompress_vm_h, void, ptr, ptr, ptr, ptr, env, i32) DEF_HELPER_6(vcompress_vm_w, void, ptr, ptr, ptr, ptr, env, i32) DEF_HELPER_6(vcompress_vm_d, void, ptr, ptr, ptr, ptr, env, i32) + +/* Crypto Extension - aes 32 */ +DEF_HELPER_3(aes32esmi, tl, tl, tl, tl) +DEF_HELPER_3(aes32esi, tl, tl, tl, tl) +DEF_HELPER_3(aes32dsmi, tl, tl, tl, tl) +DEF_HELPER_3(aes32dsi, tl, tl, tl, tl) + +/* Crypto Extension - aes 64 */ +DEF_HELPER_2(aes64esm, tl, tl, tl) +DEF_HELPER_2(aes64es, tl, tl, tl) +DEF_HELPER_2(aes64ds, tl, tl, tl) +DEF_HELPER_2(aes64dsm, tl, tl, tl) +DEF_HELPER_2(aes64ks2, tl, tl, tl) +DEF_HELPER_2(aes64ks1i, tl, tl, tl) +DEF_HELPER_1(aes64im, tl, tl) + +/* Crypto Extension - sha256 */ +DEF_HELPER_1(sha256sig0, tl, tl) +DEF_HELPER_1(sha256sig1, tl, tl) +DEF_HELPER_1(sha256sum0, tl, tl) +DEF_HELPER_1(sha256sum1, tl, tl) + +/* Crypto Extension - sha512 */ +DEF_HELPER_2(sha512sum0r, tl, tl, tl) +DEF_HELPER_2(sha512sum1r, tl, tl, tl) +DEF_HELPER_2(sha512sig0l, tl, tl, tl) +DEF_HELPER_2(sha512sig0h, tl, tl, tl) +DEF_HELPER_2(sha512sig1l, tl, tl, tl) +DEF_HELPER_2(sha512sig1h, tl, tl, tl) + +/* Crypto Extension - sha512 */ +DEF_HELPER_1(sha512sig0, tl, tl) +DEF_HELPER_1(sha512sig1, tl, tl) +DEF_HELPER_1(sha512sum0, tl, tl) +DEF_HELPER_1(sha512sum1, tl, tl) + +/* Crypto Extension - sm3 */ +DEF_HELPER_1(sm3p0, tl, tl) +DEF_HELPER_1(sm3p1, tl, tl) + +/* Crypto Extension - sm4 */ +DEF_HELPER_3(sm4ed, tl, tl, tl, tl) +DEF_HELPER_3(sm4ks, tl, tl, tl, tl) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index a5333c4533..69e940457e 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -17,8 +17,10 @@ # this program. If not, see <http://www.gnu.org/licenses/>. # Fields: +%bs 30:2 %rs3 27:5 %rs2 20:5 +%rnum 20:4 %rs1 15:5 %rd 7:5 %sh5 20:5 @@ -91,6 +93,7 @@ # Formats 64: @sh5 ....... ..... ..... ... ..... ....... &shift shamt=%sh5 %rs1 %rd +@k_aes .. ..... ..... ..... ... ..... ....... %bs %rs2 %rs1 %rd # *** Privileged Instructions *** ecall 000000000000 00000 000 00000 1110011 @@ -744,3 +747,42 @@ binv 0110100 .......... 001 ..... 0110011 @r binvi 01101. ........... 001 ..... 0010011 @sh bset 0010100 .......... 001 ..... 0110011 @r bseti 00101. ........... 001 ..... 0010011 @sh + +# *** RV32 Zkne Standard Extension *** +aes32esmi .. 10011 ..... ..... 000 ..... 0110011 @k_aes +aes32esi .. 10001 ..... ..... 000 ..... 0110011 @k_aes +# *** RV64 Zkne Standard Extension *** +aes64es 00 11001 ..... ..... 000 ..... 0110011 @r +aes64esm 00 11011 ..... ..... 000 ..... 0110011 @r +# *** RV32 Zknd Standard Extension *** +aes32dsmi .. 10111 ..... ..... 000 ..... 0110011 @k_aes +aes32dsi .. 10101 ..... ..... 000 ..... 0110011 @k_aes +# *** RV64 Zknd Standard Extension *** +aes64dsm 00 11111 ..... ..... 000 ..... 0110011 @r +aes64ds 00 11101 ..... ..... 000 ..... 0110011 @r +aes64im 00 11000 00000 ..... 001 ..... 0010011 @r2 +# *** RV64 Zkne/zknd Standard Extension *** +aes64ks2 01 11111 ..... ..... 000 ..... 0110011 @r +aes64ks1i 00 11000 1.... ..... 001 ..... 0010011 %rnum %rs1 %rd +# *** RV32 Zknh Standard Extension *** +sha256sig0 00 01000 00010 ..... 001 ..... 0010011 @r2 +sha256sig1 00 01000 00011 ..... 001 ..... 0010011 @r2 +sha256sum0 00 01000 00000 ..... 001 ..... 0010011 @r2 +sha256sum1 00 01000 00001 ..... 001 ..... 0010011 @r2 +sha512sum0r 01 01000 ..... ..... 000 ..... 0110011 @r +sha512sum1r 01 01001 ..... ..... 000 ..... 0110011 @r +sha512sig0l 01 01010 ..... ..... 000 ..... 0110011 @r +sha512sig0h 01 01110 ..... ..... 000 ..... 0110011 @r +sha512sig1l 01 01011 ..... ..... 000 ..... 0110011 @r +sha512sig1h 01 01111 ..... ..... 000 ..... 0110011 @r +# *** RV64 Zknh Standard Extension *** +sha512sig0 00 01000 00110 ..... 001 ..... 0010011 @r2 +sha512sig1 00 01000 00111 ..... 001 ..... 0010011 @r2 +sha512sum0 00 01000 00100 ..... 001 ..... 0010011 @r2 +sha512sum1 00 01000 00101 ..... 001 ..... 0010011 @r2 +# *** RV32 Zksh Standard Extension *** +sm3p0 00 01000 01000 ..... 001 ..... 0010011 @r2 +sm3p1 00 01000 01001 ..... 001 ..... 0010011 @r2 +# *** RV32 Zksed Standard Extension *** +sm4ed .. 11000 ..... ..... 000 ..... 0110011 @k_aes +sm4ks .. 11010 ..... ..... 000 ..... 0110011 @k_aes diff --git a/target/riscv/insn_trans/trans_rvk.c.inc b/target/riscv/insn_trans/trans_rvk.c.inc new file mode 100644 index 0000000000..da8dea69b8 --- /dev/null +++ b/target/riscv/insn_trans/trans_rvk.c.inc @@ -0,0 +1,467 @@ +/* + * RISC-V translation routines for the Zk[nd,ne,nh,sed,sh] Standard Extension. + * + * Copyright (c) 2021 Ruibo Lu, luruibo2000@163.com + * Copyright (c) 2021 Zewen Ye, lustrew@foxmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#define REQUIRE_ZKND(ctx) do { \ + if (!RISCV_CPU(ctx->cs)->cfg.ext_zknd) { \ + return false; \ + } \ +} while (0) + +#define REQUIRE_ZKNE(ctx) do { \ + if (!RISCV_CPU(ctx->cs)->cfg.ext_zkne) { \ + return false; \ + } \ +} while (0) + +#define REQUIRE_ZKNH(ctx) do { \ + if (!RISCV_CPU(ctx->cs)->cfg.ext_zknh) { \ + return false; \ + } \ +} while (0) + +#define REQUIRE_ZKSED(ctx) do { \ + if (!RISCV_CPU(ctx->cs)->cfg.ext_zksed) { \ + return false; \ + } \ +} while (0) + +#define REQUIRE_ZKSH(ctx) do { \ + if (!RISCV_CPU(ctx->cs)->cfg.ext_zksh) { \ + return false; \ + } \ +} while (0) + +static bool trans_aes32esmi(DisasContext *ctx, arg_aes32esmi *a) +{ + REQUIRE_ZKNE(ctx); + + TCGv bs = tcg_const_tl(a->bs); + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_aes32esmi(dest, src1, src2, bs); + gen_set_gpr(ctx, a->rd, dest); + + tcg_temp_free(bs); + return true; +} + +static bool trans_aes64esm(DisasContext *ctx, arg_aes64esm *a) +{ + REQUIRE_ZKNE(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_aes64esm(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_aes32esi(DisasContext *ctx, arg_aes32esi *a) +{ + REQUIRE_ZKNE(ctx); + + TCGv bs = tcg_const_tl(a->bs); + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_aes32esi(dest, src1, src2, bs); + gen_set_gpr(ctx, a->rd, dest); + + tcg_temp_free(bs); + return true; +} + +static bool trans_aes64es(DisasContext *ctx, arg_aes64es *a) +{ + REQUIRE_ZKNE(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_aes64es(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_aes32dsmi(DisasContext *ctx, arg_aes32dsmi *a) +{ + REQUIRE_ZKND(ctx); + + TCGv bs = tcg_const_tl(a->bs); + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_aes32dsmi(dest, src1, src2, bs); + gen_set_gpr(ctx, a->rd, dest); + + tcg_temp_free(bs); + return true; +} + +static bool trans_aes64dsm(DisasContext *ctx, arg_aes64dsm *a) +{ + REQUIRE_ZKND(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_aes64dsm(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_aes64ks2(DisasContext *ctx, arg_aes64ks2 *a) +{ + REQUIRE_EITHER_EXT(ctx, zknd, zkne); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_aes64ks2(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + + tcg_temp_free(dest); + tcg_temp_free(src1); + tcg_temp_free(src2); + + return true; +} + +static bool trans_aes32dsi(DisasContext *ctx, arg_aes32dsi *a) +{ + REQUIRE_ZKND(ctx); + + TCGv bs = tcg_const_tl(a->bs); + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_aes32dsi(dest, src1, src2, bs); + gen_set_gpr(ctx, a->rd, dest); + + tcg_temp_free(bs); + return true; +} + +static bool trans_aes64ds(DisasContext *ctx, arg_aes64ds *a) +{ + REQUIRE_ZKND(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_aes64ds(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_aes64ks1i(DisasContext *ctx, arg_aes64ks1i *a) +{ + REQUIRE_EITHER_EXT(ctx, zknd, zkne); + + if (a->rnum > 0xA) { + return false; + } + + TCGv rnum; + rnum = tcg_const_tl(a->rnum); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_aes64ks1i(dest, src1, rnum); + gen_set_gpr(ctx, a->rd, dest); + + tcg_temp_free(rnum); + return true; +} + +static bool trans_aes64im(DisasContext *ctx, arg_aes64im *a) +{ + REQUIRE_ZKND(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_aes64im(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_sha256sig0(DisasContext *ctx, arg_sha256sig0 *a) +{ + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sha256sig0(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_sha256sig1(DisasContext *ctx, arg_sha256sig1 *a) +{ + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sha256sig1(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_sha256sum0(DisasContext *ctx, arg_sha256sum0 *a) +{ + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sha256sum0(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_sha256sum1(DisasContext *ctx, arg_sha256sum1 *a) +{ + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sha256sum1(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_sha512sum0r(DisasContext *ctx, arg_sha512sum0r *a) +{ + REQUIRE_32BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_sha512sum0r(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_sha512sum1r(DisasContext *ctx, arg_sha512sum1r *a) +{ + REQUIRE_32BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_sha512sum1r(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_sha512sig0l(DisasContext *ctx, arg_sha512sig0l *a) +{ + REQUIRE_32BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_sha512sig0l(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_sha512sig0h(DisasContext *ctx, arg_sha512sig0h *a) +{ + REQUIRE_32BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_sha512sig0h(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_sha512sig1l(DisasContext *ctx, arg_sha512sig1l *a) +{ + REQUIRE_32BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_sha512sig1l(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_sha512sig1h(DisasContext *ctx, arg_sha512sig1h *a) +{ + REQUIRE_32BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_sha512sig1h(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_sha512sig0(DisasContext *ctx, arg_sha512sig0 *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sha512sig0(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_sha512sig1(DisasContext *ctx, arg_sha512sig1 *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sha512sig1(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_sha512sum0(DisasContext *ctx, arg_sha512sum0 *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sha512sum0(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_sha512sum1(DisasContext *ctx, arg_sha512sum1 *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sha512sum1(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +/* SM3 */ +static bool trans_sm3p0(DisasContext *ctx, arg_sm3p0 *a) +{ + REQUIRE_ZKSH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sm3p0(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_sm3p1(DisasContext *ctx, arg_sm3p1 *a) +{ + REQUIRE_ZKSH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sm3p1(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +/* SM4 */ +static bool trans_sm4ed(DisasContext *ctx, arg_sm4ed *a) +{ + REQUIRE_ZKSED(ctx); + + TCGv bs = tcg_const_tl(a->bs); + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_sm4ed(dest, src2, src1, bs); + gen_set_gpr(ctx, a->rd, dest); + + tcg_temp_free(bs); + return true; +} + +static bool trans_sm4ks(DisasContext *ctx, arg_sm4ks *a) +{ + REQUIRE_ZKSED(ctx); + + TCGv bs = tcg_const_tl(a->bs); + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_sm4ks(dest, src2, src1, bs); + gen_set_gpr(ctx, a->rd, dest); + + tcg_temp_free(bs); + return true; +} diff --git a/target/riscv/meson.build b/target/riscv/meson.build index d5e0bc93ea..4fc385c2fb 100644 --- a/target/riscv/meson.build +++ b/target/riscv/meson.build @@ -18,6 +18,7 @@ riscv_ss.add(files( 'vector_helper.c', 'bitmanip_helper.c', 'translate.c', + 'crypto_helper.c', )) riscv_softmmu_ss = ss.source_set() diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 5b868cd53f..735fae047a 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -656,6 +656,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc) #include "insn_trans/trans_rvh.c.inc" #include "insn_trans/trans_rvv.c.inc" #include "insn_trans/trans_rvb.c.inc" +#include "insn_trans/trans_rvk.c.inc" #include "insn_trans/trans_privileged.c.inc" /* Include the auto-generated decoder for 16 bit insn */ -- 2.17.1 ^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC 4/6] target/riscv: rvk: add implementation of instructions for Zk* @ 2021-11-02 3:11 ` liweiwei 0 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-02 3:11 UTC (permalink / raw) To: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: luruibo2000, lustrew, wangjunqiang, lazyparser, liweiwei Signed-off-by: liweiwei <liweiwei@iscas.ac.cn> Signed-off-by: wangjunqiang <wangjunqiang@iscas.ac.cn> --- target/riscv/crypto_helper.c | 540 ++++++++++++++++++++++++ target/riscv/helper.h | 43 ++ target/riscv/insn32.decode | 42 ++ target/riscv/insn_trans/trans_rvk.c.inc | 467 ++++++++++++++++++++ target/riscv/meson.build | 1 + target/riscv/translate.c | 1 + 6 files changed, 1094 insertions(+) create mode 100644 target/riscv/crypto_helper.c create mode 100644 target/riscv/insn_trans/trans_rvk.c.inc diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c new file mode 100644 index 0000000000..0390d2ebc0 --- /dev/null +++ b/target/riscv/crypto_helper.c @@ -0,0 +1,540 @@ +/* + * RISC-V Crypto Emulation Helpers for QEMU. + * + * Copyright (c) 2021 Ruibo Lu, luruibo2000@163.com + * Copyright (c) 2021 Zewen Ye, lustrew@foxmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/exec-all.h" +#include "exec/helper-proto.h" + +uint8_t AES_ENC_SBOX[] = { + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, + 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, + 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, + 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, + 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, + 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, + 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, + 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, + 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, + 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, + 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, + 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, + 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, + 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, + 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, + 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, + 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 +}; + +uint8_t AES_DEC_SBOX[] = { + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, + 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, + 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, + 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, + 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, + 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, + 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, + 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, + 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, + 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, + 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, + 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, + 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, + 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, + 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, + 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D +}; + +/* SM4 forward SBox. SM4 has no inverse sbox. */ +static const uint8_t sm4_sbox[256] = { + 0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2, + 0x28, 0xFB, 0x2C, 0x05, 0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3, + 0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9C, 0x42, 0x50, 0xF4, + 0x91, 0xEF, 0x98, 0x7A, 0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62, + 0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95, 0x80, 0xDF, 0x94, 0xFA, + 0x75, 0x8F, 0x3F, 0xA6, 0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA, + 0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8, 0x68, 0x6B, 0x81, 0xB2, + 0x71, 0x64, 0xDA, 0x8B, 0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35, + 0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2, 0x25, 0x22, 0x7C, 0x3B, + 0x01, 0x21, 0x78, 0x87, 0xD4, 0x00, 0x46, 0x57, 0x9F, 0xD3, 0x27, 0x52, + 0x4C, 0x36, 0x02, 0xE7, 0xA0, 0xC4, 0xC8, 0x9E, 0xEA, 0xBF, 0x8A, 0xD2, + 0x40, 0xC7, 0x38, 0xB5, 0xA3, 0xF7, 0xF2, 0xCE, 0xF9, 0x61, 0x15, 0xA1, + 0xE0, 0xAE, 0x5D, 0xA4, 0x9B, 0x34, 0x1A, 0x55, 0xAD, 0x93, 0x32, 0x30, + 0xF5, 0x8C, 0xB1, 0xE3, 0x1D, 0xF6, 0xE2, 0x2E, 0x82, 0x66, 0xCA, 0x60, + 0xC0, 0x29, 0x23, 0xAB, 0x0D, 0x53, 0x4E, 0x6F, 0xD5, 0xDB, 0x37, 0x45, + 0xDE, 0xFD, 0x8E, 0x2F, 0x03, 0xFF, 0x6A, 0x72, 0x6D, 0x6C, 0x5B, 0x51, + 0x8D, 0x1B, 0xAF, 0x92, 0xBB, 0xDD, 0xBC, 0x7F, 0x11, 0xD9, 0x5C, 0x41, + 0x1F, 0x10, 0x5A, 0xD8, 0x0A, 0xC1, 0x31, 0x88, 0xA5, 0xCD, 0x7B, 0xBD, + 0x2D, 0x74, 0xD0, 0x12, 0xB8, 0xE5, 0xB4, 0xB0, 0x89, 0x69, 0x97, 0x4A, + 0x0C, 0x96, 0x77, 0x7E, 0x65, 0xB9, 0xF1, 0x09, 0xC5, 0x6E, 0xC6, 0x84, + 0x18, 0xF0, 0x7D, 0xEC, 0x3A, 0xDC, 0x4D, 0x20, 0x79, 0xEE, 0x5F, 0x3E, + 0xD7, 0xCB, 0x39, 0x48 +}; + +#define AES_XTIME(a) \ + ((a << 1) ^ ((a & 0x80) ? 0x1b : 0)) + +#define AES_GFMUL(a, b) (( \ + (((b) & 0x1) ? (a) : 0) ^ \ + (((b) & 0x2) ? AES_XTIME(a) : 0) ^ \ + (((b) & 0x4) ? AES_XTIME(AES_XTIME(a)) : 0) ^ \ + (((b) & 0x8) ? AES_XTIME(AES_XTIME(AES_XTIME(a))) : 0)) & 0xFF) + +#define BY(X, I) ((X >> (8 * I)) & 0xFF) + +#define AES_SHIFROWS_LO(RS1, RS2) ( \ + (((RS1 >> 24) & 0xFF) << 56) | \ + (((RS2 >> 48) & 0xFF) << 48) | \ + (((RS2 >> 8) & 0xFF) << 40) | \ + (((RS1 >> 32) & 0xFF) << 32) | \ + (((RS2 >> 56) & 0xFF) << 24) | \ + (((RS2 >> 16) & 0xFF) << 16) | \ + (((RS1 >> 40) & 0xFF) << 8) | \ + (((RS1 >> 0) & 0xFF) << 0)) + +#define AES_INVSHIFROWS_LO(RS1, RS2) ( \ + (((RS2 >> 24) & 0xFF) << 56) | \ + (((RS2 >> 48) & 0xFF) << 48) | \ + (((RS1 >> 8) & 0xFF) << 40) | \ + (((RS1 >> 32) & 0xFF) << 32) | \ + (((RS1 >> 56) & 0xFF) << 24) | \ + (((RS2 >> 16) & 0xFF) << 16) | \ + (((RS2 >> 40) & 0xFF) << 8) | \ + (((RS1 >> 0) & 0xFF) << 0)) + +#define AES_MIXBYTE(COL, B0, B1, B2, B3) ( \ + BY(COL, B3) ^ \ + BY(COL, B2) ^ \ + AES_GFMUL(BY(COL, B1), 3) ^ \ + AES_GFMUL(BY(COL, B0), 2) \ +) + +#define AES_MIXCOLUMN(COL) ( \ + AES_MIXBYTE(COL, 3, 0, 1, 2) << 24 | \ + AES_MIXBYTE(COL, 2, 3, 0, 1) << 16 | \ + AES_MIXBYTE(COL, 1, 2, 3, 0) << 8 | \ + AES_MIXBYTE(COL, 0, 1, 2, 3) << 0 \ +) + +#define AES_INVMIXBYTE(COL, B0, B1, B2, B3) ( \ + AES_GFMUL(BY(COL, B3), 0x9) ^ \ + AES_GFMUL(BY(COL, B2), 0xd) ^ \ + AES_GFMUL(BY(COL, B1), 0xb) ^ \ + AES_GFMUL(BY(COL, B0), 0xe) \ +) + +#define AES_INVMIXCOLUMN(COL) ( \ + AES_INVMIXBYTE(COL, 3, 0, 1, 2) << 24 | \ + AES_INVMIXBYTE(COL, 2, 3, 0, 1) << 16 | \ + AES_INVMIXBYTE(COL, 1, 2, 3, 0) << 8 | \ + AES_INVMIXBYTE(COL, 0, 1, 2, 3) << 0 \ +) + +static inline uint32_t aes_mixcolumn_byte(uint8_t x, bool fwd) +{ + uint32_t u; + if (fwd) { + u = (AES_GFMUL(x, 3) << 24) | + (x << 16) | + (x << 8) | + (AES_GFMUL(x, 2) << 0); + } else { + u = (AES_GFMUL(x, 0xb) << 24) | + (AES_GFMUL(x, 0xd) << 16) | + (AES_GFMUL(x, 0x9) << 8) | + (AES_GFMUL(x, 0xe) << 0); + } + return u; +} + +#define XLEN (8 * sizeof(target_ulong)) +#define zext32(x) ((uint64_t)(uint32_t)(x)) +#define sext_xlen(x) (((int64_t)(x) << (XLEN - 32)) >> (XLEN - 32)) + +static inline target_ulong aes32_operation(target_ulong bs, target_ulong rs1, + target_ulong rs2, bool enc, + bool mix) +{ + uint8_t shamt = bs << 3; + uint8_t si = rs2 >> shamt; + uint8_t so; + uint32_t mixed; + if (enc) { + so = AES_ENC_SBOX[si]; + if (mix) { + mixed = aes_mixcolumn_byte(so, true); + } else { + mixed = so; + } + + } else { + so = AES_DEC_SBOX[si]; + if (mix) { + mixed = aes_mixcolumn_byte(so, false); + } else { + mixed = so; + } + } + mixed = (mixed << shamt) | (mixed >> (32 - shamt)); + target_ulong res = rs1 ^ mixed; + return sext_xlen(res); +} + +target_ulong HELPER(aes32esmi)(target_ulong rs1, target_ulong rs2, + target_ulong bs) +{ + return aes32_operation(bs, rs1, rs2, true, true); +} + +target_ulong HELPER(aes32esi)(target_ulong rs1, target_ulong rs2, + target_ulong bs) +{ + return aes32_operation(bs, rs1, rs2, true, false); +} + +target_ulong HELPER(aes32dsmi)(target_ulong rs1, target_ulong rs2, + target_ulong bs) +{ + return aes32_operation(bs, rs1, rs2, false, true); +} + +target_ulong HELPER(aes32dsi)(target_ulong rs1, target_ulong rs2, + target_ulong bs) +{ + return aes32_operation(bs, rs1, rs2, false, false); +} + +static inline target_ulong aes64_operation(target_ulong rs1, target_ulong rs2, + bool enc, bool mix) +{ + uint64_t RS1 = rs1; + uint64_t RS2 = rs2; + uint64_t result; + uint64_t temp; + uint32_t col_0; + uint32_t col_1; + if (enc) { + temp = AES_SHIFROWS_LO(RS1, RS2); + temp = ( + ((uint64_t)AES_ENC_SBOX[(temp >> 0) & 0xFF] << 0) | + ((uint64_t)AES_ENC_SBOX[(temp >> 8) & 0xFF] << 8) | + ((uint64_t)AES_ENC_SBOX[(temp >> 16) & 0xFF] << 16) | + ((uint64_t)AES_ENC_SBOX[(temp >> 24) & 0xFF] << 24) | + ((uint64_t)AES_ENC_SBOX[(temp >> 32) & 0xFF] << 32) | + ((uint64_t)AES_ENC_SBOX[(temp >> 40) & 0xFF] << 40) | + ((uint64_t)AES_ENC_SBOX[(temp >> 48) & 0xFF] << 48) | + ((uint64_t)AES_ENC_SBOX[(temp >> 56) & 0xFF] << 56) + ); + if (mix) { + col_0 = temp & 0xFFFFFFFF; + col_1 = temp >> 32 ; + + col_0 = AES_MIXCOLUMN(col_0); + col_1 = AES_MIXCOLUMN(col_1); + + result = ((uint64_t)col_1 << 32) | col_0; + } else { + result = temp; + } + } else { + temp = AES_INVSHIFROWS_LO(RS1, RS2); + temp = ( + ((uint64_t)AES_DEC_SBOX[(temp >> 0) & 0xFF] << 0) | + ((uint64_t)AES_DEC_SBOX[(temp >> 8) & 0xFF] << 8) | + ((uint64_t)AES_DEC_SBOX[(temp >> 16) & 0xFF] << 16) | + ((uint64_t)AES_DEC_SBOX[(temp >> 24) & 0xFF] << 24) | + ((uint64_t)AES_DEC_SBOX[(temp >> 32) & 0xFF] << 32) | + ((uint64_t)AES_DEC_SBOX[(temp >> 40) & 0xFF] << 40) | + ((uint64_t)AES_DEC_SBOX[(temp >> 48) & 0xFF] << 48) | + ((uint64_t)AES_DEC_SBOX[(temp >> 56) & 0xFF] << 56) + ); + if (mix) { + col_0 = temp & 0xFFFFFFFF; + col_1 = temp >> 32 ; + + col_0 = AES_INVMIXCOLUMN(col_0); + col_1 = AES_INVMIXCOLUMN(col_1); + + result = ((uint64_t)col_1 << 32) | col_0; + } else { + result = temp; + } + } + return result; +} + +target_ulong HELPER(aes64esm)(target_ulong rs1, target_ulong rs2) +{ + return aes64_operation(rs1, rs2, true, true); +} + +target_ulong HELPER(aes64es)(target_ulong rs1, target_ulong rs2) +{ + return aes64_operation(rs1, rs2, true, false); +} + +target_ulong HELPER(aes64ds)(target_ulong rs1, target_ulong rs2) +{ + return aes64_operation(rs1, rs2, false, false); +} + +target_ulong HELPER(aes64dsm)(target_ulong rs1, target_ulong rs2) +{ + return aes64_operation(rs1, rs2, false, true); +} + +target_ulong HELPER(aes64ks2)(target_ulong rs1, target_ulong rs2) +{ + uint64_t RS1 = rs1; + uint64_t RS2 = rs2; + uint32_t rs1_hi = RS1 >> 32; + uint32_t rs2_lo = RS2 ; + uint32_t rs2_hi = RS2 >> 32; + + uint32_t r_lo = (rs1_hi ^ rs2_lo) ; + uint32_t r_hi = (rs1_hi ^ rs2_lo ^ rs2_hi) ; + target_ulong result = ((uint64_t)r_hi << 32) | r_lo ; + return result; +} + +target_ulong HELPER(aes64ks1i)(target_ulong rs1, target_ulong rnum) +{ + uint64_t RS1 = rs1; + uint8_t round_consts[10] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 + }; + + uint8_t enc_rnum = rnum; + uint32_t temp = (RS1 >> 32) & 0xFFFFFFFF; + uint8_t rcon_ = 0; + target_ulong result; + + if (enc_rnum != 0xA) { + temp = (temp >> 8) | (temp << 24); /* Rotate right by 8 */ + rcon_ = round_consts[enc_rnum]; + } + + temp = + ((uint32_t)AES_ENC_SBOX[(temp >> 24) & 0xFF] << 24) | + ((uint32_t)AES_ENC_SBOX[(temp >> 16) & 0xFF] << 16) | + ((uint32_t)AES_ENC_SBOX[(temp >> 8) & 0xFF] << 8) | + ((uint32_t)AES_ENC_SBOX[(temp >> 0) & 0xFF] << 0) ; + + temp ^= rcon_; + + result = ((uint64_t)temp << 32) | temp; + return result; +} + +target_ulong HELPER(aes64im)(target_ulong rs1) +{ + uint64_t RS1 = rs1; + uint32_t col_0 = RS1 & 0xFFFFFFFF; + uint32_t col_1 = RS1 >> 32 ; + + col_0 = AES_INVMIXCOLUMN(col_0); + col_1 = AES_INVMIXCOLUMN(col_1); + + target_ulong result = ((uint64_t)col_1 << 32) | col_0; + return result; +} + +#define ROR32(a, amt) ((a << (-amt & 31)) | (a >> (amt & 31))) +target_ulong HELPER(sha256sig0)(target_ulong rs1) +{ + uint32_t a = rs1; + return sext_xlen(ROR32(a, 7) ^ ROR32(a, 18) ^ (a >> 3)); +} + +target_ulong HELPER(sha256sig1)(target_ulong rs1) +{ + uint32_t a = rs1; + return sext_xlen(ROR32(a, 17) ^ ROR32(a, 19) ^ (a >> 10)); +} + +target_ulong HELPER(sha256sum0)(target_ulong rs1) +{ + uint32_t a = rs1; + return sext_xlen(ROR32(a, 2) ^ ROR32(a, 13) ^ ROR32(a, 22)); +} + +target_ulong HELPER(sha256sum1)(target_ulong rs1) +{ + uint32_t a = rs1; + return sext_xlen(ROR32(a, 6) ^ ROR32(a, 11) ^ ROR32(a, 25)); +} +#undef ROR32 + +target_ulong HELPER(sha512sum0r)(target_ulong RS1, target_ulong RS2) +{ + uint64_t result = + (zext32(RS1) << 25) ^ (zext32(RS1) << 30) ^ (zext32(RS1) >> 28) ^ + (zext32(RS2) >> 7) ^ (zext32(RS2) >> 2) ^ (zext32(RS2) << 4); + return sext_xlen(result); +} + +target_ulong HELPER(sha512sum1r)(target_ulong RS1, target_ulong RS2) +{ + uint64_t result = + (zext32(RS1) << 23) ^ (zext32(RS1) >> 14) ^ (zext32(RS1) >> 18) ^ + (zext32(RS2) >> 9) ^ (zext32(RS2) << 18) ^ (zext32(RS2) << 14); + return sext_xlen(result); +} + +target_ulong HELPER(sha512sig0l)(target_ulong RS1, target_ulong RS2) +{ + uint64_t result = + (zext32(RS1) >> 1) ^ (zext32(RS1) >> 7) ^ (zext32(RS1) >> 8) ^ + (zext32(RS2) << 31) ^ (zext32(RS2) << 25) ^ (zext32(RS2) << 24); + return sext_xlen(result); +} + +target_ulong HELPER(sha512sig0h)(target_ulong RS1, target_ulong RS2) +{ + uint64_t result = + (zext32(RS1) >> 1) ^ (zext32(RS1) >> 7) ^ (zext32(RS1) >> 8) ^ + (zext32(RS2) << 31) ^ (zext32(RS2) << 24); + return sext_xlen(result); +} + +target_ulong HELPER(sha512sig1l)(target_ulong RS1, target_ulong RS2) +{ + uint64_t result = + (zext32(RS1) << 3) ^ (zext32(RS1) >> 6) ^ (zext32(RS1) >> 19) ^ + (zext32(RS2) >> 29) ^ (zext32(RS2) << 26) ^ (zext32(RS2) << 13); + return sext_xlen(result); +} + +target_ulong HELPER(sha512sig1h)(target_ulong RS1, target_ulong RS2) +{ + uint64_t result = + (zext32(RS1) << 3) ^ (zext32(RS1) >> 6) ^ (zext32(RS1) >> 19) ^ + (zext32(RS2) >> 29) ^ (zext32(RS2) << 13); + return sext_xlen(result); +} + +#define ROR64(a, amt) ((a << (-amt & 63)) | (a >> (amt & 63))) +target_ulong HELPER(sha512sig0)(target_ulong rs1) +{ + uint64_t a = rs1; + return ROR64(a, 1) ^ ROR64(a, 8) ^ (a >> 7); +} + +target_ulong HELPER(sha512sig1)(target_ulong rs1) +{ + uint64_t a = rs1; + return ROR64(a, 19) ^ ROR64(a, 61) ^ (a >> 6); +} + +target_ulong HELPER(sha512sum0)(target_ulong rs1) +{ + uint64_t a = rs1; + return ROR64(a, 28) ^ ROR64(a, 34) ^ ROR64(a, 39); +} + +target_ulong HELPER(sha512sum1)(target_ulong rs1) +{ + uint64_t a = rs1; + return ROR64(a, 14) ^ ROR64(a, 18) ^ ROR64(a, 41); +} +#undef ROR64 + +#define ROL32(a, amt) ((a >> (-amt & 31)) | (a << (amt & 31))) +target_ulong HELPER(sm3p0)(target_ulong rs1) +{ + uint32_t src = rs1; + uint32_t result = src ^ ROL32(src, 9) ^ ROL32(src, 17); + return sext_xlen(result); +} +target_ulong HELPER(sm3p1)(target_ulong rs1) +{ + uint32_t src = rs1; + uint32_t result = src ^ ROL32(src, 15) ^ ROL32(src, 23); + return sext_xlen(result); +} +#undef ROL32 + + +target_ulong HELPER(sm4ed)(target_ulong rs2, target_ulong rt, target_ulong bs) +{ + uint8_t bs_t = bs; + + uint32_t sb_in = (uint8_t)(rs2 >> (8 * bs_t)); + uint32_t sb_out = (uint32_t)sm4_sbox[sb_in]; + + uint32_t linear = sb_out ^ (sb_out << 8) ^ + (sb_out << 2) ^ + (sb_out << 18) ^ + ((sb_out & 0x3f) << 26) ^ + ((sb_out & 0xC0) << 10) ; + + uint32_t rotl = (linear << (8 * bs_t)) | (linear >> (32 - 8 * bs_t)); + + return sext_xlen(rotl ^ (uint32_t)rt); +} + +target_ulong HELPER(sm4ks)(target_ulong rs2, target_ulong rs1, target_ulong bs) +{ + uint8_t bs_t = bs; + + uint32_t sb_in = (uint8_t)(rs2 >> (8 * bs_t)); + uint32_t sb_out = sm4_sbox[sb_in]; + + uint32_t x = sb_out ^ + ((sb_out & 0x07) << 29) ^ ((sb_out & 0xFE) << 7) ^ + ((sb_out & 0x01) << 23) ^ ((sb_out & 0xF8) << 13) ; + + uint32_t rotl = (x << (8 * bs_t)) | (x >> (32 - 8 * bs_t)); + + return sext_xlen(rotl ^ (uint32_t)rs1); +} +#undef XLEN +#undef zext32 +#undef sext_xlen diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 216aa4193b..444505be8e 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1151,3 +1151,46 @@ DEF_HELPER_6(vcompress_vm_b, void, ptr, ptr, ptr, ptr, env, i32) DEF_HELPER_6(vcompress_vm_h, void, ptr, ptr, ptr, ptr, env, i32) DEF_HELPER_6(vcompress_vm_w, void, ptr, ptr, ptr, ptr, env, i32) DEF_HELPER_6(vcompress_vm_d, void, ptr, ptr, ptr, ptr, env, i32) + +/* Crypto Extension - aes 32 */ +DEF_HELPER_3(aes32esmi, tl, tl, tl, tl) +DEF_HELPER_3(aes32esi, tl, tl, tl, tl) +DEF_HELPER_3(aes32dsmi, tl, tl, tl, tl) +DEF_HELPER_3(aes32dsi, tl, tl, tl, tl) + +/* Crypto Extension - aes 64 */ +DEF_HELPER_2(aes64esm, tl, tl, tl) +DEF_HELPER_2(aes64es, tl, tl, tl) +DEF_HELPER_2(aes64ds, tl, tl, tl) +DEF_HELPER_2(aes64dsm, tl, tl, tl) +DEF_HELPER_2(aes64ks2, tl, tl, tl) +DEF_HELPER_2(aes64ks1i, tl, tl, tl) +DEF_HELPER_1(aes64im, tl, tl) + +/* Crypto Extension - sha256 */ +DEF_HELPER_1(sha256sig0, tl, tl) +DEF_HELPER_1(sha256sig1, tl, tl) +DEF_HELPER_1(sha256sum0, tl, tl) +DEF_HELPER_1(sha256sum1, tl, tl) + +/* Crypto Extension - sha512 */ +DEF_HELPER_2(sha512sum0r, tl, tl, tl) +DEF_HELPER_2(sha512sum1r, tl, tl, tl) +DEF_HELPER_2(sha512sig0l, tl, tl, tl) +DEF_HELPER_2(sha512sig0h, tl, tl, tl) +DEF_HELPER_2(sha512sig1l, tl, tl, tl) +DEF_HELPER_2(sha512sig1h, tl, tl, tl) + +/* Crypto Extension - sha512 */ +DEF_HELPER_1(sha512sig0, tl, tl) +DEF_HELPER_1(sha512sig1, tl, tl) +DEF_HELPER_1(sha512sum0, tl, tl) +DEF_HELPER_1(sha512sum1, tl, tl) + +/* Crypto Extension - sm3 */ +DEF_HELPER_1(sm3p0, tl, tl) +DEF_HELPER_1(sm3p1, tl, tl) + +/* Crypto Extension - sm4 */ +DEF_HELPER_3(sm4ed, tl, tl, tl, tl) +DEF_HELPER_3(sm4ks, tl, tl, tl, tl) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index a5333c4533..69e940457e 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -17,8 +17,10 @@ # this program. If not, see <http://www.gnu.org/licenses/>. # Fields: +%bs 30:2 %rs3 27:5 %rs2 20:5 +%rnum 20:4 %rs1 15:5 %rd 7:5 %sh5 20:5 @@ -91,6 +93,7 @@ # Formats 64: @sh5 ....... ..... ..... ... ..... ....... &shift shamt=%sh5 %rs1 %rd +@k_aes .. ..... ..... ..... ... ..... ....... %bs %rs2 %rs1 %rd # *** Privileged Instructions *** ecall 000000000000 00000 000 00000 1110011 @@ -744,3 +747,42 @@ binv 0110100 .......... 001 ..... 0110011 @r binvi 01101. ........... 001 ..... 0010011 @sh bset 0010100 .......... 001 ..... 0110011 @r bseti 00101. ........... 001 ..... 0010011 @sh + +# *** RV32 Zkne Standard Extension *** +aes32esmi .. 10011 ..... ..... 000 ..... 0110011 @k_aes +aes32esi .. 10001 ..... ..... 000 ..... 0110011 @k_aes +# *** RV64 Zkne Standard Extension *** +aes64es 00 11001 ..... ..... 000 ..... 0110011 @r +aes64esm 00 11011 ..... ..... 000 ..... 0110011 @r +# *** RV32 Zknd Standard Extension *** +aes32dsmi .. 10111 ..... ..... 000 ..... 0110011 @k_aes +aes32dsi .. 10101 ..... ..... 000 ..... 0110011 @k_aes +# *** RV64 Zknd Standard Extension *** +aes64dsm 00 11111 ..... ..... 000 ..... 0110011 @r +aes64ds 00 11101 ..... ..... 000 ..... 0110011 @r +aes64im 00 11000 00000 ..... 001 ..... 0010011 @r2 +# *** RV64 Zkne/zknd Standard Extension *** +aes64ks2 01 11111 ..... ..... 000 ..... 0110011 @r +aes64ks1i 00 11000 1.... ..... 001 ..... 0010011 %rnum %rs1 %rd +# *** RV32 Zknh Standard Extension *** +sha256sig0 00 01000 00010 ..... 001 ..... 0010011 @r2 +sha256sig1 00 01000 00011 ..... 001 ..... 0010011 @r2 +sha256sum0 00 01000 00000 ..... 001 ..... 0010011 @r2 +sha256sum1 00 01000 00001 ..... 001 ..... 0010011 @r2 +sha512sum0r 01 01000 ..... ..... 000 ..... 0110011 @r +sha512sum1r 01 01001 ..... ..... 000 ..... 0110011 @r +sha512sig0l 01 01010 ..... ..... 000 ..... 0110011 @r +sha512sig0h 01 01110 ..... ..... 000 ..... 0110011 @r +sha512sig1l 01 01011 ..... ..... 000 ..... 0110011 @r +sha512sig1h 01 01111 ..... ..... 000 ..... 0110011 @r +# *** RV64 Zknh Standard Extension *** +sha512sig0 00 01000 00110 ..... 001 ..... 0010011 @r2 +sha512sig1 00 01000 00111 ..... 001 ..... 0010011 @r2 +sha512sum0 00 01000 00100 ..... 001 ..... 0010011 @r2 +sha512sum1 00 01000 00101 ..... 001 ..... 0010011 @r2 +# *** RV32 Zksh Standard Extension *** +sm3p0 00 01000 01000 ..... 001 ..... 0010011 @r2 +sm3p1 00 01000 01001 ..... 001 ..... 0010011 @r2 +# *** RV32 Zksed Standard Extension *** +sm4ed .. 11000 ..... ..... 000 ..... 0110011 @k_aes +sm4ks .. 11010 ..... ..... 000 ..... 0110011 @k_aes diff --git a/target/riscv/insn_trans/trans_rvk.c.inc b/target/riscv/insn_trans/trans_rvk.c.inc new file mode 100644 index 0000000000..da8dea69b8 --- /dev/null +++ b/target/riscv/insn_trans/trans_rvk.c.inc @@ -0,0 +1,467 @@ +/* + * RISC-V translation routines for the Zk[nd,ne,nh,sed,sh] Standard Extension. + * + * Copyright (c) 2021 Ruibo Lu, luruibo2000@163.com + * Copyright (c) 2021 Zewen Ye, lustrew@foxmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#define REQUIRE_ZKND(ctx) do { \ + if (!RISCV_CPU(ctx->cs)->cfg.ext_zknd) { \ + return false; \ + } \ +} while (0) + +#define REQUIRE_ZKNE(ctx) do { \ + if (!RISCV_CPU(ctx->cs)->cfg.ext_zkne) { \ + return false; \ + } \ +} while (0) + +#define REQUIRE_ZKNH(ctx) do { \ + if (!RISCV_CPU(ctx->cs)->cfg.ext_zknh) { \ + return false; \ + } \ +} while (0) + +#define REQUIRE_ZKSED(ctx) do { \ + if (!RISCV_CPU(ctx->cs)->cfg.ext_zksed) { \ + return false; \ + } \ +} while (0) + +#define REQUIRE_ZKSH(ctx) do { \ + if (!RISCV_CPU(ctx->cs)->cfg.ext_zksh) { \ + return false; \ + } \ +} while (0) + +static bool trans_aes32esmi(DisasContext *ctx, arg_aes32esmi *a) +{ + REQUIRE_ZKNE(ctx); + + TCGv bs = tcg_const_tl(a->bs); + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_aes32esmi(dest, src1, src2, bs); + gen_set_gpr(ctx, a->rd, dest); + + tcg_temp_free(bs); + return true; +} + +static bool trans_aes64esm(DisasContext *ctx, arg_aes64esm *a) +{ + REQUIRE_ZKNE(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_aes64esm(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_aes32esi(DisasContext *ctx, arg_aes32esi *a) +{ + REQUIRE_ZKNE(ctx); + + TCGv bs = tcg_const_tl(a->bs); + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_aes32esi(dest, src1, src2, bs); + gen_set_gpr(ctx, a->rd, dest); + + tcg_temp_free(bs); + return true; +} + +static bool trans_aes64es(DisasContext *ctx, arg_aes64es *a) +{ + REQUIRE_ZKNE(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_aes64es(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_aes32dsmi(DisasContext *ctx, arg_aes32dsmi *a) +{ + REQUIRE_ZKND(ctx); + + TCGv bs = tcg_const_tl(a->bs); + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_aes32dsmi(dest, src1, src2, bs); + gen_set_gpr(ctx, a->rd, dest); + + tcg_temp_free(bs); + return true; +} + +static bool trans_aes64dsm(DisasContext *ctx, arg_aes64dsm *a) +{ + REQUIRE_ZKND(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_aes64dsm(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_aes64ks2(DisasContext *ctx, arg_aes64ks2 *a) +{ + REQUIRE_EITHER_EXT(ctx, zknd, zkne); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_aes64ks2(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + + tcg_temp_free(dest); + tcg_temp_free(src1); + tcg_temp_free(src2); + + return true; +} + +static bool trans_aes32dsi(DisasContext *ctx, arg_aes32dsi *a) +{ + REQUIRE_ZKND(ctx); + + TCGv bs = tcg_const_tl(a->bs); + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_aes32dsi(dest, src1, src2, bs); + gen_set_gpr(ctx, a->rd, dest); + + tcg_temp_free(bs); + return true; +} + +static bool trans_aes64ds(DisasContext *ctx, arg_aes64ds *a) +{ + REQUIRE_ZKND(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_aes64ds(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_aes64ks1i(DisasContext *ctx, arg_aes64ks1i *a) +{ + REQUIRE_EITHER_EXT(ctx, zknd, zkne); + + if (a->rnum > 0xA) { + return false; + } + + TCGv rnum; + rnum = tcg_const_tl(a->rnum); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_aes64ks1i(dest, src1, rnum); + gen_set_gpr(ctx, a->rd, dest); + + tcg_temp_free(rnum); + return true; +} + +static bool trans_aes64im(DisasContext *ctx, arg_aes64im *a) +{ + REQUIRE_ZKND(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_aes64im(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_sha256sig0(DisasContext *ctx, arg_sha256sig0 *a) +{ + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sha256sig0(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_sha256sig1(DisasContext *ctx, arg_sha256sig1 *a) +{ + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sha256sig1(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_sha256sum0(DisasContext *ctx, arg_sha256sum0 *a) +{ + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sha256sum0(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_sha256sum1(DisasContext *ctx, arg_sha256sum1 *a) +{ + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sha256sum1(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_sha512sum0r(DisasContext *ctx, arg_sha512sum0r *a) +{ + REQUIRE_32BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_sha512sum0r(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_sha512sum1r(DisasContext *ctx, arg_sha512sum1r *a) +{ + REQUIRE_32BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_sha512sum1r(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_sha512sig0l(DisasContext *ctx, arg_sha512sig0l *a) +{ + REQUIRE_32BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_sha512sig0l(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_sha512sig0h(DisasContext *ctx, arg_sha512sig0h *a) +{ + REQUIRE_32BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_sha512sig0h(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_sha512sig1l(DisasContext *ctx, arg_sha512sig1l *a) +{ + REQUIRE_32BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_sha512sig1l(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_sha512sig1h(DisasContext *ctx, arg_sha512sig1h *a) +{ + REQUIRE_32BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_sha512sig1h(dest, src1, src2); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_sha512sig0(DisasContext *ctx, arg_sha512sig0 *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sha512sig0(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_sha512sig1(DisasContext *ctx, arg_sha512sig1 *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sha512sig1(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_sha512sum0(DisasContext *ctx, arg_sha512sum0 *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sha512sum0(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_sha512sum1(DisasContext *ctx, arg_sha512sum1 *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_ZKNH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sha512sum1(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +/* SM3 */ +static bool trans_sm3p0(DisasContext *ctx, arg_sm3p0 *a) +{ + REQUIRE_ZKSH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sm3p0(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_sm3p1(DisasContext *ctx, arg_sm3p1 *a) +{ + REQUIRE_ZKSH(ctx); + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + + gen_helper_sm3p1(dest, src1); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +/* SM4 */ +static bool trans_sm4ed(DisasContext *ctx, arg_sm4ed *a) +{ + REQUIRE_ZKSED(ctx); + + TCGv bs = tcg_const_tl(a->bs); + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_sm4ed(dest, src2, src1, bs); + gen_set_gpr(ctx, a->rd, dest); + + tcg_temp_free(bs); + return true; +} + +static bool trans_sm4ks(DisasContext *ctx, arg_sm4ks *a) +{ + REQUIRE_ZKSED(ctx); + + TCGv bs = tcg_const_tl(a->bs); + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + + gen_helper_sm4ks(dest, src2, src1, bs); + gen_set_gpr(ctx, a->rd, dest); + + tcg_temp_free(bs); + return true; +} diff --git a/target/riscv/meson.build b/target/riscv/meson.build index d5e0bc93ea..4fc385c2fb 100644 --- a/target/riscv/meson.build +++ b/target/riscv/meson.build @@ -18,6 +18,7 @@ riscv_ss.add(files( 'vector_helper.c', 'bitmanip_helper.c', 'translate.c', + 'crypto_helper.c', )) riscv_softmmu_ss = ss.source_set() diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 5b868cd53f..735fae047a 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -656,6 +656,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc) #include "insn_trans/trans_rvh.c.inc" #include "insn_trans/trans_rvv.c.inc" #include "insn_trans/trans_rvb.c.inc" +#include "insn_trans/trans_rvk.c.inc" #include "insn_trans/trans_privileged.c.inc" /* Include the auto-generated decoder for 16 bit insn */ -- 2.17.1 ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [RFC 4/6] target/riscv: rvk: add implementation of instructions for Zk* 2021-11-02 3:11 ` liweiwei @ 2021-11-02 18:56 ` Richard Henderson -1 siblings, 0 replies; 34+ messages in thread From: Richard Henderson @ 2021-11-02 18:56 UTC (permalink / raw) To: liweiwei, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, luruibo2000, lustrew On 11/1/21 11:11 PM, liweiwei wrote: > +uint8_t AES_ENC_SBOX[] = { > + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, > + 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, > + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, > + 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, Use "crypto/aes.h". > +/* SM4 forward SBox. SM4 has no inverse sbox. */ > +static const uint8_t sm4_sbox[256] = { > + 0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2, > + 0x28, 0xFB, 0x2C, 0x05, 0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3, > + 0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9C, 0x42, 0x50, 0xF4, Hmm. We have an existing copy of this in target/arm/crypto_helper.c. I think we should move that code out to a shared location like aes. > +#define sext_xlen(x) (((int64_t)(x) << (XLEN - 32)) >> (XLEN - 32)) This is (target_ulong)(int32_t)(x). r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [RFC 4/6] target/riscv: rvk: add implementation of instructions for Zk* @ 2021-11-02 18:56 ` Richard Henderson 0 siblings, 0 replies; 34+ messages in thread From: Richard Henderson @ 2021-11-02 18:56 UTC (permalink / raw) To: liweiwei, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, lustrew, luruibo2000 On 11/1/21 11:11 PM, liweiwei wrote: > +uint8_t AES_ENC_SBOX[] = { > + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, > + 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, > + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, > + 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, Use "crypto/aes.h". > +/* SM4 forward SBox. SM4 has no inverse sbox. */ > +static const uint8_t sm4_sbox[256] = { > + 0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2, > + 0x28, 0xFB, 0x2C, 0x05, 0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3, > + 0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9C, 0x42, 0x50, 0xF4, Hmm. We have an existing copy of this in target/arm/crypto_helper.c. I think we should move that code out to a shared location like aes. > +#define sext_xlen(x) (((int64_t)(x) << (XLEN - 32)) >> (XLEN - 32)) This is (target_ulong)(int32_t)(x). r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [RFC 4/6] target/riscv: rvk: add implementation of instructions for Zk* 2021-11-02 18:56 ` Richard Henderson @ 2021-11-03 1:08 ` liweiwei -1 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-03 1:08 UTC (permalink / raw) To: Richard Henderson, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, luruibo2000, lustrew 在 2021/11/3 上午2:56, Richard Henderson 写道: > On 11/1/21 11:11 PM, liweiwei wrote: >> +uint8_t AES_ENC_SBOX[] = { >> + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, >> + 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, >> + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, >> + 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, > > Use "crypto/aes.h". > OK. I'll reuse this. > >> +/* SM4 forward SBox. SM4 has no inverse sbox. */ >> +static const uint8_t sm4_sbox[256] = { >> + 0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, >> 0x14, 0xC2, >> + 0x28, 0xFB, 0x2C, 0x05, 0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, >> 0x04, 0xC3, >> + 0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9C, 0x42, >> 0x50, 0xF4, > > Hmm. We have an existing copy of this in target/arm/crypto_helper.c. > I think we should move that code out to a shared location like aes. OK. I'll try to move it. > >> +#define sext_xlen(x) (((int64_t)(x) << (XLEN - 32)) >> (XLEN - 32)) > > This is (target_ulong)(int32_t)(x). > OK. I'll improve this. > > r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [RFC 4/6] target/riscv: rvk: add implementation of instructions for Zk* @ 2021-11-03 1:08 ` liweiwei 0 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-03 1:08 UTC (permalink / raw) To: Richard Henderson, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, lazyparser, lustrew, luruibo2000 在 2021/11/3 上午2:56, Richard Henderson 写道: > On 11/1/21 11:11 PM, liweiwei wrote: >> +uint8_t AES_ENC_SBOX[] = { >> + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, >> + 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, >> + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, >> + 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, > > Use "crypto/aes.h". > OK. I'll reuse this. > >> +/* SM4 forward SBox. SM4 has no inverse sbox. */ >> +static const uint8_t sm4_sbox[256] = { >> + 0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, >> 0x14, 0xC2, >> + 0x28, 0xFB, 0x2C, 0x05, 0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, >> 0x04, 0xC3, >> + 0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9C, 0x42, >> 0x50, 0xF4, > > Hmm. We have an existing copy of this in target/arm/crypto_helper.c. > I think we should move that code out to a shared location like aes. OK. I'll try to move it. > >> +#define sext_xlen(x) (((int64_t)(x) << (XLEN - 32)) >> (XLEN - 32)) > > This is (target_ulong)(int32_t)(x). > OK. I'll improve this. > > r~ ^ permalink raw reply [flat|nested] 34+ messages in thread
* [RFC 5/6] target/riscv: rvk: add CSR support for Zkr: - add SEED CSR - add USEED, SSEED fields for MSECCFG CSR 2021-11-02 3:11 ` liweiwei @ 2021-11-02 3:11 ` liweiwei -1 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-02 3:11 UTC (permalink / raw) To: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, liweiwei, lazyparser, lustrew, luruibo2000 Signed-off-by: liweiwei <liweiwei@iscas.ac.cn> Signed-off-by: wangjunqiang <wangjunqiang@iscas.ac.cn> --- target/riscv/cpu_bits.h | 9 ++++++ target/riscv/csr.c | 66 +++++++++++++++++++++++++++++++++++++++++ target/riscv/pmp.h | 8 +++-- 3 files changed, 80 insertions(+), 3 deletions(-) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 9913fa9f77..1aa14723f8 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -366,6 +366,9 @@ #define CSR_VSPMMASK 0x2c1 #define CSR_VSPMBASE 0x2c2 +/* Crypto Extension */ +#define CSR_SEED 0x015 + /* mstatus CSR bits */ #define MSTATUS_UIE 0x00000001 #define MSTATUS_SIE 0x00000002 @@ -615,4 +618,10 @@ typedef enum RISCVException { #define UMTE_U_PM_INSN U_PM_INSN #define UMTE_MASK (UMTE_U_PM_ENABLE | MMTE_U_PM_CURRENT | UMTE_U_PM_INSN) +/* seed CSR bits */ +#define SEED_OPST (0b11 << 30) +#define SEED_OPST_BIST (0b00 << 30) +#define SEED_OPST_WAIT (0b01 << 30) +#define SEED_OPST_ES16 (0b10 << 30) +#define SEED_OPST_DEAD (0b11 << 30) #endif diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 9f41954894..e5fd899df0 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -22,6 +22,8 @@ #include "cpu.h" #include "qemu/main-loop.h" #include "exec/exec-all.h" +#include "qemu/guest-random.h" +#include "qapi/error.h" /* CSR function table public API */ void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops) @@ -221,6 +223,30 @@ static RISCVException epmp(CPURISCVState *env, int csrno) } #endif +/* Predicates */ +static RISCVException seed(CPURISCVState *env, int csrno) +{ +#if !defined(CONFIG_USER_ONLY) + if (riscv_has_ext(env, RVS) && riscv_has_ext(env, RVH)) { + /* Hypervisor extension is supported */ + if (riscv_cpu_virt_enabled(env) && (env->priv != PRV_M)) { + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; + } + } + if (env->priv == PRV_M) { + return RISCV_EXCP_NONE; + } else if (env->priv == PRV_S && (env->mseccfg & MSECCFG_SSEED)) { + return RISCV_EXCP_NONE; + } else if (env->priv == PRV_U && (env->mseccfg & MSECCFG_USEED)) { + return RISCV_EXCP_NONE; + } else { + return RISCV_EXCP_ILLEGAL_INST; + } +#else + return RISCV_EXCP_NONE; +#endif +} + /* User Floating-Point CSRs */ static RISCVException read_fflags(CPURISCVState *env, int csrno, target_ulong *val) @@ -1699,6 +1725,39 @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno, #endif +/* Crypto Extension */ +static int read_seed(CPURISCVState *env, int csrno, target_ulong *val) +{ + *val = 0; + uint32_t return_status = SEED_OPST_ES16; + *val = (*val) | return_status; + if (return_status == SEED_OPST_ES16) { + uint16_t random_number; + Error *err = NULL; + if (qemu_guest_getrandom(&random_number, sizeof(random_number), + &err) < 0) { + qemu_log_mask(LOG_UNIMP, "Seed: Crypto failure: %s", + error_get_pretty(err)); + error_free(err); + return -1; + } + *val = (*val) | random_number; + } else if (return_status == SEED_OPST_BIST) { + /* Do nothing */ + } else if (return_status == SEED_OPST_WAIT) { + /* Do nothing */ + } else if (return_status == SEED_OPST_DEAD) { + /* Do nothing */ + } + return 0; +} + +static RISCVException write_seed(CPURISCVState *env, int csrno, + target_ulong val) +{ + return RISCV_EXCP_NONE; +} + /* * riscv_csrrw - read and/or update control and status register * @@ -1740,6 +1799,10 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno, return RISCV_EXCP_ILLEGAL_INST; } + if (!write_mask && (csrno == CSR_SEED)) { + return RISCV_EXCP_ILLEGAL_INST; + } + /* ensure the CSR extension is enabled. */ if (!cpu->cfg.ext_icsr) { return RISCV_EXCP_ILLEGAL_INST; @@ -1833,6 +1896,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_TIME] = { "time", ctr, read_time }, [CSR_TIMEH] = { "timeh", ctr32, read_timeh }, + /* Crypto Extension */ + [CSR_SEED] = { "seed", seed, read_seed, write_seed}, + #if !defined(CONFIG_USER_ONLY) /* Machine Timers and Counters */ [CSR_MCYCLE] = { "mcycle", any, read_instret }, diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h index a9a0b363a7..83135849bb 100644 --- a/target/riscv/pmp.h +++ b/target/riscv/pmp.h @@ -37,9 +37,11 @@ typedef enum { } pmp_am_t; typedef enum { - MSECCFG_MML = 1 << 0, - MSECCFG_MMWP = 1 << 1, - MSECCFG_RLB = 1 << 2 + MSECCFG_MML = 1 << 0, + MSECCFG_MMWP = 1 << 1, + MSECCFG_RLB = 1 << 2, + MSECCFG_USEED = 1 << 8, + MSECCFG_SSEED = 1 << 9 } mseccfg_field_t; typedef struct { -- 2.17.1 ^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC 5/6] target/riscv: rvk: add CSR support for Zkr: - add SEED CSR - add USEED, SSEED fields for MSECCFG CSR @ 2021-11-02 3:11 ` liweiwei 0 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-02 3:11 UTC (permalink / raw) To: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: luruibo2000, lustrew, wangjunqiang, lazyparser, liweiwei Signed-off-by: liweiwei <liweiwei@iscas.ac.cn> Signed-off-by: wangjunqiang <wangjunqiang@iscas.ac.cn> --- target/riscv/cpu_bits.h | 9 ++++++ target/riscv/csr.c | 66 +++++++++++++++++++++++++++++++++++++++++ target/riscv/pmp.h | 8 +++-- 3 files changed, 80 insertions(+), 3 deletions(-) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 9913fa9f77..1aa14723f8 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -366,6 +366,9 @@ #define CSR_VSPMMASK 0x2c1 #define CSR_VSPMBASE 0x2c2 +/* Crypto Extension */ +#define CSR_SEED 0x015 + /* mstatus CSR bits */ #define MSTATUS_UIE 0x00000001 #define MSTATUS_SIE 0x00000002 @@ -615,4 +618,10 @@ typedef enum RISCVException { #define UMTE_U_PM_INSN U_PM_INSN #define UMTE_MASK (UMTE_U_PM_ENABLE | MMTE_U_PM_CURRENT | UMTE_U_PM_INSN) +/* seed CSR bits */ +#define SEED_OPST (0b11 << 30) +#define SEED_OPST_BIST (0b00 << 30) +#define SEED_OPST_WAIT (0b01 << 30) +#define SEED_OPST_ES16 (0b10 << 30) +#define SEED_OPST_DEAD (0b11 << 30) #endif diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 9f41954894..e5fd899df0 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -22,6 +22,8 @@ #include "cpu.h" #include "qemu/main-loop.h" #include "exec/exec-all.h" +#include "qemu/guest-random.h" +#include "qapi/error.h" /* CSR function table public API */ void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops) @@ -221,6 +223,30 @@ static RISCVException epmp(CPURISCVState *env, int csrno) } #endif +/* Predicates */ +static RISCVException seed(CPURISCVState *env, int csrno) +{ +#if !defined(CONFIG_USER_ONLY) + if (riscv_has_ext(env, RVS) && riscv_has_ext(env, RVH)) { + /* Hypervisor extension is supported */ + if (riscv_cpu_virt_enabled(env) && (env->priv != PRV_M)) { + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; + } + } + if (env->priv == PRV_M) { + return RISCV_EXCP_NONE; + } else if (env->priv == PRV_S && (env->mseccfg & MSECCFG_SSEED)) { + return RISCV_EXCP_NONE; + } else if (env->priv == PRV_U && (env->mseccfg & MSECCFG_USEED)) { + return RISCV_EXCP_NONE; + } else { + return RISCV_EXCP_ILLEGAL_INST; + } +#else + return RISCV_EXCP_NONE; +#endif +} + /* User Floating-Point CSRs */ static RISCVException read_fflags(CPURISCVState *env, int csrno, target_ulong *val) @@ -1699,6 +1725,39 @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno, #endif +/* Crypto Extension */ +static int read_seed(CPURISCVState *env, int csrno, target_ulong *val) +{ + *val = 0; + uint32_t return_status = SEED_OPST_ES16; + *val = (*val) | return_status; + if (return_status == SEED_OPST_ES16) { + uint16_t random_number; + Error *err = NULL; + if (qemu_guest_getrandom(&random_number, sizeof(random_number), + &err) < 0) { + qemu_log_mask(LOG_UNIMP, "Seed: Crypto failure: %s", + error_get_pretty(err)); + error_free(err); + return -1; + } + *val = (*val) | random_number; + } else if (return_status == SEED_OPST_BIST) { + /* Do nothing */ + } else if (return_status == SEED_OPST_WAIT) { + /* Do nothing */ + } else if (return_status == SEED_OPST_DEAD) { + /* Do nothing */ + } + return 0; +} + +static RISCVException write_seed(CPURISCVState *env, int csrno, + target_ulong val) +{ + return RISCV_EXCP_NONE; +} + /* * riscv_csrrw - read and/or update control and status register * @@ -1740,6 +1799,10 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno, return RISCV_EXCP_ILLEGAL_INST; } + if (!write_mask && (csrno == CSR_SEED)) { + return RISCV_EXCP_ILLEGAL_INST; + } + /* ensure the CSR extension is enabled. */ if (!cpu->cfg.ext_icsr) { return RISCV_EXCP_ILLEGAL_INST; @@ -1833,6 +1896,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_TIME] = { "time", ctr, read_time }, [CSR_TIMEH] = { "timeh", ctr32, read_timeh }, + /* Crypto Extension */ + [CSR_SEED] = { "seed", seed, read_seed, write_seed}, + #if !defined(CONFIG_USER_ONLY) /* Machine Timers and Counters */ [CSR_MCYCLE] = { "mcycle", any, read_instret }, diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h index a9a0b363a7..83135849bb 100644 --- a/target/riscv/pmp.h +++ b/target/riscv/pmp.h @@ -37,9 +37,11 @@ typedef enum { } pmp_am_t; typedef enum { - MSECCFG_MML = 1 << 0, - MSECCFG_MMWP = 1 << 1, - MSECCFG_RLB = 1 << 2 + MSECCFG_MML = 1 << 0, + MSECCFG_MMWP = 1 << 1, + MSECCFG_RLB = 1 << 2, + MSECCFG_USEED = 1 << 8, + MSECCFG_SSEED = 1 << 9 } mseccfg_field_t; typedef struct { -- 2.17.1 ^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC 6/6] disas/riscv.c: rvk: add disas support for Zbk* and Zk* instructions 2021-11-02 3:11 ` liweiwei @ 2021-11-02 3:11 ` liweiwei -1 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-02 3:11 UTC (permalink / raw) To: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: wangjunqiang, liweiwei, lazyparser, lustrew, luruibo2000 Signed-off-by: liweiwei <liweiwei@iscas.ac.cn> Signed-off-by: wangjunqiang <wangjunqiang@iscas.ac.cn> --- disas/riscv.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 170 insertions(+), 1 deletion(-) diff --git a/disas/riscv.c b/disas/riscv.c index 793ad14c27..eb1d36d1e5 100644 --- a/disas/riscv.c +++ b/disas/riscv.c @@ -156,6 +156,8 @@ typedef enum { rv_codec_css_swsp, rv_codec_css_sdsp, rv_codec_css_sqsp, + rv_codec_k_bs, + rv_codec_k_rnum, } rv_codec; typedef enum { @@ -521,6 +523,43 @@ typedef enum { rv_op_bclr = 359, rv_op_binv = 360, rv_op_bext = 361, + rv_op_aes32esmi = 362, + rv_op_aes32esi = 363, + rv_op_aes32dsmi = 364, + rv_op_aes32dsi = 365, + rv_op_aes64ks1i = 366, + rv_op_aes64ks2 = 367, + rv_op_aes64im = 368, + rv_op_aes64esm = 369, + rv_op_aes64es = 370, + rv_op_aes64dsm = 371, + rv_op_aes64ds = 372, + rv_op_sha256sig0 = 373, + rv_op_sha256sig1 = 374, + rv_op_sha256sum0 = 375, + rv_op_sha256sum1 = 376, + rv_op_sha512sig0 = 377, + rv_op_sha512sig1 = 378, + rv_op_sha512sum0 = 379, + rv_op_sha512sum1 = 380, + rv_op_sha512sum0r = 381, + rv_op_sha512sum1r = 382, + rv_op_sha512sig0l = 383, + rv_op_sha512sig0h = 384, + rv_op_sha512sig1l = 385, + rv_op_sha512sig1h = 386, + rv_op_sm3p0 = 387, + rv_op_sm3p1 = 388, + rv_op_sm4ed = 389, + rv_op_sm4ks = 390, + rv_op_brev8 = 391, + rv_op_pack = 392, + rv_op_packh = 393, + rv_op_packw = 394, + rv_op_unzip = 395, + rv_op_zip = 396, + rv_op_xperm4 = 397, + rv_op_xperm8 = 398, } rv_op; /* structures */ @@ -540,6 +579,8 @@ typedef struct { uint8_t succ; uint8_t aq; uint8_t rl; + uint8_t bs; + uint8_t rnum; } rv_decode; typedef struct { @@ -615,6 +656,8 @@ static const char rv_freg_name_sym[32][5] = { #define rv_fmt_rd_rs2 "O\t0,2" #define rv_fmt_rs1_offset "O\t1,o" #define rv_fmt_rs2_offset "O\t2,o" +#define rv_fmt_rs1_rs2_bs "O\t1,2,b" +#define rv_fmt_rd_rs1_rnum "O\t0,1,n" /* pseudo-instruction constraints */ @@ -766,6 +809,7 @@ static const rv_comp_data rvcp_csrrw[] = { { rv_op_illegal, NULL } }; + static const rv_comp_data rvcp_csrrs[] = { { rv_op_rdcycle, rvcc_rdcycle }, { rv_op_rdtime, rvcc_rdtime }, @@ -1203,10 +1247,46 @@ const rv_opcode_data opcode_data[] = { { "bclr", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, { "binv", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, { "bext", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "aes32esmi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 }, + { "aes32esi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 }, + { "aes32dsmi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 }, + { "aes32dsi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 }, + { "aes64ks1i", rv_codec_k_rnum, rv_fmt_rd_rs1_rnum, NULL, 0, 0, 0 }, + { "aes64ks2", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "aes64im", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, + { "aes64esm", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "aes64es", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "aes64dsm", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "aes64ds", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha256sig0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, + { "sha256sig1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, + { "sha256sum0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, + { "sha256sum1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, + { "sha512sig0", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha512sig1", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha512sum0", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha512sum1", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha512sum0r", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha512sum1r", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha512sig0l", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha512sig0h", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha512sig1l", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha512sig1h", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sm3p0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, + { "sm3p1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, + { "sm4ed", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 }, + { "sm4ks", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 }, + { "brev8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, + { "pack", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "packh", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "packw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "unzip", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, + { "zip", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, + { "xperm4", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "xperm8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 } }; /* CSR names */ - static const char *csr_name(int csrno) { switch (csrno) { @@ -1216,6 +1296,7 @@ static const char *csr_name(int csrno) case 0x0003: return "fcsr"; case 0x0004: return "uie"; case 0x0005: return "utvec"; + case 0x0015: return "seed"; case 0x0040: return "uscratch"; case 0x0041: return "uepc"; case 0x0042: return "ucause"; @@ -1594,7 +1675,36 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 1: switch (((inst >> 27) & 0b11111)) { case 0b00000: op = rv_op_slli; break; + case 0b00001: + switch (((inst >> 20) & 0b1111111)) { + case 0b0001111: op = rv_op_zip; break; + } + break; + case 0b00010: + switch (((inst >> 20) & 0b1111111)) { + case 0b0000000: op = rv_op_sha256sum0; break; + case 0b0000001: op = rv_op_sha256sum1; break; + case 0b0000010: op = rv_op_sha256sig0; break; + case 0b0000011: op = rv_op_sha256sig1; break; + case 0b0000100: op = rv_op_sha512sum0; break; + case 0b0000101: op = rv_op_sha512sum1; break; + case 0b0000110: op = rv_op_sha512sig0; break; + case 0b0000111: op = rv_op_sha512sig1; break; + case 0b0001000: op = rv_op_sm3p0; break; + case 0b0001001: op = rv_op_sm3p1; break; + } + break; case 0b00101: op = rv_op_bseti; break; + case 0b00110: + switch (((inst >> 20) & 0b1111111)) { + case 0b0000000: op = rv_op_aes64im; break; + default: + if (((inst >> 24) & 0x111) == 0b001) { + op = rv_op_aes64ks1i; + } + break; + } + break; case 0b01001: op = rv_op_bclri; break; case 0b01101: op = rv_op_binvi; break; case 0b01100: @@ -1615,6 +1725,11 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 5: switch (((inst >> 27) & 0b11111)) { case 0b00000: op = rv_op_srli; break; + case 0b00001: + switch (((inst >> 20) & 0b1111111)) { + case 0b0001111: op = rv_op_unzip; break; + } + break; case 0b00101: op = rv_op_orc_b; break; case 0b01000: op = rv_op_srai; break; case 0b01001: op = rv_op_bexti; break; @@ -1622,6 +1737,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 0b01101: switch ((inst >> 20) & 0b1111111) { case 0b0111000: op = rv_op_rev8; break; + case 0b0000111: op = rv_op_brev8; break; } break; } @@ -1742,8 +1858,11 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 36: switch ((inst >> 20) & 0b11111) { case 0: op = rv_op_zext_h; break; + default: op = rv_op_pack; break; } break; + case 39: op = rv_op_packh; break; + case 41: op = rv_op_clmul; break; case 42: op = rv_op_clmulr; break; case 43: op = rv_op_clmulh; break; @@ -1755,6 +1874,12 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 132: op = rv_op_sh2add; break; case 134: op = rv_op_sh3add; break; case 161: op = rv_op_bset; break; + case 162: op = rv_op_xperm4; break; + case 164: op = rv_op_xperm8; break; + case 200: op = rv_op_aes64es; break; + case 216: op = rv_op_aes64esm; break; + case 232: op = rv_op_aes64ds; break; + case 248: op = rv_op_aes64dsm; break; case 256: op = rv_op_sub; break; case 260: op = rv_op_xnor; break; case 261: op = rv_op_sra; break; @@ -1762,9 +1887,24 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 263: op = rv_op_andn; break; case 289: op = rv_op_bclr; break; case 293: op = rv_op_bext; break; + case 320: op = rv_op_sha512sum0r; break; + case 328: op = rv_op_sha512sum1r; break; + case 336: op = rv_op_sha512sig0l; break; + case 344: op = rv_op_sha512sig1l; break; + case 368: op = rv_op_sha512sig0h; break; + case 376: op = rv_op_sha512sig1h; break; case 385: op = rv_op_rol; break; case 386: op = rv_op_ror; break; case 417: op = rv_op_binv; break; + case 504: op = rv_op_aes64ks2; break; + } + switch ((inst >> 25) & 0b0011111) { + case 17: op = rv_op_aes32esi; break; + case 19: op = rv_op_aes32esmi; break; + case 21: op = rv_op_aes32dsi; break; + case 23: op = rv_op_aes32esmi; break; + case 24: op = rv_op_sm4ed; break; + case 26: op = rv_op_sm4ks; break; } break; case 13: op = rv_op_lui; break; @@ -1782,6 +1922,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 36: switch ((inst >> 20) & 0b11111) { case 0: op = rv_op_zext_h; break; + default: op = rv_op_packw; break; } break; case 130: op = rv_op_sh1add_uw; break; @@ -2374,6 +2515,16 @@ static uint32_t operand_cimmq(rv_inst inst) ((inst << 57) >> 62) << 6; } +static uint32_t operand_bs(rv_inst inst) +{ + return (inst << 32) >> 62; +} + +static uint32_t operand_rnum(rv_inst inst) +{ + return (inst << 40) >> 60; +} + /* decode operands */ static void decode_inst_operands(rv_decode *dec) @@ -2653,6 +2804,16 @@ static void decode_inst_operands(rv_decode *dec) dec->rs2 = operand_crs2(inst); dec->imm = operand_cimmsqsp(inst); break; + case rv_codec_k_bs: + dec->rs1 = operand_rs1(inst); + dec->rs2 = operand_rs2(inst); + dec->bs = operand_bs(inst); + break; + case rv_codec_k_rnum: + dec->rd = operand_rd(inst); + dec->rs1 = operand_rs1(inst); + dec->rnum = operand_rnum(inst); + break; }; } @@ -2812,6 +2973,14 @@ static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec) case ')': append(buf, ")", buflen); break; + case 'b': + snprintf(tmp, sizeof(tmp), "%d", dec->bs); + append(buf, tmp, buflen); + break; + case 'n': + snprintf(tmp, sizeof(tmp), "%d", dec->rnum); + append(buf, tmp, buflen); + break; case '0': append(buf, rv_ireg_name_sym[dec->rd], buflen); break; -- 2.17.1 ^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC 6/6] disas/riscv.c: rvk: add disas support for Zbk* and Zk* instructions @ 2021-11-02 3:11 ` liweiwei 0 siblings, 0 replies; 34+ messages in thread From: liweiwei @ 2021-11-02 3:11 UTC (permalink / raw) To: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel Cc: luruibo2000, lustrew, wangjunqiang, lazyparser, liweiwei Signed-off-by: liweiwei <liweiwei@iscas.ac.cn> Signed-off-by: wangjunqiang <wangjunqiang@iscas.ac.cn> --- disas/riscv.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 170 insertions(+), 1 deletion(-) diff --git a/disas/riscv.c b/disas/riscv.c index 793ad14c27..eb1d36d1e5 100644 --- a/disas/riscv.c +++ b/disas/riscv.c @@ -156,6 +156,8 @@ typedef enum { rv_codec_css_swsp, rv_codec_css_sdsp, rv_codec_css_sqsp, + rv_codec_k_bs, + rv_codec_k_rnum, } rv_codec; typedef enum { @@ -521,6 +523,43 @@ typedef enum { rv_op_bclr = 359, rv_op_binv = 360, rv_op_bext = 361, + rv_op_aes32esmi = 362, + rv_op_aes32esi = 363, + rv_op_aes32dsmi = 364, + rv_op_aes32dsi = 365, + rv_op_aes64ks1i = 366, + rv_op_aes64ks2 = 367, + rv_op_aes64im = 368, + rv_op_aes64esm = 369, + rv_op_aes64es = 370, + rv_op_aes64dsm = 371, + rv_op_aes64ds = 372, + rv_op_sha256sig0 = 373, + rv_op_sha256sig1 = 374, + rv_op_sha256sum0 = 375, + rv_op_sha256sum1 = 376, + rv_op_sha512sig0 = 377, + rv_op_sha512sig1 = 378, + rv_op_sha512sum0 = 379, + rv_op_sha512sum1 = 380, + rv_op_sha512sum0r = 381, + rv_op_sha512sum1r = 382, + rv_op_sha512sig0l = 383, + rv_op_sha512sig0h = 384, + rv_op_sha512sig1l = 385, + rv_op_sha512sig1h = 386, + rv_op_sm3p0 = 387, + rv_op_sm3p1 = 388, + rv_op_sm4ed = 389, + rv_op_sm4ks = 390, + rv_op_brev8 = 391, + rv_op_pack = 392, + rv_op_packh = 393, + rv_op_packw = 394, + rv_op_unzip = 395, + rv_op_zip = 396, + rv_op_xperm4 = 397, + rv_op_xperm8 = 398, } rv_op; /* structures */ @@ -540,6 +579,8 @@ typedef struct { uint8_t succ; uint8_t aq; uint8_t rl; + uint8_t bs; + uint8_t rnum; } rv_decode; typedef struct { @@ -615,6 +656,8 @@ static const char rv_freg_name_sym[32][5] = { #define rv_fmt_rd_rs2 "O\t0,2" #define rv_fmt_rs1_offset "O\t1,o" #define rv_fmt_rs2_offset "O\t2,o" +#define rv_fmt_rs1_rs2_bs "O\t1,2,b" +#define rv_fmt_rd_rs1_rnum "O\t0,1,n" /* pseudo-instruction constraints */ @@ -766,6 +809,7 @@ static const rv_comp_data rvcp_csrrw[] = { { rv_op_illegal, NULL } }; + static const rv_comp_data rvcp_csrrs[] = { { rv_op_rdcycle, rvcc_rdcycle }, { rv_op_rdtime, rvcc_rdtime }, @@ -1203,10 +1247,46 @@ const rv_opcode_data opcode_data[] = { { "bclr", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, { "binv", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, { "bext", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "aes32esmi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 }, + { "aes32esi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 }, + { "aes32dsmi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 }, + { "aes32dsi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 }, + { "aes64ks1i", rv_codec_k_rnum, rv_fmt_rd_rs1_rnum, NULL, 0, 0, 0 }, + { "aes64ks2", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "aes64im", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, + { "aes64esm", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "aes64es", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "aes64dsm", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "aes64ds", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha256sig0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, + { "sha256sig1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, + { "sha256sum0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, + { "sha256sum1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, + { "sha512sig0", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha512sig1", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha512sum0", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha512sum1", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha512sum0r", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha512sum1r", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha512sig0l", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha512sig0h", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha512sig1l", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sha512sig1h", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sm3p0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, + { "sm3p1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, + { "sm4ed", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 }, + { "sm4ks", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 }, + { "brev8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, + { "pack", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "packh", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "packw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "unzip", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, + { "zip", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, + { "xperm4", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "xperm8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 } }; /* CSR names */ - static const char *csr_name(int csrno) { switch (csrno) { @@ -1216,6 +1296,7 @@ static const char *csr_name(int csrno) case 0x0003: return "fcsr"; case 0x0004: return "uie"; case 0x0005: return "utvec"; + case 0x0015: return "seed"; case 0x0040: return "uscratch"; case 0x0041: return "uepc"; case 0x0042: return "ucause"; @@ -1594,7 +1675,36 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 1: switch (((inst >> 27) & 0b11111)) { case 0b00000: op = rv_op_slli; break; + case 0b00001: + switch (((inst >> 20) & 0b1111111)) { + case 0b0001111: op = rv_op_zip; break; + } + break; + case 0b00010: + switch (((inst >> 20) & 0b1111111)) { + case 0b0000000: op = rv_op_sha256sum0; break; + case 0b0000001: op = rv_op_sha256sum1; break; + case 0b0000010: op = rv_op_sha256sig0; break; + case 0b0000011: op = rv_op_sha256sig1; break; + case 0b0000100: op = rv_op_sha512sum0; break; + case 0b0000101: op = rv_op_sha512sum1; break; + case 0b0000110: op = rv_op_sha512sig0; break; + case 0b0000111: op = rv_op_sha512sig1; break; + case 0b0001000: op = rv_op_sm3p0; break; + case 0b0001001: op = rv_op_sm3p1; break; + } + break; case 0b00101: op = rv_op_bseti; break; + case 0b00110: + switch (((inst >> 20) & 0b1111111)) { + case 0b0000000: op = rv_op_aes64im; break; + default: + if (((inst >> 24) & 0x111) == 0b001) { + op = rv_op_aes64ks1i; + } + break; + } + break; case 0b01001: op = rv_op_bclri; break; case 0b01101: op = rv_op_binvi; break; case 0b01100: @@ -1615,6 +1725,11 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 5: switch (((inst >> 27) & 0b11111)) { case 0b00000: op = rv_op_srli; break; + case 0b00001: + switch (((inst >> 20) & 0b1111111)) { + case 0b0001111: op = rv_op_unzip; break; + } + break; case 0b00101: op = rv_op_orc_b; break; case 0b01000: op = rv_op_srai; break; case 0b01001: op = rv_op_bexti; break; @@ -1622,6 +1737,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 0b01101: switch ((inst >> 20) & 0b1111111) { case 0b0111000: op = rv_op_rev8; break; + case 0b0000111: op = rv_op_brev8; break; } break; } @@ -1742,8 +1858,11 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 36: switch ((inst >> 20) & 0b11111) { case 0: op = rv_op_zext_h; break; + default: op = rv_op_pack; break; } break; + case 39: op = rv_op_packh; break; + case 41: op = rv_op_clmul; break; case 42: op = rv_op_clmulr; break; case 43: op = rv_op_clmulh; break; @@ -1755,6 +1874,12 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 132: op = rv_op_sh2add; break; case 134: op = rv_op_sh3add; break; case 161: op = rv_op_bset; break; + case 162: op = rv_op_xperm4; break; + case 164: op = rv_op_xperm8; break; + case 200: op = rv_op_aes64es; break; + case 216: op = rv_op_aes64esm; break; + case 232: op = rv_op_aes64ds; break; + case 248: op = rv_op_aes64dsm; break; case 256: op = rv_op_sub; break; case 260: op = rv_op_xnor; break; case 261: op = rv_op_sra; break; @@ -1762,9 +1887,24 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 263: op = rv_op_andn; break; case 289: op = rv_op_bclr; break; case 293: op = rv_op_bext; break; + case 320: op = rv_op_sha512sum0r; break; + case 328: op = rv_op_sha512sum1r; break; + case 336: op = rv_op_sha512sig0l; break; + case 344: op = rv_op_sha512sig1l; break; + case 368: op = rv_op_sha512sig0h; break; + case 376: op = rv_op_sha512sig1h; break; case 385: op = rv_op_rol; break; case 386: op = rv_op_ror; break; case 417: op = rv_op_binv; break; + case 504: op = rv_op_aes64ks2; break; + } + switch ((inst >> 25) & 0b0011111) { + case 17: op = rv_op_aes32esi; break; + case 19: op = rv_op_aes32esmi; break; + case 21: op = rv_op_aes32dsi; break; + case 23: op = rv_op_aes32esmi; break; + case 24: op = rv_op_sm4ed; break; + case 26: op = rv_op_sm4ks; break; } break; case 13: op = rv_op_lui; break; @@ -1782,6 +1922,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 36: switch ((inst >> 20) & 0b11111) { case 0: op = rv_op_zext_h; break; + default: op = rv_op_packw; break; } break; case 130: op = rv_op_sh1add_uw; break; @@ -2374,6 +2515,16 @@ static uint32_t operand_cimmq(rv_inst inst) ((inst << 57) >> 62) << 6; } +static uint32_t operand_bs(rv_inst inst) +{ + return (inst << 32) >> 62; +} + +static uint32_t operand_rnum(rv_inst inst) +{ + return (inst << 40) >> 60; +} + /* decode operands */ static void decode_inst_operands(rv_decode *dec) @@ -2653,6 +2804,16 @@ static void decode_inst_operands(rv_decode *dec) dec->rs2 = operand_crs2(inst); dec->imm = operand_cimmsqsp(inst); break; + case rv_codec_k_bs: + dec->rs1 = operand_rs1(inst); + dec->rs2 = operand_rs2(inst); + dec->bs = operand_bs(inst); + break; + case rv_codec_k_rnum: + dec->rd = operand_rd(inst); + dec->rs1 = operand_rs1(inst); + dec->rnum = operand_rnum(inst); + break; }; } @@ -2812,6 +2973,14 @@ static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec) case ')': append(buf, ")", buflen); break; + case 'b': + snprintf(tmp, sizeof(tmp), "%d", dec->bs); + append(buf, tmp, buflen); + break; + case 'n': + snprintf(tmp, sizeof(tmp), "%d", dec->rnum); + append(buf, tmp, buflen); + break; case '0': append(buf, rv_ireg_name_sym[dec->rd], buflen); break; -- 2.17.1 ^ permalink raw reply related [flat|nested] 34+ messages in thread
end of thread, other threads:[~2021-11-03 7:23 UTC | newest] Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-11-02 3:11 [RFC 0/6] support subsets of scalar crypto extension liweiwei 2021-11-02 3:11 ` liweiwei 2021-11-02 3:11 ` [RFC 1/6] target/riscv: rvk: add flag support for Zbk[bcx] liweiwei 2021-11-02 3:11 ` liweiwei 2021-11-02 14:18 ` Richard Henderson 2021-11-02 14:18 ` Richard Henderson 2021-11-02 15:00 ` liweiwei 2021-11-02 15:00 ` liweiwei 2021-11-02 3:11 ` [RFC 2/6] target/riscv: rvk: add implementation of instructions for Zbk* - reuse partial instructions of Zbb/Zbc extensions - add brev8 packh, unzip, zip, etc liweiwei 2021-11-02 3:11 ` liweiwei 2021-11-02 15:44 ` Richard Henderson 2021-11-02 15:44 ` Richard Henderson 2021-11-03 0:56 ` liweiwei 2021-11-03 0:56 ` liweiwei 2021-11-02 3:11 ` [RFC 3/6] target/riscv: rvk: add flag support for Zk/Zkn/Zknd/Zknd/Zkne/Zknh/Zks/Zksed/Zksh/Zkr liweiwei 2021-11-02 3:11 ` liweiwei 2021-11-02 17:56 ` Richard Henderson 2021-11-02 17:56 ` Richard Henderson 2021-11-03 1:06 ` liweiwei 2021-11-03 1:06 ` liweiwei 2021-11-03 1:21 ` Richard Henderson 2021-11-03 1:21 ` Richard Henderson 2021-11-03 7:22 ` liweiwei 2021-11-03 7:22 ` liweiwei 2021-11-02 3:11 ` [RFC 4/6] target/riscv: rvk: add implementation of instructions for Zk* liweiwei 2021-11-02 3:11 ` liweiwei 2021-11-02 18:56 ` Richard Henderson 2021-11-02 18:56 ` Richard Henderson 2021-11-03 1:08 ` liweiwei 2021-11-03 1:08 ` liweiwei 2021-11-02 3:11 ` [RFC 5/6] target/riscv: rvk: add CSR support for Zkr: - add SEED CSR - add USEED, SSEED fields for MSECCFG CSR liweiwei 2021-11-02 3:11 ` liweiwei 2021-11-02 3:11 ` [RFC 6/6] disas/riscv.c: rvk: add disas support for Zbk* and Zk* instructions liweiwei 2021-11-02 3:11 ` liweiwei
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.