From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789542607580791.6334226115196; Wed, 16 Sep 2026 00:10:07 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jkb-0005dI-6X; Wed, 16 Sep 2026 03:08:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jkX-0005bk-Mb; Wed, 16 Sep 2026 03:08:09 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jkT-0008J2-RH; Wed, 16 Sep 2026 03:08:09 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S3; Wed, 16 Sep 2026 15:08:00 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Yin Zhang , Dajun Huang , Zhiyuan Yang Subject: [PATCH v3 01/19] target/riscv: Add packed SIMD extension state Date: Wed, 16 Sep 2026 07:07:03 +0000 Message-Id: <20260916070721.3279229-2-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S3 X-Coremail-Antispam: 1UD129KBjvJXoW3Ar4xtryfWry8Jw1DAFW3GFg_yoWDGry7pr 4DG39xG3y8Jas7Za93tF1UWF15Ww4kG3ySkws7Ww4IqFW5JrW5GFn7t3y7ZFn8GFZ5Zr43 uF48CryDZr4UAFDanT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUQj14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_Jr4l82xGYIkIc2 x26xkF7I0E14v26r4j6ryUM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_Xr0_Ar1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJw A2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq3wAa w2AFwI0_Jrv_JF1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrV C2j2WlYx0E2Ix0cI8IcVAFwI0_JF0_Jw1lYx0Ex4A2jsIE14v26F4j6r4UJwAm72CE4IkC 6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4IIrI 8v6xkF7I0E8cxan2IY04v7MxkF7I0En4kS14v26r4a6rW5MxAIw28IcxkI7VAKI48JMxC2 0s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI 0_JrI_JrWlx4CE17CEb7AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE 14v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY6xAIw20EY4v20x vaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Cr0_Gr1UMIIF0xvEx4A2jsIEc7CjxVAFwI0_ Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x0pR0oG9UUUUU= X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542608810158500 Content-Type: text/plain; charset="utf-8" Model vxsat with separate Vector/Zve and P-only control paths. When Zve* is present, vxsat follows mstatus.VS/vsstatus.VS; when P is implemented without Zve*, stateen0.VXSAT controls access instead. Record the P-only stateen result in TB flags so cached translations preserve both instruction legality and the illegal-vs-virtual exception class. Co-authored-by: Yin Zhang Co-authored-by: Dajun Huang Co-authored-by: Zhiyuan Yang Signed-off-by: Molly Chen Reviewed-by: Daniel Henrique Barboza Reviewed-by: Nutty Liu Reviewed-by: Chao Liu --- target/riscv/cpu.c | 5 ++-- target/riscv/cpu.h | 8 +++++++ target/riscv/cpu_bits.h | 2 ++ target/riscv/machine.c | 19 +++++++++++++++ target/riscv/tcg/csr.c | 39 +++++++++++++++++++++++++++++-- target/riscv/tcg/tcg-cpu.c | 48 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 117 insertions(+), 4 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 652311ddef2..ea771ac9167 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -47,7 +47,7 @@ /* RISC-V CPU definitions */ static const char riscv_single_letter_exts[] =3D "IEMAFDQCBPVH"; const uint32_t misa_bits[] =3D {RVI, RVE, RVM, RVA, RVF, RVD, RVV, - RVC, RVS, RVU, RVH, RVG, RVB, 0}; + RVC, RVS, RVU, RVH, RVG, RVB, RVP, 0}; #define RISCV_CPU_MVENDORID 0 #define RISCV_CPU_MIMPID 0 /* @@ -1579,7 +1579,8 @@ static const MISAExtInfo misa_ext_info_arr[] =3D { MISA_EXT_INFO(RVH, "h", "Hypervisor"), MISA_EXT_INFO(RVV, "v", "Vector operations"), MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"), - MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)") + MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)"), + MISA_EXT_INFO(RVP, "x-p", "Packed-SIMD instructions") }; =20 static void riscv_cpu_validate_misa_mxl(RISCVCPUClass *mcc) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index c2138dbd4ba..23235b4cefb 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -70,6 +70,7 @@ typedef struct CPUArchState CPURISCVState; #define RVG RV('G') #define RVB RV('B') #define RVX RV('X') +#define RVP RV('P') =20 extern const uint32_t misa_bits[]; const char *riscv_get_misa_ext_name(uint32_t bit); @@ -748,6 +749,13 @@ FIELD(TB_FLAGS, PM_SIGNEXTEND, 31, 1) FIELD(EXT_TB_FLAGS, MISA_EXT, 0, 32) FIELD(EXT_TB_FLAGS, ALTFMT, 32, 1) FIELD(EXT_TB_FLAGS, BIG_ENDIAN, 33, 1) +FIELD(EXT_TB_FLAGS, P_VXSAT_EXCP, 34, 2) + +enum { + P_VXSAT_EXCP_NONE, + P_VXSAT_EXCP_ILLEGAL, + P_VXSAT_EXCP_VIRTUAL, +}; =20 #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index c01050ce2b6..22774a3ec36 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -355,6 +355,8 @@ #define SMSTATEEN0_CS (1ULL << 0) #define SMSTATEEN0_FCSR (1ULL << 1) #define SMSTATEEN0_JVT (1ULL << 2) +/* Packed-SIMD draft: enable access to vxsat when misa.V =3D 0. */ +#define SMSTATEEN0_VXSAT (1ULL << 3) #define SMSTATEEN0_CTR (1ULL << 54) #define SMSTATEEN0_P1P13 (1ULL << 56) #define SMSTATEEN0_HSCONTXT (1ULL << 57) diff --git a/target/riscv/machine.c b/target/riscv/machine.c index bf203bffcef..9d01236dd5d 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -160,6 +160,24 @@ static const VMStateDescription vmstate_vector =3D { } }; =20 +static bool p_vxsat_needed(void *opaque) +{ + RISCVCPU *cpu =3D opaque; + + return riscv_has_ext(&cpu->env, RVP) && !cpu->cfg.ext_zve32x; +} + +static const VMStateDescription vmstate_p_vxsat =3D { + .name =3D "cpu/p-vxsat", + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D p_vxsat_needed, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT8(env.vxsat, RISCVCPU), + VMSTATE_END_OF_LIST() + } +}; + static bool pointermasking_needed(void *opaque) { return false; @@ -561,6 +579,7 @@ const VMStateDescription vmstate_riscv_cpu =3D { &vmstate_pmp, &vmstate_hyper, &vmstate_vector, + &vmstate_p_vxsat, &vmstate_pointermasking, &vmstate_rv128, #ifdef CONFIG_KVM diff --git a/target/riscv/tcg/csr.c b/target/riscv/tcg/csr.c index bd4b6dc114b..eefb487ca21 100644 --- a/target/riscv/tcg/csr.c +++ b/target/riscv/tcg/csr.c @@ -109,6 +109,24 @@ static RISCVException vs(CPURISCVState *env, int csrno) return RISCV_EXCP_ILLEGAL_INST; } =20 +/* vxsat is also architectural state when P is implemented without Zve*. */ +static RISCVException vxsat(CPURISCVState *env, int csrno) +{ + if (riscv_cpu_cfg(env)->ext_zve32x) { + return vs(env, csrno); + } + + if (riscv_has_ext(env, RVP)) { +#if !defined(CONFIG_USER_ONLY) + return smstateen_acc_ok(env, 0, SMSTATEEN0_VXSAT); +#else + return RISCV_EXCP_NONE; +#endif + } + + return RISCV_EXCP_ILLEGAL_INST; +} + static RISCVException ctr(CPURISCVState *env, int csrno) { #if !defined(CONFIG_USER_ONLY) @@ -1013,7 +1031,12 @@ static RISCVException write_vxsat(CPURISCVState *env= , int csrno, target_ulong val, uintptr_t ra) { #if !defined(CONFIG_USER_ONLY) - env->mstatus |=3D MSTATUS_VS; + if (riscv_cpu_cfg(env)->ext_zve32x) { + env->mstatus |=3D MSTATUS_VS; + if (env->virt_enabled) { + env->mstatus_hs |=3D MSTATUS_VS; + } + } #endif env->vxsat =3D val & BIT(0); return RISCV_EXCP_NONE; @@ -3512,6 +3535,10 @@ static RISCVException write_mstateen0(CPURISCVState = *env, int csrno, target_ulong new_val, uintptr_t ra) { uint64_t wr_mask =3D SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG; + + if (riscv_has_ext(env, RVP) && !riscv_cpu_cfg(env)->ext_zve32x) { + wr_mask |=3D SMSTATEEN0_VXSAT; + } if (!riscv_has_ext(env, RVF)) { wr_mask |=3D SMSTATEEN0_FCSR; } @@ -3635,6 +3662,10 @@ static RISCVException write_hstateen0(CPURISCVState = *env, int csrno, { uint64_t wr_mask =3D SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG; =20 + if (riscv_has_ext(env, RVP) && !riscv_cpu_cfg(env)->ext_zve32x) { + wr_mask |=3D SMSTATEEN0_VXSAT; + } + if (!riscv_has_ext(env, RVF)) { wr_mask |=3D SMSTATEEN0_FCSR; } @@ -3764,6 +3795,10 @@ static RISCVException write_sstateen0(CPURISCVState = *env, int csrno, { uint64_t wr_mask =3D 0; =20 + if (riscv_has_ext(env, RVP) && !riscv_cpu_cfg(env)->ext_zve32x) { + wr_mask |=3D SMSTATEEN0_VXSAT; + } + if (!riscv_has_ext(env, RVF)) { wr_mask |=3D SMSTATEEN0_FCSR; } @@ -5934,7 +5969,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] =3D { [CSR_FCSR] =3D { "fcsr", fs, read_fcsr, write_fcsr }, /* Vector CSRs */ [CSR_VSTART] =3D { "vstart", vs, read_vstart, write_vstart }, - [CSR_VXSAT] =3D { "vxsat", vs, read_vxsat, write_vxsat }, + [CSR_VXSAT] =3D { "vxsat", vxsat, read_vxsat, write_vxsat }, [CSR_VXRM] =3D { "vxrm", vs, read_vxrm, write_vxrm }, [CSR_VCSR] =3D { "vcsr", vs, read_vcsr, write_vcsr }, [CSR_VL] =3D { "vl", vs, read_vl }, diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c index b68160af830..3e72e2ffd7f 100644 --- a/target/riscv/tcg/tcg-cpu.c +++ b/target/riscv/tcg/tcg-cpu.c @@ -158,6 +158,8 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *c= s) fs =3D EXT_STATUS_DIRTY; vs =3D EXT_STATUS_DIRTY; #else + RISCVException p_vxsat_excp; + flags =3D FIELD_DP32(flags, TB_FLAGS, PRIV, env->priv); =20 flags |=3D riscv_env_mmu_index(env, 0); @@ -180,6 +182,23 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *= cs) ? EXT_STATUS_DIRTY : EXT_STATUS_DISABLED; } =20 + /* + * Without Zve*, all P instructions in the OP-32 and OP-IMM-32 + * spaces are controlled by stateen0.VXSAT. Preserve the exception + * class in the TB flags so translated code can distinguish an illegal + * instruction from a virtual-instruction exception. + */ + p_vxsat_excp =3D smstateen_acc_ok(env, 0, SMSTATEEN0_VXSAT); + if (riscv_has_ext(env, RVP) && !riscv_cpu_cfg(env)->ext_zve32x) { + if (p_vxsat_excp =3D=3D RISCV_EXCP_VIRT_INSTRUCTION_FAULT) { + ext_flags =3D FIELD_DP64(ext_flags, EXT_TB_FLAGS, P_VXSAT_EXCP, + P_VXSAT_EXCP_VIRTUAL); + } else if (p_vxsat_excp !=3D RISCV_EXCP_NONE) { + ext_flags =3D FIELD_DP64(ext_flags, EXT_TB_FLAGS, P_VXSAT_EXCP, + P_VXSAT_EXCP_ILLEGAL); + } + } + if ((cpu->cfg.debug || cpu->cfg.ext_sdtrig) && !icount_enabled()) { flags =3D FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enab= led); @@ -529,6 +548,28 @@ static void riscv_cpu_validate_b(RISCVCPU *cpu) } } =20 +static void riscv_cpu_validate_p(RISCVCPU *cpu, Error **errp) +{ + CPURISCVState *env =3D &cpu->env; + + if (!riscv_has_ext(env, RVP)) { + return; + } + + if (riscv_cpu_mxl(env) !=3D MXL_RV32 && + riscv_cpu_mxl(env) !=3D MXL_RV64) { + error_setg(errp, "P extension requires RV32 or RV64"); + return; + } + + if (!(cpu->cfg.ext_zmmul && cpu->cfg.ext_zba && cpu->cfg.ext_zbb && + cpu->cfg.ext_zbkb)) { + error_setg(errp, "P extension requires zmmul, zba, zbb and zbkb " + "extensions"); + return; + } +} + /* * Check consistency between chosen extensions while setting * cpu->cfg accordingly. @@ -611,6 +652,12 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, = Error **errp) return; } =20 + riscv_cpu_validate_p(cpu, &local_err); + if (local_err !=3D NULL) { + error_propagate(errp, local_err); + return; + } + riscv_cpu_validate_v(env, &cpu->cfg, &local_err); if (local_err !=3D NULL) { error_propagate(errp, local_err); @@ -1413,6 +1460,7 @@ static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = =3D { MISA_CFG(RVV, false), MISA_CFG(RVG, false), MISA_CFG(RVB, false), + MISA_CFG(RVP, false), }; =20 /* --=20 2.34.1 From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789542616979456.71799562822855; Wed, 16 Sep 2026 00:10:16 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jki-0005iv-Ik; Wed, 16 Sep 2026 03:08:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jkb-0005dM-1Q; Wed, 16 Sep 2026 03:08:13 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jkT-0008J7-Sg; Wed, 16 Sep 2026 03:08:12 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S4; Wed, 16 Sep 2026 15:08:00 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 02/19] target/riscv: Add packed SIMD helper framework Date: Wed, 16 Sep 2026 07:07:04 +0000 Message-Id: <20260916070721.3279229-3-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S4 X-Coremail-Antispam: 1UD129KBjvAXoWDWr18WF45tw1kWFW3tFyUGFg_yoW7Xry3uo W7Gw4fX3yxXryxCrWkZwn7XanruFW5uw15ZrWYvryfZ3W7W3WakFyfAw4kXa1Fya12qrW7 JrZ7Wwn8KasI9rn3n29KB7ZKAUJUUUUr529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUYu7AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r15M28IrcIa0x kI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l84AC jcxK6xIIjxv20xvE14v26ryj6F1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4UJVWxJr 1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE3s1l n4kS14v26r1Y6r17M2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F4 0Ex7xfMcIj6xIIjxv20xvE14v26r126r1DMcIj6I8E87Iv67AKxVWxJVW8Jr1lOx8S6xCa FVCjc4AY6r1j6r4UM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2kIc2 xKxwCY1x0262kKe7AKxVWUtVW8ZwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E 14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIx AIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1lIxAI cVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26F4j6r4UJwCI42IY6I8E87 Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7VUb_OzDUUUUU== X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542618482158500 Content-Type: text/plain; charset="utf-8" Add the common helper infrastructure used to implement packed SIMD operations. Introduce the GEN_PSIMD_* macros to abstract the recurring lane-wise loops used by psimd instruction emulation. These macros centralize element extraction, per-lane operation and result insertion, allowing individual helpers to focus on instruction-specific behavior. Also provide common arithmetic, saturation, rounding and overflow handling facilities, and add psimd_helper.c to the RISC-V TCG build. Signed-off-by: Molly Chen --- target/riscv/tcg/meson.build | 3 +- target/riscv/tcg/psimd_helper.c | 2046 +++++++++++++++++++++++++++++++ 2 files changed, 2048 insertions(+), 1 deletion(-) create mode 100644 target/riscv/tcg/psimd_helper.c diff --git a/target/riscv/tcg/meson.build b/target/riscv/tcg/meson.build index a05ab642f41..cc438d7c0d2 100644 --- a/target/riscv/tcg/meson.build +++ b/target/riscv/tcg/meson.build @@ -15,7 +15,8 @@ riscv_ss.add(files( 'vcrypto_helper.c', 'vector_helper.c', 'vector_internals.c', - 'zce_helper.c')) + 'zce_helper.c', + 'psimd_helper.c')) =20 =20 riscv_system_ss.add(files( diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helpe= r.c new file mode 100644 index 00000000000..488deeadd96 --- /dev/null +++ b/target/riscv/tcg/psimd_helper.c @@ -0,0 +1,2046 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* RISC-V Packed SIMD Extension Helpers for QEMU. */ +/* Copyright (C) 2026 ISRC ISCAS. */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "qemu/bitops.h" +#include "qemu/host-utils.h" +#include "exec/helper-proto.h" +#include "fpu/softfloat.h" +#include "internals.h" + + +/* Helper macros */ + +/* Element count calculations */ +#define ELEMS_B(target) (sizeof(target) * 8 / 8) /* byte elements count= */ +#define ELEMS_H(target) (sizeof(target) * 8 / 16) +#define ELEMS_W(target) (sizeof(target) * 8 / 32) /* word elements count= */ +#define ELEMS_D(target) (sizeof(target) * 8 / 64) + +/* Element extraction macros - unsigned to avoid sign extension */ +#define EXTRACT8(val, idx) extract64((val), (idx) * 8, 8) +#define EXTRACT16(val, idx) extract64((val), (idx) * 16, 16) +#define EXTRACT32(val, idx) extract64((val), (idx) * 32, 32) +#define EXTRACT64(val, idx) extract64((val), (idx) * 64, 64) + +/* Element insertion macros */ +#define INSERT8(val, res, idx) \ + ((val) | ((target_ulong)(uint8_t)(res) << ((idx) * 8))) +#define INSERT16(val, res, idx) \ + ((val) | ((target_ulong)(uint16_t)(res) << ((idx) * 16))) +#define INSERT32(val, res, idx) \ + ((val) | ((target_ulong)(uint32_t)(res) << ((idx) * 32))) +#define INSERT32_64(val, res, idx) \ + ((val) | ((uint64_t)(uint32_t)(res) << ((idx) * 32))) +#define INSERT64(val, res, idx) \ + ((val) | ((uint64_t)(res) << ((idx) * 64))) + +/* Saturation constants */ +static const int8_t SAT_MAX_B =3D 127; +static const int8_t SAT_MIN_B =3D -128; +static const int16_t SAT_MAX_H =3D 32767; +static const int16_t SAT_MIN_H =3D -32768; +static const int32_t SAT_MAX_W =3D 2147483647; +static const int32_t SAT_MIN_W =3D -2147483648LL; +static const uint8_t USAT_MAX_B =3D 255; +static const uint16_t USAT_MAX_H =3D 65535; +static const uint32_t USAT_MAX_W =3D 4294967295U; + +/** + * Saturation helper functions + * Returns saturated value and sets *sat if saturation occurred + */ +static inline int8_t signed_saturate_b(int32_t val, int *sat) +{ + if (val > SAT_MAX_B) { + *sat =3D 1; + return SAT_MAX_B; + } + if (val < SAT_MIN_B) { + *sat =3D 1; + return SAT_MIN_B; + } + return (int8_t)val; +} + +static inline int16_t signed_saturate_h(int32_t val, int *sat) +{ + if (val > SAT_MAX_H) { + *sat =3D 1; + return SAT_MAX_H; + } + if (val < SAT_MIN_H) { + *sat =3D 1; + return SAT_MIN_H; + } + return (int16_t)val; +} + +static inline int32_t signed_saturate_w(int64_t val, int *sat) +{ + if (val > SAT_MAX_W) { + *sat =3D 1; + return SAT_MAX_W; + } + if (val < SAT_MIN_W) { + *sat =3D 1; + return SAT_MIN_W; + } + return (int32_t)val; +} + +static inline uint8_t unsigned_saturate_b(uint32_t val, int *sat) +{ + if (val > USAT_MAX_B) { + *sat =3D 1; + return USAT_MAX_B; + } + return (uint8_t)val; +} + +static inline uint16_t unsigned_saturate_h(uint32_t val, int *sat) +{ + if (val > USAT_MAX_H) { + *sat =3D 1; + return USAT_MAX_H; + } + return (uint16_t)val; +} + +static inline uint32_t unsigned_saturate_w(uint64_t val, int *sat) +{ + if (val > USAT_MAX_W) { + *sat =3D 1; + return USAT_MAX_W; + } + return (uint32_t)val; +} + +static inline target_ulong psimd_abdsumu_b(target_ulong rs1, + target_ulong rs2, + target_ulong sum) +{ + int elems =3D ELEMS_B(rs1); + + for (int i =3D 0; i < elems; i++) { + uint8_t e1 =3D EXTRACT8(rs1, i); + uint8_t e2 =3D EXTRACT8(rs2, i); + uint8_t diff =3D (e1 > e2) ? (e1 - e2) : (e2 - e1); + sum +=3D diff; + } + + return sum; +} + +#define PSIMD_DO_ADD(N, M) ((N) + (M)) +#define PSIMD_DO_SUB(N, M) ((N) - (M)) +#define PSIMD_DO_ABD(N, M) ((N) >=3D (M) ? (N) - (M) : (M) - (N)) +#define PSIMD_DO_EQ_MASK(N, M) ((N) =3D=3D (M) ? -1 : 0) +#define PSIMD_DO_LT_MASK(N, M) ((N) < (M) ? -1 : 0) +#define PSIMD_DO_MIN(N, M) ((N) < (M) ? (N) : (M)) +#define PSIMD_DO_MAX(N, M) ((N) > (M) ? (N) : (M)) +#define PSIMD_DO_SLL(N, M) ((uint64_t)(N) << (M)) +#define PSIMD_DO_SRL(N, M) ((N) >> (M)) +#define PSIMD_DO_SRA(N, M) ((N) >> (M)) + +/* + * The GEN_PSIMD_* macros below build one helper from a lane operation. + * RTYPE is the integer type holding the complete packed operand/result; + * ETYPE/STYPE specifies how an input lane is interpreted, and WTYPE/DTYPE + * is a wider intermediate type. These types determine whether extension + * and subsequent arithmetic are signed or unsigned. EXTRACT, INSERT, and + * ELEMS describe the lane layout. + */ + +/* + * Generate a lane-wise binary-operation helper. rs1 and rs2 contain the + * source lanes; OP combines corresponding lanes. Used for PADD, PSUB, + * PABD, comparison, minimum, and maximum instructions. + */ +#define GEN_PSIMD_BINOP(NAME, RTYPE, STYPE, DTYPE, EXTRACT, INSERT, \ + ELEMS, OP) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + STYPE e1 =3D (STYPE)EXTRACT(rs1, i); = \ + STYPE e2 =3D (STYPE)EXTRACT(rs2, i); = \ + DTYPE res =3D (DTYPE)OP(e1, e2); = \ + rd =3D INSERT(rd, res, i); = \ + } \ + return rd; \ +} + +/* + * Generate a packed-by-scalar binary-operation helper. rs1 contains the + * source lanes and rs2 lane 0 is applied to every lane. Used for PADD.BS, + * PADD.HS, and PADD.WS. + */ +#define GEN_PSIMD_BINOP_SCALAR(NAME, RTYPE, ETYPE, EXTRACT, INSERT, \ + ELEMS, OP) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + ETYPE e2 =3D (ETYPE)EXTRACT(rs2, 0); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE e1 =3D (ETYPE)EXTRACT(rs1, i); = \ + ETYPE res =3D OP(e1, e2); = \ + rd =3D INSERT(rd, res, i); = \ + } \ + return rd; \ +} + +/* + * Generate a packed shift helper. rs1 contains the lanes and rs2 carries + * the immediate or scalar shift amount, masked by SHMASK. Used for the + * PSLL[I], PSRL[I], and PSRA[I] instruction families. + */ +#define GEN_PSIMD_SHIFTOP(NAME, RTYPE, STYPE, DTYPE, EXTRACT, INSERT, \ + ELEMS, SHMASK, OP) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + uint8_t shamt =3D rs2 & (SHMASK); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + STYPE e1 =3D (STYPE)EXTRACT(rs1, i); = \ + DTYPE res =3D (DTYPE)OP(e1, shamt); = \ + rd =3D INSERT(rd, res, i); = \ + } \ + return rd; \ +} + +/* + * Generate a signed saturating immediate left-shift helper. The rs1 oper= and + * contains the elements to shift, and rs2 carries the decoded unsigned + * immediate shift amount. Each element is left-shifted and saturated to + * its signed range; vxsat is set if any element saturates. This macro is + * used for PSSLAI.H, PSSLAI.W, and SSLAI. + */ +#define GEN_PSIMD_SAT_SHIFTOP(NAME, RTYPE, ETYPE, WTYPE, EXTRACT, INSERT, \ + ELEMS, SHMASK, SAT_FN) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + int sat =3D 0; = \ + uint8_t shamt =3D rs2 & (SHMASK); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE e1 =3D (ETYPE)EXTRACT(rs1, i); = \ + WTYPE shifted =3D (WTYPE)e1 * ((WTYPE)1 << shamt); = \ + ETYPE res =3D SAT_FN(shifted, &sat); = \ + rd =3D INSERT(rd, res, i); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +/* + * Generate a rounded arithmetic-right-shift helper. rs1 contains signed + * lanes and rs2 carries the decoded immediate; zero leaves rs1 unchanged. + * Used for PSRARI.H, PSRARI.W, and SRARI. + */ +#define GEN_PSIMD_ROUND_SRAI(NAME, RTYPE, ETYPE, WTYPE, EXTRACT, INSERT, \ + ELEMS, SHMASK) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + uint8_t shamt =3D rs2 & (SHMASK); = \ + \ + if (shamt =3D=3D 0) { = \ + return rs1; \ + } \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE e1 =3D (ETYPE)EXTRACT(rs1, i); = \ + WTYPE rounded =3D (((WTYPE)e1 >> (shamt - 1)) + 1) >> 1; = \ + rd =3D INSERT(rd, (ETYPE)rounded, i); = \ + } \ + return rd; \ +} + +/* + * Generate a saturating lane-wise binary-operation helper. rs1 and rs2 + * contain corresponding source lanes; SAT_FN clamps OP's widened result a= nd + * sets vxsat on saturation. Used for the signed/unsigned PSADD and signed + * PSSUB families, plus SADD, SADDU, and SSUB. + */ +#define GEN_PSIMD_SAT_BINOP(NAME, RTYPE, ETYPE, WTYPE, EXTRACT, INSERT, \ + ELEMS, OP, SAT_FN) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + int sat =3D 0; = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE e1 =3D (ETYPE)EXTRACT(rs1, i); = \ + ETYPE e2 =3D (ETYPE)EXTRACT(rs2, i); = \ + WTYPE val =3D OP((WTYPE)e1, (WTYPE)e2); = \ + ETYPE res =3D SAT_FN(val, &sat); = \ + rd =3D INSERT(rd, res, i); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +/* + * Generate an unsigned saturating-subtract helper. rs1 and rs2 contain + * corresponding unsigned lanes; underflow produces zero and sets vxsat. + * Used for PSSUBU.B, PSSUBU.H, PSSUBU.W, and SSUBU. + */ +#define GEN_PSIMD_SAT_USUB(NAME, RTYPE, ETYPE, EXTRACT, INSERT, ELEMS) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + int sat =3D 0; = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE e1 =3D (ETYPE)EXTRACT(rs1, i); = \ + ETYPE e2 =3D (ETYPE)EXTRACT(rs2, i); = \ + ETYPE res =3D (e1 >=3D e2) ? (e1 - e2) : 0; = \ + if (e1 < e2) { \ + sat =3D 1; = \ + } \ + rd =3D INSERT(rd, res, i); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +/* + * Generate a lane-wise halving add/subtract helper. rs1 and rs2 contain + * corresponding lanes; OP runs in WTYPE before the result is shifted right + * by one. Signed results therefore round toward negative infinity. Used + * for the signed and unsigned PAADD/PASUB families and scalar AADD/AADDU + * and ASUB/ASUBU. + */ +#define GEN_PSIMD_AVG_BINOP(NAME, RTYPE, ETYPE, WTYPE, EXTRACT, INSERT, \ + ELEMS, OP) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + WTYPE e1 =3D (WTYPE)(ETYPE)EXTRACT(rs1, i); = \ + WTYPE e2 =3D (WTYPE)(ETYPE)EXTRACT(rs2, i); = \ + ETYPE res =3D (ETYPE)(OP(e1, e2) >> 1); = \ + rd =3D INSERT(rd, res, i); = \ + } \ + return rd; \ +} + +/* + * Generate a lane-wise shifted-add helper. rs1 supplies the lanes shifted + * left by SHAMT and rs2 supplies the addends. Used for PSH1ADD.H and + * PSH1ADD.W. + */ +#define GEN_PSIMD_SHADD(NAME, RTYPE, ETYPE, EXTRACT, INSERT, ELEMS, \ + SHAMT) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE e1 =3D (ETYPE)EXTRACT(rs1, i); = \ + ETYPE e2 =3D (ETYPE)EXTRACT(rs2, i); = \ + ETYPE res =3D (e1 << (SHAMT)) + e2; = \ + rd =3D INSERT(rd, res, i); = \ + } \ + return rd; \ +} + +/* + * Generate a saturating shifted-add helper. rs1 supplies signed lanes to + * shift by SHAMT and rs2 supplies addends; out-of-range results set vxsat. + * Used for PSSH1SADD.H, PSSH1SADD.W, and SSH1SADD. + */ +#define GEN_PSIMD_SAT_SHADD(NAME, RTYPE, ETYPE, WTYPE, EXTRACT, INSERT, \ + ELEMS, SHAMT, SH_MIN, SH_MAX, SAT_MIN, \ + SAT_MAX, SAT_FN) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + int sat =3D 0; = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE e1 =3D (ETYPE)EXTRACT(rs1, i); = \ + ETYPE e2 =3D (ETYPE)EXTRACT(rs2, i); = \ + WTYPE shifted; \ + \ + if (e1 > (SH_MAX) || e1 < (SH_MIN)) { \ + shifted =3D (e1 < 0) ? (SAT_MIN) : (SAT_MAX); = \ + sat =3D 1; = \ + } else { \ + shifted =3D (WTYPE)e1 * ((WTYPE)1 << (SHAMT)); = \ + } \ + \ + WTYPE sum =3D shifted + e2; = \ + ETYPE res =3D SAT_FN(sum, &sat); = \ + rd =3D INSERT(rd, res, i); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +/* + * Generate a helper that saturates signed source elements to a signed + * immediate-selected width. rs1 contains the source elements, and imm + * specifies the signed range [-2^imm, 2^imm - 1]. Values outside this ra= nge + * are clamped and set vxsat. Used for PSATI.H, PSATI.W, and SATI. + */ +#define GEN_PSIMD_SATI(NAME, RTYPE, ETYPE, WTYPE, EXTRACT, INSERT, \ + ELEMS, IMMMASK) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE imm) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + int range =3D (imm & (IMMMASK)) + 1; = \ + uint64_t sign =3D UINT64_C(1) << (range - 1); = \ + WTYPE max =3D (WTYPE)(sign - 1); = \ + WTYPE min =3D (range =3D=3D 64) ? INT64_MIN : -(WTYPE)sign; = \ + int sat =3D 0; = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE e1 =3D (ETYPE)EXTRACT(rs1, i); = \ + ETYPE res; \ + \ + if (e1 > max) { \ + res =3D max; = \ + sat =3D 1; = \ + } else if (e1 < min) { \ + res =3D min; = \ + sat =3D 1; = \ + } else { \ + res =3D e1; = \ + } \ + \ + rd =3D INSERT(rd, res, i); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +/* + * Generate a helper that saturates signed source elements to an unsigned + * immediate-selected width. rs1 contains the source elements, and imm + * specifies the unsigned range [0, 2^imm - 1]. Values outside this range + * are clamped and set vxsat. Used for PUSATI.H, PUSATI.W, and USATI. + */ +#define GEN_PSIMD_USATI(NAME, RTYPE, ETYPE, UTYPE, WTYPE, EXTRACT, \ + INSERT, ELEMS, ONE) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE imm) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + WTYPE max =3D ((WTYPE)(ONE) << imm) - 1; = \ + int sat =3D 0; = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE e1 =3D (ETYPE)EXTRACT(rs1, i); = \ + ETYPE res; \ + \ + if (e1 < 0) { \ + res =3D 0; = \ + sat =3D 1; = \ + } else if ((UTYPE)e1 > max) { \ + res =3D max; = \ + sat =3D 1; = \ + } else { \ + res =3D e1; = \ + } \ + \ + rd =3D INSERT(rd, res, i); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +/* + * Generate a packed saturating signed-absolute-value helper. rs1 contains + * signed source elements; an element equal to MINVAL is clamped to MAXVAL + * and sets vxsat. Used for PSABS.B and PSABS.H. + */ +#define GEN_PSIMD_ABS(NAME, RTYPE, ETYPE, EXTRACT, INSERT, ELEMS, \ + MINVAL, MAXVAL) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + int sat =3D 0; = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE e1 =3D (ETYPE)EXTRACT(rs1, i); = \ + ETYPE res; \ + \ + if (e1 =3D=3D (MINVAL)) { = \ + res =3D (MAXVAL); = \ + sat =3D 1; = \ + } else if (e1 < 0) { \ + res =3D -e1; = \ + } else { \ + res =3D e1; = \ + } \ + \ + rd =3D INSERT(rd, res, i); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +/* + * Generate a scalar absolute-value helper. rs1 supplies the signed scala= r; + * UTYPE performs negation without signed-overflow undefined behavior. Us= ed + * for ABS and ABSW. + */ +#define GEN_PSIMD_SCALAR_ABS(NAME, RTYPE, STYPE, UTYPE) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1) \ +{ \ + STYPE value =3D (STYPE)rs1; = \ + UTYPE result =3D (UTYPE)value; = \ + \ + if (value < 0) { \ + result =3D (UTYPE)0 - result; = \ + } \ + return (RTYPE)(STYPE)result; \ +} + +/* + * Generate a signed bidirectional saturating-shift helper. rs1 contains + * signed lanes and the low signed byte of rs2 selects left (nonnegative) = or + * arithmetic right (negative) shift. Used for PSSHA.HS, PSSHA.WS, and SS= HA. + */ +#define GEN_PSIMD_VAR_SSHA(NAME, RTYPE, ETYPE, WTYPE, EXTRACT, INSERT, \ + ELEMS, BITS, SAT_FN) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + int sat =3D 0; = \ + int8_t shamt =3D (int8_t)(rs2 & 0xff); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE e1 =3D (ETYPE)EXTRACT(rs1, i); = \ + ETYPE res; \ + \ + if (shamt >=3D 0) { = \ + int left =3D (shamt >=3D (BITS)) ? (BITS) : shamt; = \ + WTYPE shifted =3D (WTYPE)e1 * ((WTYPE)1 << left); = \ + res =3D SAT_FN(shifted, &sat); = \ + } else { \ + int right =3D -shamt; = \ + if (right >=3D (BITS)) { = \ + res =3D (e1 < 0) ? -1 : 0; = \ + } else { \ + res =3D e1 >> right; = \ + } \ + } \ + \ + rd =3D INSERT(rd, res, i); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +/* + * Generate a signed bidirectional saturating/rounding-shift helper. rs1 + * contains signed lanes and the low signed byte of rs2 selects saturating + * left or rounded right shift. Used for PSSHAR.HS, PSSHAR.WS, and SSHAR. + */ +#define GEN_PSIMD_VAR_SSHAR(NAME, RTYPE, ETYPE, WTYPE, EXTRACT, INSERT, \ + ELEMS, BITS, SAT_MIN, SAT_MAX, SAT_FN) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + int sat =3D 0; = \ + int8_t shamt =3D (int8_t)(rs2 & 0xff); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE e1 =3D (ETYPE)EXTRACT(rs1, i); = \ + ETYPE res; \ + \ + if (shamt >=3D 0) { = \ + if (shamt >=3D (BITS)) { = \ + if (e1 =3D=3D 0) { = \ + res =3D 0; = \ + } else if (e1 > 0) { \ + res =3D (SAT_MAX); = \ + sat =3D 1; = \ + } else { \ + res =3D (SAT_MIN); = \ + sat =3D 1; = \ + } \ + } else { \ + WTYPE shifted =3D (WTYPE)e1 * ((WTYPE)1 << shamt); = \ + res =3D SAT_FN(shifted, &sat); = \ + } \ + } else { \ + int right =3D -shamt; = \ + if (right >=3D (BITS)) { = \ + res =3D 0; = \ + } else { \ + WTYPE rounded =3D (((WTYPE)e1 >> (right - 1)) + 1) >> 1; = \ + res =3D (ETYPE)rounded; = \ + } \ + } \ + \ + rd =3D INSERT(rd, res, i); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +/* + * Generate an unsigned bidirectional saturating-shift helper. rs1 contai= ns + * unsigned lanes and the low signed byte of rs2 selects saturating left or + * logical right shift. Used for PSSHL.HS, PSSHL.WS, and SSHL. + */ +#define GEN_PSIMD_VAR_USHL(NAME, RTYPE, ETYPE, WTYPE, EXTRACT, INSERT, \ + ELEMS, BITS, SAT_FN) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + int sat =3D 0; = \ + int8_t shamt =3D (int8_t)(rs2 & 0xff); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE e1 =3D (ETYPE)EXTRACT(rs1, i); = \ + ETYPE res; \ + \ + if (shamt >=3D 0) { = \ + WTYPE shifted =3D (shamt >=3D (BITS)) ? = \ + ((WTYPE)e1 << (BITS)) : \ + ((WTYPE)e1 << shamt); \ + res =3D SAT_FN(shifted, &sat); = \ + } else { \ + int right =3D -shamt; = \ + if (right >=3D (BITS)) { = \ + res =3D 0; = \ + } else { \ + res =3D e1 >> right; = \ + } \ + } \ + \ + rd =3D INSERT(rd, res, i); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +/* + * Generate an unsigned bidirectional saturating/rounding-shift helper. r= s1 + * contains unsigned lanes and the low signed byte of rs2 selects saturati= ng + * left or rounded logical right shift. Used for PSSHLR.HS, PSSHLR.WS, and + * SSHLR. + */ +#define GEN_PSIMD_VAR_USHLR(NAME, RTYPE, ETYPE, WTYPE, EXTRACT, INSERT, \ + ELEMS, BITS, SAT_FN) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + int sat =3D 0; = \ + int8_t shamt =3D (int8_t)(rs2 & 0xff); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE e1 =3D (ETYPE)EXTRACT(rs1, i); = \ + ETYPE res; \ + \ + if (shamt >=3D 0) { = \ + WTYPE shifted =3D (shamt >=3D (BITS)) ? = \ + ((WTYPE)e1 << (BITS)) : \ + ((WTYPE)e1 << shamt); \ + res =3D SAT_FN(shifted, &sat); = \ + } else { \ + int right =3D MIN(-shamt, (BITS)); = \ + WTYPE rounded =3D ((WTYPE)e1 >> (right - 1)) + 1; = \ + res =3D (ETYPE)(rounded >> 1); = \ + } \ + \ + rd =3D INSERT(rd, res, i); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +#define PSIMD_DO_SRA64(A, B) \ + (((B) >=3D 64) ? ((A) < 0 ? (int64_t)-1 : 0) : ((A) >> (B))) +#define PSIMD_DO_RNDSRA64(A, B) \ + (((B) >=3D 64) ? 0 : = \ + (int64_t)((((__int128_t)(A) >> ((B) - 1)) + 1) >> 1)) + +/* + * Generate a signed 64-bit bidirectional-shift helper. rs1 is the signed + * value and the low signed byte of rs2 selects left or RIGHT_OP right shi= ft. + * Used for SHA and SHAR. + */ +#define GEN_PSIMD_VAR_SRA64(NAME, RIGHT_OP) \ +uint64_t HELPER(NAME)(CPURISCVState *env, uint64_t rs1, uint64_t rs2) \ +{ \ + int64_t a =3D (int64_t)rs1; = \ + int8_t shamt =3D (int8_t)(rs2 & 0xff); = \ + \ + if (shamt >=3D 0) { = \ + return (shamt >=3D 64) ? 0 : (uint64_t)a << shamt; = \ + } \ + \ + int right =3D -shamt; = \ + return (uint64_t)RIGHT_OP(a, right); \ +} + +#define PSIMD_DO_SRL64(A, B) (((B) >=3D 64) ? 0 : ((A) >> (B))) +#define PSIMD_DO_RNDSRL64(A, B) \ + (uint64_t)((((__uint128_t)(A) >> (MIN((B), 64) - 1)) + 1) >> 1) + +/* + * Generate an unsigned 64-bit bidirectional-shift helper. rs1 is the + * unsigned value and the low signed byte of rs2 selects left or RIGHT_OP + * right shift. Used for SHL and SHLR. + */ +#define GEN_PSIMD_VAR_SRL64(NAME, RIGHT_OP) \ +uint64_t HELPER(NAME)(CPURISCVState *env, uint64_t rs1, uint64_t rs2) \ +{ \ + int8_t shamt =3D (int8_t)(rs2 & 0xff); = \ + \ + if (shamt < 0) { \ + return RIGHT_OP(rs1, -shamt); \ + } \ + return (shamt >=3D 64) ? 0 : (rs1 << shamt); = \ +} + +/* + * XPAIR operates on adjacent lane pairs. The low result combines rs1.low + * with rs2.high, and the high result combines rs1.high with rs2.low; + * OP_LO and OP_HI select add/subtract independently for those two crossin= gs. + */ +/* + * Generate a crossed-pair binary-operation helper. Adjacent rs1 and rs2 + * lanes are crossed, with OP_LO/OP_HI selecting each result operation. U= sed + * for PAS.HX, PSA.HX, PAS.WX, and PSA.WX. + */ +#define GEN_PSIMD_XPAIR_BINOP(NAME, RTYPE, ETYPE, EXTRACT, INSERT, \ + ELEMS, OP_LO, OP_HI) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i +=3D 2) { = \ + ETYPE s1_lo =3D (ETYPE)EXTRACT(rs1, i); = \ + ETYPE s1_hi =3D (ETYPE)EXTRACT(rs1, i + 1); = \ + ETYPE s2_lo =3D (ETYPE)EXTRACT(rs2, i); = \ + ETYPE s2_hi =3D (ETYPE)EXTRACT(rs2, i + 1); = \ + RTYPE res_lo =3D OP_LO((RTYPE)s1_lo, (RTYPE)s2_hi); = \ + RTYPE res_hi =3D OP_HI((RTYPE)s1_hi, (RTYPE)s2_lo); = \ + rd =3D INSERT(rd, res_lo, i); = \ + rd =3D INSERT(rd, res_hi, i + 1); = \ + } \ + return rd; \ +} + +/* + * Generate a saturating crossed-pair helper. Adjacent rs1 and rs2 lanes = are + * crossed and combined by OP_LO/OP_HI; saturation sets vxsat. Used for + * PSAS.HX, PSSA.HX, PSAS.WX, and PSSA.WX. + */ +#define GEN_PSIMD_XPAIR_SAT_BINOP(NAME, RTYPE, ETYPE, WTYPE, EXTRACT, \ + INSERT, ELEMS, OP_LO, OP_HI, SAT_FN) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + int sat =3D 0; = \ + \ + for (int i =3D 0; i < elems; i +=3D 2) { = \ + ETYPE s1_lo =3D (ETYPE)EXTRACT(rs1, i); = \ + ETYPE s1_hi =3D (ETYPE)EXTRACT(rs1, i + 1); = \ + ETYPE s2_lo =3D (ETYPE)EXTRACT(rs2, i); = \ + ETYPE s2_hi =3D (ETYPE)EXTRACT(rs2, i + 1); = \ + WTYPE val_lo =3D OP_LO((WTYPE)s1_lo, (WTYPE)s2_hi); = \ + WTYPE val_hi =3D OP_HI((WTYPE)s1_hi, (WTYPE)s2_lo); = \ + ETYPE res_lo =3D SAT_FN(val_lo, &sat); = \ + ETYPE res_hi =3D SAT_FN(val_hi, &sat); = \ + rd =3D INSERT(rd, res_lo, i); = \ + rd =3D INSERT(rd, res_hi, i + 1); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +/* + * Generate a halving crossed-pair helper. Adjacent signed rs1 and rs2 la= nes + * are crossed, combined by OP_LO/OP_HI, and arithmetically shifted right = by + * one, rounding toward negative infinity. Used for PAAS.HX, PASA.HX, + * PAAS.WX, and PASA.WX. + */ +#define GEN_PSIMD_XPAIR_AVG_BINOP(NAME, RTYPE, ETYPE, WTYPE, EXTRACT, \ + INSERT, ELEMS, OP_LO, OP_HI) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i +=3D 2) { = \ + ETYPE s1_lo =3D (ETYPE)EXTRACT(rs1, i); = \ + ETYPE s1_hi =3D (ETYPE)EXTRACT(rs1, i + 1); = \ + ETYPE s2_lo =3D (ETYPE)EXTRACT(rs2, i); = \ + ETYPE s2_hi =3D (ETYPE)EXTRACT(rs2, i + 1); = \ + ETYPE res_lo =3D (ETYPE)(OP_LO((WTYPE)s1_lo, (WTYPE)s2_hi) >> 1); = \ + ETYPE res_hi =3D (ETYPE)(OP_HI((WTYPE)s1_hi, (WTYPE)s2_lo) >> 1); = \ + rd =3D INSERT(rd, res_lo, i); = \ + rd =3D INSERT(rd, res_hi, i + 1); = \ + } \ + return rd; \ +} + +/* + * Generate a packed reduction-sum helper. rs1 supplies lanes and INIT + * supplies the rs2 initial accumulator value. Used for PREDSUM.BS, + * PREDSUM.HS, PREDSUM.WS, and their unsigned variants. + */ +#define GEN_PSIMD_REDSUM(NAME, RTYPE, SUMTYPE, ETYPE, EXTRACT, ELEMS, \ + INIT) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + uint64_t sum =3D (uint64_t)(INIT); = \ + int elems =3D ELEMS(rs1); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE e1 =3D (ETYPE)EXTRACT(rs1, i); = \ + sum +=3D (uint64_t)(SUMTYPE)e1; = \ + } \ + \ + return (RTYPE)sum; \ +} + +#define PSIMD_PAIR_LO(V, MASK, SHIFT) ((V) & (MASK)) +#define PSIMD_PAIR_HI(V, MASK, SHIFT) (((V) >> (SHIFT)) & (MASK)) + +/* + * Generate a pair-packing helper. rs1 and rs2 contain packed source lane= s; + * MASK and SHIFT select the low or high subfield of each lane. Used for = the + * PPAIRE*, PPAIREO*, PPAIROE*, and PPAIRO* byte/halfword instructions. + */ +#define GEN_PSIMD_PAIR_PACK(NAME, RTYPE, ETYPE, EXTRACT, INSERT, ELEMS, \ + MASK, SHIFT, HI_SEL, LO_SEL) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE e1 =3D EXTRACT(rs1, i); = \ + ETYPE e2 =3D EXTRACT(rs2, i); = \ + ETYPE res =3D (HI_SEL(e2, MASK, SHIFT) << (SHIFT)) | = \ + LO_SEL(e1, MASK, SHIFT); \ + rd =3D INSERT(rd, res, i); = \ + } \ + return rd; \ +} + +/* + * Generate a word-pair packing helper. RS1_IDX and RS2_IDX select one wo= rd + * from rs1 and rs2 for the low and high result words. Used for PPAIREO.W, + * PPAIROE.W, and PPAIRO.W. + */ +#define GEN_PSIMD_PAIR_WORD(NAME, RS1_IDX, RS2_IDX) \ +uint64_t HELPER(NAME)(CPURISCVState *env, uint64_t rs1, uint64_t rs2) \ +{ \ + uint32_t e1 =3D EXTRACT32(rs1, RS1_IDX); = \ + uint32_t e2 =3D EXTRACT32(rs2, RS2_IDX); = \ + \ + return ((uint64_t)e2 << 32) | e1; \ +} + +/* + * Generate a packed sign-extension helper. rs1 supplies narrow signed + * lanes; SCALE selects the low lane of each source group to widen into the + * result. Used for PSEXT.H.B, PSEXT.W.B, and PSEXT.W.H. + */ +#define GEN_PSIMD_SIGN_EXTEND(NAME, RTYPE, STYPE, DTYPE, EXTRACT, INSERT, \ + ELEMS, SCALE) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + STYPE e1 =3D (STYPE)EXTRACT(rs1, i * (SCALE)); = \ + rd =3D INSERT(rd, (DTYPE)e1, i); = \ + } \ + return rd; \ +} + +/* + * Generate a 64-bit lane-interleave helper. rs1 and rs2 supply lanes; + * START selects which half of each operand is zipped. Used for ZIP8P, + * ZIP8HP, ZIP16P, and ZIP16HP. + */ +#define GEN_PSIMD_ZIP(NAME, ETYPE, EXTRACT, ELEMS, BITS, START) \ +uint64_t HELPER(NAME)(CPURISCVState *env, uint64_t rs1, uint64_t rs2) \ +{ \ + uint64_t rd =3D 0; = \ + \ + for (int i =3D 0; i < (ELEMS); i++) { = \ + ETYPE e1 =3D EXTRACT(rs1, (START) - i); = \ + ETYPE e2 =3D EXTRACT(rs2, (START) - i); = \ + rd =3D (rd << (2 * (BITS))) | ((uint64_t)e2 << (BITS)) | e1; = \ + } \ + \ + return rd; \ +} + +/* + * Generate a 64-bit lane-deinterleave helper. rs1 and rs2 supply packed + * lanes and OFFSET selects the even or odd lanes. Used for UNZIP8P, + * UNZIP8HP, UNZIP16P, and UNZIP16HP. + */ +#define GEN_PSIMD_UNZIP(NAME, EXTRACT, ELEMS, BITS, OFFSET) \ +uint64_t HELPER(NAME)(CPURISCVState *env, uint64_t rs1, uint64_t rs2) \ +{ \ + uint64_t rd =3D 0; = \ + \ + for (int i =3D 0; i < (ELEMS); i++) { = \ + uint64_t e1 =3D (uint64_t)EXTRACT(rs1, 2 * i + (OFFSET)) << = \ + ((BITS) * i); \ + uint64_t e2 =3D (uint64_t)EXTRACT(rs2, 2 * i + (OFFSET)) << = \ + (32 + (BITS) * i); \ + rd =3D rd | e2 | e1; = \ + } \ + \ + return rd; \ +} + +/* + * Generate a bit-select helper. MASK, TRUE_VAL, and FALSE_VAL name the r= d, + * rs1, or rs2 operands used as mask and alternatives. Used for MVM, MVMN, + * and MERGE. + */ +#define GEN_PSIMD_BIT_SELECT(NAME, MASK, TRUE_VAL, FALSE_VAL) \ +target_ulong HELPER(NAME)(CPURISCVState *env, target_ulong rs1, \ + target_ulong rs2, target_ulong rd) \ +{ \ + return (~(MASK) & (FALSE_VAL)) | ((MASK) & (TRUE_VAL)); \ +} + +/* + * Generate a packed narrowing-clip helper. rs1 supplies the low half and + * rs2 the high half of a conceptual 128-bit source. Each wide lane is + * clipped directly to the signed or unsigned narrow range and packed into + * the result; saturation sets vxsat. Used for PNCLIPP.B/H/W and + * PNCLIPUP.B/H/W. + */ +#define GEN_PSIMD_NCLIP_PACK(NAME, ITYPE, OTYPE, EXTRACT, INSERT, ELEMS, \ + SAT_FN) \ +uint64_t HELPER(NAME)(CPURISCVState *env, uint64_t rs1, uint64_t rs2) \ +{ \ + uint64_t rd =3D 0; = \ + int sat =3D 0; = \ + \ + for (int i =3D 0; i < (ELEMS); i++) { = \ + ITYPE lo =3D (ITYPE)EXTRACT(rs1, i); = \ + ITYPE hi =3D (ITYPE)EXTRACT(rs2, i); = \ + OTYPE res_lo =3D SAT_FN(lo, &sat); = \ + OTYPE res_hi =3D SAT_FN(hi, &sat); = \ + \ + rd =3D (uint64_t)INSERT(rd, res_lo, i); = \ + rd =3D (uint64_t)INSERT(rd, res_hi, i + (ELEMS)); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +/* + * Generate a count-leading-sign-bits helper. rs1 supplies the signed sca= lar + * and CLRSB selects its width; the sign bit is excluded from the result. + * Used for CLS and CLSW. + */ +#define GEN_PSIMD_CLS(NAME, RTYPE, UTYPE, CLRSB) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1) \ +{ \ + return CLRSB((UTYPE)rs1); \ +} + +#define PSIMD_MUL_S32(A, B) ((int32_t)(A) * (int32_t)(B)) +#define PSIMD_MUL_SU16(A, B) ((int16_t)(A) * (uint16_t)(B)) +#define PSIMD_MUL_SU32(A, B) ((int32_t)(A) * (uint32_t)(B)) +#define PSIMD_MUL_U32(A, B) ((uint32_t)(A) * (uint32_t)(B)) +#define PSIMD_MUL_S64(A, B) ((int64_t)(A) * (int64_t)(B)) +#define PSIMD_MUL_SU64(A, B) ((int64_t)(A) * (uint64_t)(B)) +#define PSIMD_MUL_U64(A, B) ((uint64_t)(A) * (uint64_t)(B)) + +/* + * Multiplication generators separate the input-lane types (E1TYPE/E2TYPE), + * the full product type (PTYPE), and the packed output type (HTYPE/OTYPE). + * SCALE maps each output lane to its source group; OFFSET or OFFSET1/2 pi= cks + * the member(s) of that group, which covers bottom/top and cross variants. + */ +/* + * Generate a lane-wise multiply-high helper. rs1 and rs2 supply factors; + * their signedness comes from E1TYPE/E2TYPE, while ROUND selects rounding. + * Used for PMULH*, PMULHR*, MULHR, MULHRSU, and MULHRU. + */ +#define GEN_PSIMD_MUL_HIGH(NAME, RTYPE, E1TYPE, E2TYPE, PTYPE, HTYPE, \ + EXTRACT, INSERT, ELEMS, SHIFT, ROUND, OP) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + E1TYPE e1 =3D (E1TYPE)EXTRACT(rs1, i); = \ + E2TYPE e2 =3D (E2TYPE)EXTRACT(rs2, i); = \ + PTYPE prod =3D OP(e1, e2) + (ROUND); = \ + HTYPE high =3D (HTYPE)(prod >> (SHIFT)); = \ + rd =3D INSERT(rd, high, i); = \ + } \ + return rd; \ +} + +/* + * Generate a selected-element multiply-high helper. rs1 supplies wide + * factors and OFFSET selects the narrow rs2 factor for each SCALE-sized + * group. Used for PMULH*.B0/B1, MULH*.H0/H1, and PMULH*.H0/H1 forms. + */ +#define GEN_PSIMD_MUL_HIGH_SEL(NAME, RTYPE, E1TYPE, E2TYPE, PTYPE, \ + HTYPE, EXTRACT1, EXTRACT2, INSERT, ELEMS, \ + SCALE, OFFSET, SHIFT, OP) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + E1TYPE e1 =3D (E1TYPE)EXTRACT1(rs1, i); = \ + E2TYPE e2 =3D (E2TYPE)EXTRACT2(rs2, i * (SCALE) + (OFFSET)); = \ + PTYPE prod =3D OP(e1, e2); = \ + HTYPE high =3D (HTYPE)(prod >> (SHIFT)); = \ + rd =3D INSERT(rd, high, i); = \ + } \ + return rd; \ +} + +/* + * Generate an indexed widening-multiply helper. OFFSET1 selects rs1 lanes + * and OFFSET2 selects one rs2 lane per SCALE-sized group. Used for the + * PMUL.H.B**, PMUL.W.H**, PMULSU*, and PMULU* families. + */ +#define GEN_PSIMD_MUL_ELEM_INDEXED(NAME, RTYPE, E1TYPE, E2TYPE, PTYPE, \ + OTYPE, EXTRACT, INSERT, ELEMS, SCALE, \ + OFFSET1, OFFSET2, OP) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + E1TYPE e1 =3D (E1TYPE)EXTRACT(rs1, i * (SCALE) + (OFFSET1)); = \ + E2TYPE e2 =3D (E2TYPE)EXTRACT(rs2, i * (SCALE) + (OFFSET2)); = \ + PTYPE mul =3D OP(e1, e2); = \ + rd =3D INSERT(rd, (OTYPE)mul, i); = \ + } \ + return rd; \ +} + +/* + * Generate a selected-element scalar multiply helper. OFFSET1/2 select o= ne + * element from rs1 and rs2 and the full-width product is returned. Used = for + * MUL.H**, MUL.W**, MULSU.*, and MULU.* instructions. + */ +#define GEN_PSIMD_MUL_ELEM_SCALAR(NAME, RTYPE, E1TYPE, E2TYPE, PTYPE, \ + EXTRACT, OFFSET1, OFFSET2, OP) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + E1TYPE e1 =3D (E1TYPE)EXTRACT(rs1, OFFSET1); = \ + E2TYPE e2 =3D (E2TYPE)EXTRACT(rs2, OFFSET2); = \ + PTYPE mul =3D OP(e1, e2); = \ + \ + return (RTYPE)mul; \ +} + +/* + * Generate a lane-wise multiply-high-accumulate helper. rs1 and rs2 supp= ly + * factors and dest supplies accumulator lanes; SHIFT/ROUND select the high + * product. Used for PMHACC*, PMHRACC*, MHACC*, and MHRACC*. + */ +#define GEN_PSIMD_MUL_HIGH_ACC(NAME, RTYPE, E1TYPE, E2TYPE, DTYPE, PTYPE, \ + HTYPE, OTYPE, EXTRACT, INSERT, ELEMS, \ + SHIFT, ROUND, OP) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2, RTYPE dest) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + E1TYPE e1 =3D (E1TYPE)EXTRACT(rs1, i); = \ + E2TYPE e2 =3D (E2TYPE)EXTRACT(rs2, i); = \ + DTYPE d =3D (DTYPE)EXTRACT(dest, i); = \ + PTYPE prod =3D OP(e1, e2) + (ROUND); = \ + HTYPE high =3D (HTYPE)(prod >> (SHIFT)); = \ + OTYPE res =3D (OTYPE)high + (OTYPE)d; = \ + rd =3D INSERT(rd, res, i); = \ + } \ + return rd; \ +} + +/* + * Generate a selected-element multiply-high-accumulate helper. rs1 and t= he + * OFFSET-selected rs2 lanes supply factors, while dest supplies accumulat= or + * lanes. Used for PMHACC*.B0/B1, MHACC*.H0/H1, and PMHACC*.H0/H1. + */ +#define GEN_PSIMD_MUL_HIGH_ACC_SEL(NAME, RTYPE, E1TYPE, E2TYPE, DTYPE, \ + PTYPE, HTYPE, OTYPE, EXTRACT1, \ + EXTRACT2, INSERT, ELEMS, SCALE, \ + OFFSET, SHIFT, OP) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2, RTYPE dest) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + E1TYPE e1 =3D (E1TYPE)EXTRACT1(rs1, i); = \ + E2TYPE e2 =3D (E2TYPE)EXTRACT2(rs2, i * (SCALE) + (OFFSET)); = \ + DTYPE d =3D (DTYPE)EXTRACT1(dest, i); = \ + PTYPE prod =3D OP(e1, e2); = \ + HTYPE high =3D (HTYPE)(prod >> (SHIFT)); = \ + OTYPE res =3D (OTYPE)high + (OTYPE)d; = \ + rd =3D INSERT(rd, res, i); = \ + } \ + return rd; \ +} + +/* + * Generate an indexed multiply-accumulate helper. OFFSET1/2 select factor + * lanes from rs1 and rs2, and dest supplies accumulator lanes. Used for = the + * PMACC.W.H**, MACC.H**, and MACC.W** signed/unsigned families. + */ +#define GEN_PSIMD_MUL_ACC_INDEXED(NAME, RTYPE, E1TYPE, E2TYPE, DTYPE, \ + PTYPE, OTYPE, EXTRACT, EXTRACTD, \ + INSERT, ELEMS, SCALE, OFFSET1, \ + OFFSET2, OP) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2, RTYPE dest) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + E1TYPE e1 =3D (E1TYPE)EXTRACT(rs1, i * (SCALE) + (OFFSET1)); = \ + E2TYPE e2 =3D (E2TYPE)EXTRACT(rs2, i * (SCALE) + (OFFSET2)); = \ + DTYPE d =3D (DTYPE)EXTRACTD(dest, i); = \ + PTYPE mul =3D OP(e1, e2); = \ + rd =3D INSERT(rd, (OTYPE)d + (OTYPE)mul, i); = \ + } \ + return rd; \ +} + +/* + * Generate a saturating Q-format multiply helper. rs1 and rs2 contain + * signed fractional lanes; SHIFT and ROUND scale the product and saturati= on + * sets vxsat. Used for PMULQ.H/W, PMULQR.H/W, MULQ, and MULQR. + */ +#define GEN_PSIMD_QMUL(NAME, RTYPE, ETYPE, PTYPE, OTYPE, EXTRACT, INSERT, \ + ELEMS, SHIFT, ROUND, MINVAL, MAXVAL) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + int sat =3D 0; = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE e1 =3D (ETYPE)EXTRACT(rs1, i); = \ + ETYPE e2 =3D (ETYPE)EXTRACT(rs2, i); = \ + OTYPE result; \ + \ + if ((e1 =3D=3D (ETYPE)(MINVAL)) && (e2 =3D=3D (ETYPE)(MINVAL))) { = \ + sat =3D 1; = \ + result =3D (OTYPE)(MAXVAL); = \ + } else { \ + PTYPE prod =3D (PTYPE)e1 * (PTYPE)e2 + (ROUND); = \ + result =3D (OTYPE)(prod >> (SHIFT)); = \ + } \ + rd =3D INSERT(rd, result, i); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +/* + * Generate an indexed Q-format multiply-accumulate helper. OFFSET1/2 sel= ect + * rs1/rs2 factors and dest supplies accumulator lanes; ROUND controls pro= duct + * rounding. Used for MQACC*, MQRACC*, PMQACC*, and PMQRACC*. + */ +#define GEN_PSIMD_QMUL_ACC_INDEXED(NAME, RTYPE, E1TYPE, E2TYPE, DTYPE, \ + PTYPE, STYPE, OTYPE, EXTRACT, \ + EXTRACTD, INSERT, ELEMS, SCALE, \ + OFFSET1, OFFSET2, SHIFT, ROUND, OP) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2, RTYPE dest) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + E1TYPE e1 =3D (E1TYPE)EXTRACT(rs1, i * (SCALE) + (OFFSET1)); = \ + E2TYPE e2 =3D (E2TYPE)EXTRACT(rs2, i * (SCALE) + (OFFSET2)); = \ + DTYPE d =3D (DTYPE)EXTRACTD(dest, i); = \ + PTYPE prod =3D OP(e1, e2) + (ROUND); = \ + STYPE scaled =3D (STYPE)(((__int128_t)prod) >> (SHIFT)); = \ + rd =3D INSERT(rd, (OTYPE)d + (OTYPE)scaled, i); = \ + } \ + return rd; \ +} + +/* + * Generate a two-product Q-format helper. rs1 and rs2 supply paired sign= ed + * factors; OP forms each product, which is scaled before the two results = are + * added without saturation. Used for PMQ2ADD.H/W and PMQR2ADD.H/W. + */ +#define GEN_PSIMD_Q2ADD(NAME, RTYPE, ETYPE, PTYPE, STYPE, OTYPE, EXTRACT, \ + INSERT, ELEMS, SCALE, SHIFT, ROUND, OP) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE s1_0 =3D (ETYPE)EXTRACT(rs1, i * (SCALE)); = \ + ETYPE s1_1 =3D (ETYPE)EXTRACT(rs1, i * (SCALE) + 1); = \ + ETYPE s2_0 =3D (ETYPE)EXTRACT(rs2, i * (SCALE)); = \ + ETYPE s2_1 =3D (ETYPE)EXTRACT(rs2, i * (SCALE) + 1); = \ + PTYPE prod0 =3D OP(s1_0, s2_0) + (ROUND); = \ + PTYPE prod1 =3D OP(s1_1, s2_1) + (ROUND); = \ + STYPE scaled0 =3D (STYPE)(((__int128_t)prod0) >> (SHIFT)); = \ + STYPE scaled1 =3D (STYPE)(((__int128_t)prod1) >> (SHIFT)); = \ + rd =3D INSERT(rd, (OTYPE)(scaled0 + scaled1), i); = \ + } \ + return rd; \ +} + +/* + * Generate an accumulating two-product Q-format helper. rs1 and rs2 supp= ly + * paired factors, OP forms each product, and dest supplies the accumulator + * lanes to which the two scaled products are added. Used for PMQ2ADDA.H/W + * and PMQR2ADDA.H/W. + */ +#define GEN_PSIMD_Q2ADDA(NAME, RTYPE, ETYPE, DTYPE, PTYPE, STYPE, OTYPE, \ + EXTRACT, EXTRACTD, INSERT, ELEMS, SCALE, \ + SHIFT, ROUND, OP) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2, RTYPE dest) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + ETYPE s1_0 =3D (ETYPE)EXTRACT(rs1, i * (SCALE)); = \ + ETYPE s1_1 =3D (ETYPE)EXTRACT(rs1, i * (SCALE) + 1); = \ + ETYPE s2_0 =3D (ETYPE)EXTRACT(rs2, i * (SCALE)); = \ + ETYPE s2_1 =3D (ETYPE)EXTRACT(rs2, i * (SCALE) + 1); = \ + DTYPE d =3D (DTYPE)EXTRACTD(dest, i); = \ + PTYPE prod0 =3D OP(s1_0, s2_0) + (ROUND); = \ + PTYPE prod1 =3D OP(s1_1, s2_1) + (ROUND); = \ + STYPE scaled0 =3D (STYPE)(((__int128_t)prod0) >> (SHIFT)); = \ + STYPE scaled1 =3D (STYPE)(((__int128_t)prod1) >> (SHIFT)); = \ + rd =3D INSERT(rd, (OTYPE)d + (OTYPE)scaled0 + (OTYPE)scaled1, i); = \ + } \ + return rd; \ +} + +#define PSIMD_COMB_ADD(D, A, B) ((D) + (A) + (B)) +#define PSIMD_COMB_SUB(D, A, B) ((D) + (A) - (B)) + +/* + * The 2-way generators form two products per output lane. The four OFFSET + * arguments select the rs1 and rs2 lanes for each product, and COMBINE + * chooses whether the second product is added or subtracted (and whether = an + * accumulator D participates). + */ +/* + * Generate a two-product helper. OFFSET10/11 and OFFSET20/21 select fact= or + * lanes from rs1 and rs2; COMBINE adds or subtracts the products. Used f= or + * PM2ADD*, PM2SUB*, and their signed/unsigned and crossed variants. + */ +#define GEN_PSIMD_2WAY_MUL(NAME, RTYPE, E1TYPE, E2TYPE, PTYPE, OTYPE, \ + EXTRACT, INSERT, ELEMS, SCALE, OFFSET10, \ + OFFSET11, OFFSET20, OFFSET21, OP, COMBINE) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + E1TYPE s1_0 =3D (E1TYPE)EXTRACT(rs1, i * (SCALE) + (OFFSET10)); = \ + E1TYPE s1_1 =3D (E1TYPE)EXTRACT(rs1, i * (SCALE) + (OFFSET11)); = \ + E2TYPE s2_0 =3D (E2TYPE)EXTRACT(rs2, i * (SCALE) + (OFFSET20)); = \ + E2TYPE s2_1 =3D (E2TYPE)EXTRACT(rs2, i * (SCALE) + (OFFSET21)); = \ + PTYPE prod0 =3D OP(s1_0, s2_0); = \ + PTYPE prod1 =3D OP(s1_1, s2_1); = \ + rd =3D INSERT(rd, COMBINE((OTYPE)0, (OTYPE)prod0, = \ + (OTYPE)prod1), i); \ + } \ + return rd; \ +} + +/* + * Generate a saturating two-product helper. OFFSET10/11 and OFFSET20/21 + * select halfword factors from rs1 and rs2; each sum is saturated to the + * signed 32-bit range and sets vxsat. Used for PM2SADD.H and PM2SADD.HX. + */ +#define GEN_PSIMD_2WAY_SAT_MUL(NAME, OFFSET10, OFFSET11, OFFSET20, \ + OFFSET21) \ +target_ulong HELPER(NAME)(CPURISCVState *env, target_ulong rs1, \ + target_ulong rs2) \ +{ \ + target_ulong rd =3D 0; = \ + int sat =3D 0; = \ + \ + for (int i =3D 0; i < ELEMS_W(rd); i++) { = \ + int16_t s1_0 =3D (int16_t)EXTRACT16(rs1, i * 2 + (OFFSET10)); = \ + int16_t s1_1 =3D (int16_t)EXTRACT16(rs1, i * 2 + (OFFSET11)); = \ + int16_t s2_0 =3D (int16_t)EXTRACT16(rs2, i * 2 + (OFFSET20)); = \ + int16_t s2_1 =3D (int16_t)EXTRACT16(rs2, i * 2 + (OFFSET21)); = \ + uint32_t result; \ + \ + if (s1_0 =3D=3D INT16_MIN && s1_1 =3D=3D INT16_MIN && = \ + s2_0 =3D=3D INT16_MIN && s2_1 =3D=3D INT16_MIN) { = \ + result =3D INT32_MAX; = \ + sat =3D 1; = \ + } else { \ + int32_t prod0 =3D (int32_t)s1_0 * s2_0; = \ + int32_t prod1 =3D (int32_t)s1_1 * s2_1; = \ + result =3D (uint32_t)(prod0 + prod1); = \ + } \ + rd =3D INSERT32(rd, result, i); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +/* + * Generate an accumulating two-product helper. rs1 and rs2 supply select= ed + * factors and dest supplies accumulator lanes; COMBINE adds or subtracts. + * Used for PM2ADDA*, PM2SUBA*, and signed/unsigned crossed variants. + */ +#define GEN_PSIMD_2WAY_MUL_ACC(NAME, RTYPE, E1TYPE, E2TYPE, DTYPE, PTYPE, \ + OTYPE, EXTRACT, EXTRACTD, INSERT, ELEMS, \ + SCALE, OFFSET10, OFFSET11, OFFSET20, \ + OFFSET21, OP, COMBINE) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2, RTYPE dest) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + E1TYPE s1_0 =3D (E1TYPE)EXTRACT(rs1, i * (SCALE) + (OFFSET10)); = \ + E1TYPE s1_1 =3D (E1TYPE)EXTRACT(rs1, i * (SCALE) + (OFFSET11)); = \ + E2TYPE s2_0 =3D (E2TYPE)EXTRACT(rs2, i * (SCALE) + (OFFSET20)); = \ + E2TYPE s2_1 =3D (E2TYPE)EXTRACT(rs2, i * (SCALE) + (OFFSET21)); = \ + DTYPE d =3D (DTYPE)EXTRACTD(dest, i); = \ + PTYPE prod0 =3D OP(s1_0, s2_0); = \ + PTYPE prod1 =3D OP(s1_1, s2_1); = \ + rd =3D INSERT(rd, COMBINE((OTYPE)d, (OTYPE)prod0, = \ + (OTYPE)prod1), i); \ + } \ + return rd; \ +} + +/* + * Generate a four-product reduction helper. Each four-lane group in rs1 + * and rs2 supplies corresponding factors whose products form one result. + * Used for PM4ADD.B/H and their signed-unsigned/unsigned variants. + */ +#define GEN_PSIMD_4WAY_MUL(NAME, RTYPE, E1TYPE, E2TYPE, PTYPE, OTYPE, \ + EXTRACT, INSERT, ELEMS, SCALE, OP) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + PTYPE prod0 =3D OP((E1TYPE)EXTRACT(rs1, i * (SCALE)), = \ + (E2TYPE)EXTRACT(rs2, i * (SCALE))); \ + PTYPE prod1 =3D OP((E1TYPE)EXTRACT(rs1, i * (SCALE) + 1), = \ + (E2TYPE)EXTRACT(rs2, i * (SCALE) + 1)); \ + PTYPE prod2 =3D OP((E1TYPE)EXTRACT(rs1, i * (SCALE) + 2), = \ + (E2TYPE)EXTRACT(rs2, i * (SCALE) + 2)); \ + PTYPE prod3 =3D OP((E1TYPE)EXTRACT(rs1, i * (SCALE) + 3), = \ + (E2TYPE)EXTRACT(rs2, i * (SCALE) + 3)); \ + rd =3D INSERT(rd, (OTYPE)prod0 + (OTYPE)prod1 + = \ + (OTYPE)prod2 + (OTYPE)prod3, i); \ + } \ + return rd; \ +} + +/* + * Generate an accumulating four-product reduction helper. rs1 and rs2 + * supply four factors per result and dest supplies accumulator lanes. Us= ed + * for PM4ADDA.B/H and their signed-unsigned/unsigned variants. + */ +#define GEN_PSIMD_4WAY_MUL_ACC(NAME, RTYPE, E1TYPE, E2TYPE, DTYPE, PTYPE, \ + OTYPE, EXTRACT, EXTRACTD, INSERT, ELEMS, \ + SCALE, OP) \ +RTYPE HELPER(NAME)(CPURISCVState *env, RTYPE rs1, RTYPE rs2, RTYPE dest) \ +{ \ + RTYPE rd =3D 0; = \ + int elems =3D ELEMS(rd); = \ + \ + for (int i =3D 0; i < elems; i++) { = \ + DTYPE d =3D (DTYPE)EXTRACTD(dest, i); = \ + PTYPE prod0 =3D OP((E1TYPE)EXTRACT(rs1, i * (SCALE)), = \ + (E2TYPE)EXTRACT(rs2, i * (SCALE))); \ + PTYPE prod1 =3D OP((E1TYPE)EXTRACT(rs1, i * (SCALE) + 1), = \ + (E2TYPE)EXTRACT(rs2, i * (SCALE) + 1)); \ + PTYPE prod2 =3D OP((E1TYPE)EXTRACT(rs1, i * (SCALE) + 2), = \ + (E2TYPE)EXTRACT(rs2, i * (SCALE) + 2)); \ + PTYPE prod3 =3D OP((E1TYPE)EXTRACT(rs1, i * (SCALE) + 3), = \ + (E2TYPE)EXTRACT(rs2, i * (SCALE) + 3)); \ + rd =3D INSERT(rd, (OTYPE)d + (OTYPE)prod0 + (OTYPE)prod1 + = \ + (OTYPE)prod2 + (OTYPE)prod3, i); \ + } \ + return rd; \ +} + +/* + * RV32 widening helpers consume packed 32-bit operands and construct the + * 64-bit result explicitly. IBITS/OBITS are input/output lane strides, + * IMASK/OMASK isolate raw lanes, and casts to ETYPE/DTYPE supply the sign= ed + * interpretation before arithmetic. + */ +/* + * Generate an RV32 widening binary-operation helper. rs1 and rs2 contain + * narrow lanes and OP produces packed wide lanes in a 64-bit result. Used + * for PWADD/PWSUB.B/H and scalar WADD/WSUB signed/unsigned forms. + */ +#define GEN_PSIMD_WIDEN_BINOP(NAME, ETYPE, WTYPE, OTYPE, ELEMS, IBITS, \ + OBITS, IMASK, OP) \ +uint64_t HELPER(NAME)(CPURISCVState *env, uint32_t rs1, uint32_t rs2) \ +{ \ + uint64_t rd =3D 0; = \ + \ + for (int i =3D 0; i < (ELEMS); i++) { = \ + ETYPE e1 =3D (ETYPE)((rs1 >> (i * (IBITS))) & (IMASK)); = \ + ETYPE e2 =3D (ETYPE)((rs2 >> (i * (IBITS))) & (IMASK)); = \ + WTYPE res =3D OP((WTYPE)0, (WTYPE)e1, (WTYPE)e2); = \ + rd |=3D ((uint64_t)(OTYPE)res) << (i * (OBITS)); = \ + } \ + return rd; \ +} + +/* + * Generate an RV32 widening binary-accumulate helper. rs1 and rs2 contain + * narrow lanes and dest supplies packed wide accumulators. Used for + * PWADDA/PWSUBA.B/H and scalar WADDA/WSUBA signed/unsigned forms. + */ +#define GEN_PSIMD_WIDEN_BINOP_ACC(NAME, ETYPE, WTYPE, OTYPE, ELEMS, \ + IBITS, OBITS, IMASK, OMASK, OP) \ +uint64_t HELPER(NAME)(CPURISCVState *env, uint32_t rs1, uint32_t rs2, \ + uint64_t dest) \ +{ \ + uint64_t rd =3D 0; = \ + \ + for (int i =3D 0; i < (ELEMS); i++) { = \ + ETYPE e1 =3D (ETYPE)((rs1 >> (i * (IBITS))) & (IMASK)); = \ + ETYPE e2 =3D (ETYPE)((rs2 >> (i * (IBITS))) & (IMASK)); = \ + WTYPE acc =3D (WTYPE)((dest >> (i * (OBITS))) & (OMASK)); = \ + OTYPE res =3D OP((OTYPE)acc, (OTYPE)e1, (OTYPE)e2); = \ + rd |=3D ((uint64_t)(OTYPE)res) << (i * (OBITS)); = \ + } \ + return rd; \ +} + +/* + * Generate an RV32 widening-multiply helper. rs1 and rs2 contain narrow + * factors and each full-width product is packed into the 64-bit result. + * Used for PWMUL.B/H and scalar WMUL signed/unsigned forms. + */ +#define GEN_PSIMD_WIDEN_MUL(NAME, E1TYPE, E2TYPE, PTYPE, OTYPE, ELEMS, \ + EXTRACT, OBITS, OP) \ +uint64_t HELPER(NAME)(CPURISCVState *env, uint32_t rs1, uint32_t rs2) \ +{ \ + uint64_t rd =3D 0; = \ + \ + for (int i =3D 0; i < (ELEMS); i++) { = \ + E1TYPE e1 =3D (E1TYPE)EXTRACT(rs1, i); = \ + E2TYPE e2 =3D (E2TYPE)EXTRACT(rs2, i); = \ + PTYPE prod =3D OP(e1, e2); = \ + rd |=3D ((uint64_t)(OTYPE)prod) << (i * (OBITS)); = \ + } \ + return rd; \ +} + +/* + * Generate an RV32 widening multiply-accumulate helper. rs1 and rs2 supp= ly + * narrow factors and dest supplies wide accumulator lanes. Used for + * PWMACC.H and scalar WMACC signed/unsigned forms. + */ +#define GEN_PSIMD_WIDEN_MUL_ACC(NAME, E1TYPE, E2TYPE, DTYPE, PTYPE, \ + OTYPE, ELEMS, EXTRACT, EXTRACTD, OBITS, \ + OP) \ +uint64_t HELPER(NAME)(CPURISCVState *env, uint32_t rs1, uint32_t rs2, \ + uint64_t dest) \ +{ \ + uint64_t rd =3D 0; = \ + \ + for (int i =3D 0; i < (ELEMS); i++) { = \ + E1TYPE e1 =3D (E1TYPE)EXTRACT(rs1, i); = \ + E2TYPE e2 =3D (E2TYPE)EXTRACT(rs2, i); = \ + DTYPE d =3D (DTYPE)EXTRACTD(dest, i); = \ + PTYPE prod =3D OP(e1, e2); = \ + rd |=3D ((uint64_t)((OTYPE)d + (OTYPE)prod)) << (i * (OBITS)); = \ + } \ + return rd; \ +} + +/* + * Generate an RV32 widening Q-format MAC helper. Products of OFFSET-sele= cted + * rs1/rs2 lanes are scaled by SHIFT/ROUND and added to wide dest lanes. = Used + * for PMQWACC.H, PMQRWACC.H, MQWACC, and MQRWACC. + */ +#define GEN_PSIMD_WIDEN_QMUL_ACC(NAME, ETYPE, DTYPE, PTYPE, STYPE, \ + OTYPE, ELEMS, EXTRACT, EXTRACTD, SCALE, \ + OFFSET, SHIFT, ROUND, OBITS, OP) \ +uint64_t HELPER(NAME)(CPURISCVState *env, uint32_t rs1, uint32_t rs2, \ + uint64_t dest) \ +{ \ + uint64_t rd =3D 0; = \ + \ + for (int i =3D 0; i < (ELEMS); i++) { = \ + ETYPE e1 =3D (ETYPE)EXTRACT(rs1, i * (SCALE) + (OFFSET)); = \ + ETYPE e2 =3D (ETYPE)EXTRACT(rs2, i * (SCALE) + (OFFSET)); = \ + DTYPE d =3D (DTYPE)EXTRACTD(dest, i); = \ + PTYPE prod =3D OP(e1, e2) + (ROUND); = \ + STYPE scaled =3D (STYPE)(((__int128_t)prod) >> (SHIFT)); = \ + rd |=3D ((uint64_t)((OTYPE)d + (OTYPE)scaled)) = \ + << (i * (OBITS)); \ + } \ + return rd; \ +} + +/* + * Generate an RV32 two-product doubleword helper. The OFFSET parameters + * select halfword factors from rs1 and rs2 and COMBINE forms the 64-bit + * result. Used for PM2WADD.H/HX and PM2WSUB.H/HX variants. + */ +#define GEN_PSIMD_DW_2WAY_MUL(NAME, E1TYPE, E2TYPE, PTYPE, EXTRACT, \ + OFFSET10, OFFSET11, OFFSET20, OFFSET21, \ + OP, COMBINE) \ +uint64_t HELPER(NAME)(CPURISCVState *env, uint32_t rs1, uint32_t rs2) \ +{ \ + E1TYPE s1_0 =3D (E1TYPE)EXTRACT(rs1, OFFSET10); = \ + E1TYPE s1_1 =3D (E1TYPE)EXTRACT(rs1, OFFSET11); = \ + E2TYPE s2_0 =3D (E2TYPE)EXTRACT(rs2, OFFSET20); = \ + E2TYPE s2_1 =3D (E2TYPE)EXTRACT(rs2, OFFSET21); = \ + PTYPE prod0 =3D OP(s1_0, s2_0); = \ + PTYPE prod1 =3D OP(s1_1, s2_1); = \ + \ + return COMBINE(UINT64_C(0), (uint64_t)prod0, (uint64_t)prod1); \ +} + +/* + * Generate an accumulating RV32 two-product doubleword helper. rs1 and r= s2 + * supply selected halfword factors and dest is the 64-bit accumulator. U= sed + * for PM2WADDA.H/HX and PM2WSUBA.H/HX variants. + */ +#define GEN_PSIMD_DW_2WAY_MUL_ACC(NAME, E1TYPE, E2TYPE, DTYPE, PTYPE, \ + EXTRACT, OFFSET10, OFFSET11, OFFSET20, \ + OFFSET21, OP, COMBINE) \ +uint64_t HELPER(NAME)(CPURISCVState *env, uint32_t rs1, uint32_t rs2, \ + uint64_t dest) \ +{ \ + E1TYPE s1_0 =3D (E1TYPE)EXTRACT(rs1, OFFSET10); = \ + E1TYPE s1_1 =3D (E1TYPE)EXTRACT(rs1, OFFSET11); = \ + E2TYPE s2_0 =3D (E2TYPE)EXTRACT(rs2, OFFSET20); = \ + E2TYPE s2_1 =3D (E2TYPE)EXTRACT(rs2, OFFSET21); = \ + DTYPE d =3D (DTYPE)dest; = \ + PTYPE prod0 =3D OP(s1_0, s2_0); = \ + PTYPE prod1 =3D OP(s1_1, s2_1); = \ + \ + return COMBINE((uint64_t)d, (uint64_t)prod0, (uint64_t)prod1); \ +} + +/* + * Generate an RV32 widening-left-shift helper. rs1 supplies narrow lanes + * and rs2 carries the immediate or scalar shift amount masked by SHMASK. + * Used for PWSLL[I].B/H, PWSLA[I].B/H, WSLL[I], and WSLA[I]. + */ +#define GEN_PSIMD_WIDEN_SHIFT(NAME, ETYPE, WTYPE, OTYPE, ELEMS, IBITS, \ + OBITS, IMASK, SHMASK) \ +uint64_t HELPER(NAME)(CPURISCVState *env, uint32_t rs1, uint32_t rs2) \ +{ \ + uint64_t rd =3D 0; = \ + uint8_t shamt =3D rs2 & (SHMASK); = \ + \ + for (int i =3D 0; i < (ELEMS); i++) { = \ + ETYPE e1 =3D (ETYPE)((rs1 >> (i * (IBITS))) & (IMASK)); = \ + WTYPE res =3D (WTYPE)e1 * ((WTYPE)1 << shamt); = \ + rd |=3D ((uint64_t)(OTYPE)res) << (i * (OBITS)); = \ + } \ + return rd; \ +} + +/* + * Generate an RV32 widening-interleave helper. rs1 and rs2 supply packed + * lanes that alternate in the 64-bit result according to STRIDE. Used for + * WZIP8P and WZIP16P. + */ +#define GEN_PSIMD_DW_ZIP(NAME, EXTRACT, ELEMS, STRIDE, BITS) \ +uint64_t HELPER(NAME)(CPURISCVState *env, uint32_t rs1, uint32_t rs2) \ +{ \ + uint64_t rd =3D 0; = \ + \ + for (int i =3D 0; i < (ELEMS); i++) { = \ + uint64_t e1 =3D (uint64_t)EXTRACT(rs1, i) << ((STRIDE) * i); = \ + uint64_t e2 =3D (uint64_t)EXTRACT(rs2, i) = \ + << ((STRIDE) * i + (BITS)); \ + rd |=3D e2 | e1; = \ + } \ + return rd; \ +} + +/* + * Generate an RV32 doubleword reduction-sum helper. rs1_lo and rs1_hi fo= rm + * the packed 64-bit source and rs2 supplies the initial accumulator. Used + * for PREDSUM.DBS/DHS and their unsigned variants. + */ +#define GEN_PSIMD_DW_REDSUM(NAME, SUMTYPE, INITTYPE, ETYPE, EXTRACT, \ + ELEMS) \ +uint32_t HELPER(NAME)(CPURISCVState *env, uint32_t rs1_lo, \ + uint32_t rs1_hi, uint32_t rs2) \ +{ \ + SUMTYPE sum =3D (INITTYPE)rs2; = \ + uint64_t s1 =3D ((uint64_t)rs1_hi << 32) | rs1_lo; = \ + \ + for (int i =3D 0; i < (ELEMS); i++) { = \ + sum +=3D (ETYPE)EXTRACT(s1, i); = \ + } \ + return (uint32_t)sum; \ +} + +/* + * Generate an RV32 narrowing logical-right-shift helper. s1 contains wide + * source lanes and shamt carries the immediate or scalar shift amount. U= sed + * for PNSRLI.B/H, PNSRL.BS/HS, NSRLI, and NSRL. + */ +#define GEN_PSIMD_NARROW_SRL(NAME, ETYPE, OTYPE, ELEMS, IBITS, OBITS, \ + IMASK, SHMASK) \ +uint32_t HELPER(NAME)(CPURISCVState *env, uint64_t s1, uint32_t shamt) \ +{ \ + uint32_t rd =3D 0; = \ + uint8_t shift =3D shamt & (SHMASK); = \ + \ + for (int i =3D 0; i < (ELEMS); i++) { = \ + ETYPE e1 =3D (ETYPE)((s1 >> (i * (IBITS))) & (IMASK)); = \ + OTYPE result =3D (OTYPE)(e1 >> shift); = \ + rd |=3D ((uint32_t)result) << (i * (OBITS)); = \ + } \ + return rd; \ +} + +/* + * Generate an RV32 narrowing arithmetic-right-shift helper. s1 contains + * signed wide lanes and shamt carries the immediate or scalar shift amoun= t. + * Used for PNSRAI.B/H and PNSRA.BS. + */ +#define GEN_PSIMD_NARROW_SRA_PACK(NAME, ETYPE, STYPE, OTYPE, ELEMS, \ + IBITS, OBITS, IMASK, SHMASK) \ +uint32_t HELPER(NAME)(CPURISCVState *env, uint64_t s1, uint32_t shamt) \ +{ \ + uint32_t rd =3D 0; = \ + uint8_t shift =3D shamt & (SHMASK); = \ + \ + for (int i =3D 0; i < (ELEMS); i++) { = \ + ETYPE e1 =3D (ETYPE)((s1 >> (i * (IBITS))) & (IMASK)); = \ + STYPE shx =3D (STYPE)e1 >> shift; = \ + OTYPE result =3D (OTYPE)shx; = \ + rd |=3D ((uint32_t)result) << (i * (OBITS)); = \ + } \ + return rd; \ +} + +/* + * Generate an RV32 rounded narrowing arithmetic-shift helper. s1 contains + * signed wide lanes and shamt carries the immediate or scalar shift amoun= t. + * Used for PNSRARI.B/H and PNSRAR.BS. + */ +#define GEN_PSIMD_NARROW_RNDSRA_PACK(NAME, ETYPE, STYPE, OTYPE, ELEMS, \ + IBITS, OBITS, IMASK, SHMASK, RMASK) \ +uint32_t HELPER(NAME)(CPURISCVState *env, uint64_t s1, uint32_t shamt) \ +{ \ + uint32_t rd =3D 0; = \ + uint8_t shift =3D shamt & (SHMASK); = \ + \ + for (int i =3D 0; i < (ELEMS); i++) { = \ + ETYPE e1 =3D (ETYPE)((s1 >> (i * (IBITS))) & (IMASK)); = \ + STYPE e1_s =3D (STYPE)e1; = \ + uint64_t shx =3D (((uint64_t)e1_s << 1) >> shift) & (RMASK); = \ + OTYPE result =3D (OTYPE)((shx + 1) >> 1); = \ + rd |=3D ((uint32_t)result) << (i * (OBITS)); = \ + } \ + return rd; \ +} + +/* + * Generate an RV32 signed narrowing-clip helper. s1 contains signed wide + * lanes and shamt supplies the immediate or scalar right shift; clipping + * sets vxsat. Used for PNCLIPI.B and PNCLIP.BS/HS. + */ +#define GEN_PSIMD_NCLIP_SIGNED_PACK(NAME, ETYPE, STYPE, CTYPE, OTYPE, \ + ELEMS, IBITS, OBITS, IMASK, SHMASK, \ + MIN, MAX, MIN_RES, MAX_RES) \ +uint32_t HELPER(NAME)(CPURISCVState *env, uint64_t s1, uint32_t shamt) \ +{ \ + uint32_t rd =3D 0; = \ + uint8_t shift =3D shamt & (SHMASK); = \ + int sat =3D 0; = \ + \ + for (int i =3D 0; i < (ELEMS); i++) { = \ + ETYPE e1 =3D (ETYPE)((s1 >> (i * (IBITS))) & (IMASK)); = \ + CTYPE shx =3D (CTYPE)((STYPE)e1 >> shift); = \ + OTYPE result; \ + \ + if (shx < (MIN)) { \ + sat =3D 1; = \ + result =3D (MIN_RES); = \ + } else if (shx > (MAX)) { \ + sat =3D 1; = \ + result =3D (MAX_RES); = \ + } else { \ + result =3D (OTYPE)shx; = \ + } \ + rd |=3D ((uint32_t)result) << (i * (OBITS)); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +/* + * Generate an RV32 rounded signed narrowing-clip helper. s1 contains sig= ned + * wide lanes and shamt supplies the immediate or scalar right shift; + * clipping sets vxsat. Used for PNCLIPRI.B and PNCLIPR.BS/HS. + */ +#define GEN_PSIMD_NCLIPR_SIGNED_PACK(NAME, ETYPE, STYPE, CTYPE, OTYPE, \ + ELEMS, IBITS, OBITS, IMASK, SHMASK, \ + RMASK, MIN, MAX, MIN_RES, MAX_RES) \ +uint32_t HELPER(NAME)(CPURISCVState *env, uint64_t s1, uint32_t shamt) \ +{ \ + uint32_t rd =3D 0; = \ + uint8_t shift =3D shamt & (SHMASK); = \ + int sat =3D 0; = \ + \ + for (int i =3D 0; i < (ELEMS); i++) { = \ + ETYPE e1 =3D (ETYPE)((s1 >> (i * (IBITS))) & (IMASK)); = \ + STYPE e1_s =3D (STYPE)e1; = \ + uint64_t shx =3D (((uint64_t)e1_s << 1) >> shift) & (RMASK); = \ + CTYPE round_shx =3D (CTYPE)((shx + 1) >> 1); = \ + OTYPE result; \ + \ + if (round_shx < (MIN)) { \ + sat =3D 1; = \ + result =3D (MIN_RES); = \ + } else if (round_shx > (MAX)) { \ + sat =3D 1; = \ + result =3D (MAX_RES); = \ + } else { \ + result =3D (OTYPE)round_shx; = \ + } \ + rd |=3D ((uint32_t)result) << (i * (OBITS)); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +/* + * Generate an RV32 unsigned narrowing-clip helper. s1 contains unsigned + * wide lanes and shamt supplies the immediate or scalar right shift; + * clipping sets vxsat. Used for PNCLIPIU.B and PNCLIPU.BS/HS. + */ +#define GEN_PSIMD_NCLIP_UNSIGNED_PACK(NAME, ETYPE, WTYPE, OTYPE, ELEMS, \ + IBITS, OBITS, IMASK, SHMASK, MAX) \ +uint32_t HELPER(NAME)(CPURISCVState *env, uint64_t s1, uint32_t shamt) \ +{ \ + uint32_t rd =3D 0; = \ + uint8_t shift =3D shamt & (SHMASK); = \ + int sat =3D 0; = \ + \ + for (int i =3D 0; i < (ELEMS); i++) { = \ + ETYPE e1 =3D (ETYPE)((s1 >> (i * (IBITS))) & (IMASK)); = \ + WTYPE shx =3D (WTYPE)e1 >> shift; = \ + OTYPE result; \ + \ + if (shx > (MAX)) { \ + sat =3D 1; = \ + result =3D (OTYPE)(MAX); = \ + } else { \ + result =3D (OTYPE)shx; = \ + } \ + rd |=3D ((uint32_t)result) << (i * (OBITS)); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +/* + * Generate an RV32 rounded unsigned narrowing-clip helper. s1 contains + * unsigned wide lanes and shamt supplies the immediate or scalar shift; + * clipping sets vxsat. Used for PNCLIPRIU.B and PNCLIPRU.BS/HS. + */ +#define GEN_PSIMD_NCLIPR_UNSIGNED_PACK(NAME, ETYPE, WTYPE, OTYPE, ELEMS, \ + IBITS, OBITS, IMASK, SHMASK, MAX) \ +uint32_t HELPER(NAME)(CPURISCVState *env, uint64_t s1, uint32_t shamt) \ +{ \ + uint32_t rd =3D 0; = \ + uint8_t shift =3D shamt & (SHMASK); = \ + int sat =3D 0; = \ + \ + for (int i =3D 0; i < (ELEMS); i++) { = \ + ETYPE e1 =3D (ETYPE)((s1 >> (i * (IBITS))) & (IMASK)); = \ + WTYPE shx =3D ((WTYPE)e1 << 1) >> shift; = \ + WTYPE round_shx =3D (shx + 1) >> 1; = \ + OTYPE result; \ + \ + if (round_shx > (MAX)) { \ + sat =3D 1; = \ + result =3D (OTYPE)(MAX); = \ + } else { \ + result =3D (OTYPE)round_shx; = \ + } \ + rd |=3D ((uint32_t)result) << (i * (OBITS)); = \ + } \ + \ + if (sat) { \ + env->vxsat =3D 1; = \ + } \ + return rd; \ +} + +/* + * These scalar RV32 forms conceptually shift a sign-extended 96-bit value. + * The extra bit in the rounding form preserves the bit below the result + * before adding one, so rounding also works for the largest shift count. + */ +/* + * Generate an RV32 scalar narrowing arithmetic-shift helper. s1 is treat= ed + * as the low 64 bits of a sign-extended 96-bit value and shamt supplies t= he + * shift amount. Used for NSRAI and NSRA. + */ +#define GEN_PSIMD_NARROW_SRA(NAME) \ +uint32_t HELPER(NAME)(CPURISCVState *env, uint64_t s1, uint32_t shamt) \ +{ \ + __int128_t s1_s96 =3D (int64_t)s1; = \ + \ + return (uint32_t)(s1_s96 >> (shamt & 0x3F)) & 0xFFFFFFFF; \ +} + +/* + * Generate an RV32 rounded scalar narrowing-shift helper. s1 is sign-ext= ended + * to 96 bits and shamt supplies the shift amount; a 97th bit preserves + * rounding. Used for NSRARI and NSRAR. + */ +#define GEN_PSIMD_NARROW_RNDSRA(NAME) \ +uint32_t HELPER(NAME)(CPURISCVState *env, uint64_t s1, uint32_t shamt) \ +{ \ + __int128_t s1_s96 =3D (int64_t)s1; = \ + __uint128_t shx_97bit =3D ((__uint128_t)s1_s96 << 1); = \ + uint64_t shx =3D (uint64_t)(shx_97bit >> (shamt & 0x3F)) & 0x1FFFFFFFF= ; \ + \ + return (uint32_t)((shx + 1) >> 1); \ +} + +/* + * Generate a narrowing-helper alias. s1 and shamt are forwarded unchanged + * to TARGET. Used where immediate and scalar forms share PNSRA.HS, + * PNSRAR.HS, PNCLIP.HS, PNCLIPR.HS, PNCLIPU.HS, or PNCLIPRU.HS semantics. + */ +#define GEN_PSIMD_NARROW_ALIAS(NAME, TARGET) \ +uint32_t HELPER(NAME)(CPURISCVState *env, uint64_t s1, uint32_t shamt) \ +{ \ + return HELPER(TARGET)(env, s1, shamt); \ +} + +typedef struct { + __uint128_t low; + uint8_t high; +} PsImdUint129; + +/* A 129-bit unsigned temporary retains the rounding bit without overflow.= */ +static inline PsImdUint129 psimd_uint129_lshift1(__int128_t val) +{ + PsImdUint129 result; + __uint128_t uval =3D (__uint128_t)val; + + result.low =3D uval << 1; + result.high =3D (uval >> 127) & 0x1; + return result; +} + +static inline PsImdUint129 psimd_uint129_rshift(PsImdUint129 val, + uint32_t shamt) +{ + PsImdUint129 result; + + if (shamt =3D=3D 0) { + return val; + } else if (shamt >=3D 129) { + result.low =3D 0; + result.high =3D 0; + } else if (shamt =3D=3D 128) { + result.low =3D val.high; + result.high =3D 0; + } else { + result.low =3D (val.low >> shamt) | + ((__uint128_t)val.high << (128 - shamt)); + result.high =3D val.high >> shamt; + } + return result; +} + +/* + * Generate an RV32 scalar signed narrowing-clip helper. s1 is the signed + * 64-bit source and shamt supplies the right-shift amount; clipping sets + * vxsat. Used for NCLIPI and NCLIP. + */ +#define GEN_PSIMD_NCLIP(NAME) \ +uint32_t HELPER(NAME)(CPURISCVState *env, uint64_t s1, uint32_t shamt) \ +{ \ + __int128_t s1_s128 =3D (__int128_t)((int64_t)s1); = \ + int64_t shx =3D (int64_t)(s1_s128 >> (shamt & 0x3F)); = \ + \ + if (shx < -2147483648LL) { \ + env->vxsat =3D 1; = \ + return 0x80000000U; \ + } else if (shx > 2147483647LL) { \ + env->vxsat =3D 1; = \ + return 0x7FFFFFFFU; \ + } else { \ + return (uint32_t)(shx & 0xFFFFFFFF); \ + } \ +} + +/* + * Generate an RV32 rounded signed narrowing-clip helper. s1 is the signed + * 64-bit source and shamt supplies the right-shift amount; clipping sets + * vxsat. Used for NCLIPRI and NCLIPR. + */ +#define GEN_PSIMD_NCLIPR(NAME) \ +uint32_t HELPER(NAME)(CPURISCVState *env, uint64_t s1, uint32_t shamt) \ +{ \ + __int128_t s1_s128 =3D (__int128_t)((int64_t)s1); = \ + PsImdUint129 shx_129bit =3D psimd_uint129_lshift1(s1_s128); = \ + PsImdUint129 shx =3D psimd_uint129_rshift(shx_129bit, shamt & 0x3F); = \ + int64_t round_shx =3D (int64_t)((shx.low + 1) >> 1); = \ + \ + if (round_shx < -2147483648LL) { \ + env->vxsat =3D 1; = \ + return 0x80000000U; \ + } else if (round_shx > 2147483647LL) { \ + env->vxsat =3D 1; = \ + return 0x7FFFFFFFU; \ + } else { \ + return (uint32_t)round_shx; \ + } \ +} + +/* + * Generate an RV32 scalar unsigned narrowing-clip helper. s1 is the + * unsigned 64-bit source and shamt supplies the right-shift amount; clipp= ing + * sets vxsat. Used for NCLIPIU and NCLIPU. + */ +#define GEN_PSIMD_NCLIPU(NAME) \ +uint32_t HELPER(NAME)(CPURISCVState *env, uint64_t s1, uint32_t shamt) \ +{ \ + uint64_t shx =3D s1 >> (shamt & 0x3F); = \ + \ + if (shx > 4294967295ULL) { \ + env->vxsat =3D 1; = \ + return 0xFFFFFFFFU; \ + } else { \ + return (uint32_t)(shx & 0xFFFFFFFF); \ + } \ +} + +/* + * Generate an RV32 rounded unsigned narrowing-clip helper. s1 is the + * unsigned 64-bit source and shamt supplies the right-shift amount; clipp= ing + * sets vxsat. Used for NCLIPRIU and NCLIPRU. + */ +#define GEN_PSIMD_NCLIPRU(NAME) \ +uint32_t HELPER(NAME)(CPURISCVState *env, uint64_t s1, uint32_t shamt) \ +{ \ + __uint128_t shx_65bit =3D (__uint128_t)s1 << 1; = \ + __uint128_t shx =3D shx_65bit >> (shamt & 0x3F); = \ + uint64_t round_shx =3D (shx + 1) >> 1; = \ + \ + if (round_shx > 4294967295ULL) { \ + env->vxsat =3D 1; = \ + return 0xFFFFFFFFU; \ + } else { \ + return (uint32_t)(round_shx & 0xFFFFFFFF); \ + } \ +} --=20 2.34.1 From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789542704607817.5891684198881; Wed, 16 Sep 2026 00:11:44 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jki-0005iC-0e; Wed, 16 Sep 2026 03:08:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jkc-0005dv-Ry; Wed, 16 Sep 2026 03:08:15 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jkU-0008JE-QR; Wed, 16 Sep 2026 03:08:14 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S5; Wed, 16 Sep 2026 15:08:01 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 03/19] target/riscv: Add packed SIMD arithmetic instructions Date: Wed, 16 Sep 2026 07:07:05 +0000 Message-Id: <20260916070721.3279229-4-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S5 X-Coremail-Antispam: 1UD129KBjvAXoWfXFW8Gr48Cr1xGFy7Jry3twb_yoW5ZrW8Ko WfKr45Cr1xt343ZwnIkw4xX3srAF97uwn7WrWUXr4UuasxJr12kr17Jw1xZ3WxAry5KrWf Ga93Wrn8tFn3WFnrn29KB7ZKAUJUUUUr529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUOg7AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r1rM28IrcIa0x kI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l84AC jcxK6xIIjxv20xvE14v26ryj6F1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4UJVWxJr 1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE3s1l n4kS14v26r1Y6r17M2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F4 0Ex7xfMcIj6xIIjxv20xvE14v26r126r1DMcIj6I8E87Iv67AKxVWxJVW8Jr1lOx8S6xCa FVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI4 02YVCY1x02628vn2kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCF x2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14 v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY 67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UMIIF0xvE42xK8VAvwI 8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWxJVW8Jr1lIxAIcVC2z280aVCY1x0267AK xVW8Jr0_Cr1UYxBIdaVFxhVjvjDU0xZFpf9x0JUJ8n5UUUUU= X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542704890158500 Content-Type: text/plain; charset="utf-8" Implement addition, subtraction, shift-and-add, and saturation/clipping operations. Cover signed and unsigned, saturating and non-saturating variants across the supported element widths. The implementation includes four components: instruction decodings, translation functions, helper declarations and helper implementations. Create trans_rvp.c.inc and define the GEN_SIMD_TRANS_* macros used by the P extension instruction groups added in this and subsequent patches. These macros provide common translation paths for checking P extension availability and invoking helpers. Update vxsat when a saturating operation overflows. Signed-off-by: Molly Chen --- target/riscv/helper.h | 41 ++ target/riscv/insn32.decode | 63 +++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 553 ++++++++++++++++++++ target/riscv/tcg/psimd_helper.c | 116 ++++ target/riscv/tcg/translate.c | 4 + 5 files changed, 777 insertions(+) create mode 100644 target/riscv/tcg/insn_trans/trans_rvp.c.inc diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 4fc2d3a1559..23741b2e827 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1357,3 +1357,44 @@ DEF_HELPER_1(ssamoswap_disabled, void, env) =20 /* Zalrsc SC write probe */ DEF_HELPER_FLAGS_3(sc_probe_write, TCG_CALL_NO_WG, void, env, tl, tl) + +/* Packed SIMD */ +/* Packed SIMD - Arithmetic Operations(Non-Saturating and Saturating) */ +DEF_HELPER_3(padd_b, tl, env, tl, tl) +DEF_HELPER_3(padd_h, tl, env, tl, tl) +DEF_HELPER_3(padd_w, i64, env, i64, i64) +DEF_HELPER_3(padd_bs, tl, env, tl, tl) +DEF_HELPER_3(padd_hs, tl, env, tl, tl) +DEF_HELPER_3(padd_ws, i64, env, i64, i64) +DEF_HELPER_3(psub_b, tl, env, tl, tl) +DEF_HELPER_3(psub_h, tl, env, tl, tl) +DEF_HELPER_3(psub_w, i64, env, i64, i64) +DEF_HELPER_3(psh1add_h, tl, env, tl, tl) +DEF_HELPER_3(psh1add_w, i64, env, i64, i64) +DEF_HELPER_3(pssh1sadd_h, tl, env, tl, tl) +DEF_HELPER_3(pssh1sadd_w, i64, env, i64, i64) +DEF_HELPER_3(ssh1sadd, i32, env, i32, i32) +DEF_HELPER_3(psadd_b, tl, env, tl, tl) +DEF_HELPER_3(psadd_h, tl, env, tl, tl) +DEF_HELPER_3(psadd_w, i64, env, i64, i64) +DEF_HELPER_3(psaddu_b, tl, env, tl, tl) +DEF_HELPER_3(psaddu_h, tl, env, tl, tl) +DEF_HELPER_3(psaddu_w, i64, env, i64, i64) +DEF_HELPER_3(sadd, i32, env, i32, i32) +DEF_HELPER_3(saddu, i32, env, i32, i32) +DEF_HELPER_3(pssub_b, tl, env, tl, tl) +DEF_HELPER_3(pssub_h, tl, env, tl, tl) +DEF_HELPER_3(pssub_w, i64, env, i64, i64) +DEF_HELPER_3(pssubu_b, tl, env, tl, tl) +DEF_HELPER_3(pssubu_h, tl, env, tl, tl) +DEF_HELPER_3(pssubu_w, i64, env, i64, i64) +DEF_HELPER_3(ssub, i32, env, i32, i32) +DEF_HELPER_3(ssubu, i32, env, i32, i32) +DEF_HELPER_3(psati_h, tl, env, tl, tl) +DEF_HELPER_3(pusati_h, tl, env, tl, tl) +DEF_HELPER_3(psati_w, i64, env, i64, i64) +DEF_HELPER_3(pusati_w, i64, env, i64, i64) +DEF_HELPER_3(sati_32, i32, env, i32, i32) +DEF_HELPER_3(usati_32, i32, env, i32, i32) +DEF_HELPER_3(sati_64, i64, env, i64, i64) +DEF_HELPER_3(usati_64, i64, env, i64, i64) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index aa02dae3c90..afd096cf5db 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -40,6 +40,9 @@ %imm_z6 26:1 15:5 %imm_mop5 30:1 26:2 20:2 %imm_mop3 30:1 26:2 +%imm_p_ui16 20:4 +%imm_p_ui32 20:5 +%imm_p_ui64 20:6 =20 # Argument sets: &empty @@ -60,6 +63,7 @@ &k_aes shamt rs2 rs1 rd &mop5 imm rd rs1 &mop3 imm rd rs1 rs2 +&p_ui imm rs1 rd =20 # Formats 32: @r ....... ..... ..... ... ..... ....... &r %rs2 %r= s1 %rd @@ -105,6 +109,10 @@ @mop5 . . .. .. .... .. ..... ... ..... ....... &mop5 imm=3D%imm_mop5 %rd = %rs1 @mop3 . . .. .. . ..... ..... ... ..... ....... &mop3 imm=3D%imm_mop3 %rd = %rs1 %rs2 =20 +@p_ui16 ..... .... ... ..... ... ..... ....... &i imm=3D%imm_p_ui16 %rs1 %= rd +@p_ui32 ..... .... ... ..... ... ..... ....... &i imm=3D%imm_p_ui32 %rs1 %= rd +@p_ui64 ..... .... ... ..... ... ..... ....... &i imm=3D%imm_p_ui64 %rs1 %= rd + # Formats 64: @sh5 ....... ..... ..... ... ..... ....... &shift shamt=3D%sh5 = %rs1 %rd =20 @@ -1086,3 +1094,58 @@ sb_aqrl 00111 . . ..... ..... 000 ..... 0101111 @at= om_st sh_aqrl 00111 . . ..... ..... 001 ..... 0101111 @atom_st sw_aqrl 00111 . . ..... ..... 010 ..... 0101111 @atom_st sd_aqrl 00111 . . ..... ..... 011 ..... 0101111 @atom_st + +# *** P Experimental Extension Version v020 *** +# Packed SIMD - Arithmetic Operations(Non-Saturating and Saturating) +padd_b 1000010 ..... ..... 000 ..... 0111011 @r +padd_h 1000000 ..... ..... 000 ..... 0111011 @r +padd_w 1000001 ..... ..... 000 ..... 0111011 @r +padd_bs 1001110 ..... ..... 010 ..... 0011011 @r +padd_hs 1001100 ..... ..... 010 ..... 0011011 @r +padd_ws 1001101 ..... ..... 010 ..... 0011011 @r +psub_b 1100010 ..... ..... 000 ..... 0111011 @r +psub_h 1100000 ..... ..... 000 ..... 0111011 @r +psub_w 1100001 ..... ..... 000 ..... 0111011 @r +psh1add_h 1010000 ..... ..... 010 ..... 0111011 @r +psh1add_w 1010001 ..... ..... 010 ..... 0111011 @r +pssh1sadd_h 1011000 ..... ..... 010 ..... 0111011 @r +{ + ssh1sadd 1011001 ..... ..... 010 ..... 0111011 @r + pssh1sadd_w 1011001 ..... ..... 010 ..... 0111011 @r +} +psadd_b 1001010 ..... ..... 000 ..... 0111011 @r +psadd_h 1001000 ..... ..... 000 ..... 0111011 @r +{ + sadd 1001001 ..... ..... 000 ..... 0111011 @r + psadd_w 1001001 ..... ..... 000 ..... 0111011 @r +} +psaddu_b 1011010 ..... ..... 000 ..... 0111011 @r +psaddu_h 1011000 ..... ..... 000 ..... 0111011 @r +{ + saddu 1011001 ..... ..... 000 ..... 0111011 @r + psaddu_w 1011001 ..... ..... 000 ..... 0111011 @r +} +pssub_b 1101010 ..... ..... 000 ..... 0111011 @r +pssub_h 1101000 ..... ..... 000 ..... 0111011 @r +{ + ssub 1101001 ..... ..... 000 ..... 0111011 @r + pssub_w 1101001 ..... ..... 000 ..... 0111011 @r +} +pssubu_b 1111010 ..... ..... 000 ..... 0111011 @r +pssubu_h 1111000 ..... ..... 000 ..... 0111011 @r +{ + ssubu 1111001 ..... ..... 000 ..... 0111011 @r + pssubu_w 1111001 ..... ..... 000 ..... 0111011 @r +} +psati_h 11100 001.... ..... 100 ..... 0011011 @p_ui16 +pusati_h 10100 001.... ..... 100 ..... 0011011 @p_ui16 +{ + sati_32 11100 01..... ..... 100 ..... 0011011 @p_ui32 + psati_w 11100 01..... ..... 100 ..... 0011011 @p_ui32 +} +{ + usati_32 10100 01..... ..... 100 ..... 0011011 @p_ui32 + pusati_w 10100 01..... ..... 100 ..... 0011011 @p_ui32 +} +sati_64 111001 ...... ..... 100 ..... 0011011 @p_ui64 +usati_64 101001 ...... ..... 100 ..... 0011011 @p_ui64 diff --git a/target/riscv/tcg/insn_trans/trans_rvp.c.inc b/target/riscv/tcg= /insn_trans/trans_rvp.c.inc new file mode 100644 index 00000000000..0c91aac5060 --- /dev/null +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -0,0 +1,553 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* RISC-V translation routines for the P Standard Extensions. */ +/* Copyright (c) 2026 ISRC ISCAS. */ + +static bool require_rvp(DisasContext *ctx) +{ + uint32_t opcode =3D ctx->opcode & 0x7f; + + if (!has_ext(ctx, RVP)) { + return false; + } + + /* + * P_VXSAT_EXCP is encoded in the TB flags only when P is implemented + * without Zve*, where stateen0.VXSAT controls the whole OP-32 and + * OP-IMM-32 P instruction spaces. When Zve* is present, this field + * remains NONE and vxsat access is checked by the VS path instead. + */ + if ((opcode =3D=3D 0x3b || opcode =3D=3D 0x1b) && + ctx->p_vxsat_excp !=3D P_VXSAT_EXCP_NONE) { + ctx->virt_inst_excp =3D + ctx->p_vxsat_excp =3D=3D P_VXSAT_EXCP_VIRTUAL; + return false; + } + + return true; +} + +static bool prepare_rvp_vxsat(DisasContext *ctx) +{ + if (!ctx->cfg_ptr->ext_zve32x) { + return true; + } + + if (ctx->mstatus_vs =3D=3D EXT_STATUS_DISABLED) { + return false; + } + + mark_vs_dirty(ctx); + return true; +} + +#define REQUIRE_RVP(ctx) do { \ + if (!require_rvp(ctx)) { \ + return false; \ + } \ +} while (0) + +#define GEN_SIMD_TRANS_BODY(NAME, VXSAT) \ +do { \ + REQUIRE_RVP(ctx); \ + if (VXSAT && !prepare_rvp_vxsat(ctx)) { \ + return false; \ + } \ + TCGv src1 =3D get_gpr(ctx, a->rs1, EXT_NONE); \ + TCGv src2 =3D get_gpr(ctx, a->rs2, EXT_NONE); \ + TCGv dest =3D dest_gpr(ctx, a->rd); \ + gen_helper_##NAME(dest, tcg_env, src1, src2); \ + gen_set_gpr(ctx, a->rd, dest); \ + return true; \ +} while (0) + +#define GEN_SIMD_TRANS_UNAVAILABLE_32(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + return false; \ +} + +#define GEN_SIMD_TRANS_UNAVAILABLE_64(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_64BIT(ctx); \ + return false; \ +} + +#define GEN_SIMD_TRANS(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + GEN_SIMD_TRANS_BODY(NAME, false); \ +} + +#define GEN_SIMD_TRANS_VXSAT(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + GEN_SIMD_TRANS_BODY(NAME, true); \ +} + +#if defined(TARGET_RISCV32) +#define GEN_SIMD_TRANS_32(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + GEN_SIMD_TRANS_BODY(NAME, false); \ +} +#define GEN_SIMD_TRANS_32_VXSAT(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + GEN_SIMD_TRANS_BODY(NAME, true); \ +} +#else +#define GEN_SIMD_TRANS_32(NAME) GEN_SIMD_TRANS_UNAVAILABLE_32(NAME) +#define GEN_SIMD_TRANS_32_VXSAT(NAME) GEN_SIMD_TRANS_UNAVAILABLE_32(NAME) +#endif + +#if defined(TARGET_RISCV32) +#define GEN_SIMD_TRANS_64(NAME) GEN_SIMD_TRANS_UNAVAILABLE_64(NAME) +#define GEN_SIMD_TRANS_64_VXSAT(NAME) GEN_SIMD_TRANS_UNAVAILABLE_64(NAME) +#else +#define GEN_SIMD_TRANS_64(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_64BIT(ctx); \ + GEN_SIMD_TRANS_BODY(NAME, false); \ +} +#define GEN_SIMD_TRANS_64_VXSAT(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_64BIT(ctx); \ + GEN_SIMD_TRANS_BODY(NAME, true); \ +} +#endif + +#define GEN_SIMD_TRANS_ACC_BODY(NAME, VXSAT) \ +do { \ + REQUIRE_RVP(ctx); \ + if (VXSAT && !prepare_rvp_vxsat(ctx)) { \ + return false; \ + } \ + TCGv src1 =3D get_gpr(ctx, a->rs1, EXT_NONE); \ + TCGv src2 =3D get_gpr(ctx, a->rs2, EXT_NONE); \ + TCGv acc =3D get_gpr(ctx, a->rd, EXT_NONE); \ + TCGv t =3D tcg_temp_new(); \ + gen_helper_##NAME(t, tcg_env, src1, src2, acc); \ + gen_set_gpr(ctx, a->rd, t); \ + return true; \ +} while (0) + +#define GEN_SIMD_TRANS_ACC(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + GEN_SIMD_TRANS_ACC_BODY(NAME, false); \ +} + +#define GEN_SIMD_TRANS_ACC_VXSAT(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + GEN_SIMD_TRANS_ACC_BODY(NAME, true); \ +} + +#if defined(TARGET_RISCV32) +#define GEN_SIMD_TRANS_ACC_32(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + GEN_SIMD_TRANS_ACC_BODY(NAME, false); \ +} +#else +#define GEN_SIMD_TRANS_ACC_32(NAME) GEN_SIMD_TRANS_UNAVAILABLE_32(NAME) +#endif + +#if defined(TARGET_RISCV32) +#define GEN_SIMD_TRANS_ACC_64(NAME) GEN_SIMD_TRANS_UNAVAILABLE_64(NAME) +#else +#define GEN_SIMD_TRANS_ACC_64(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_64BIT(ctx); \ + GEN_SIMD_TRANS_ACC_BODY(NAME, false); \ +} +#endif + +#define GEN_SIMD_TRANS_R1_BODY(NAME, VXSAT) \ +do { \ + REQUIRE_RVP(ctx); \ + if (VXSAT && !prepare_rvp_vxsat(ctx)) { \ + return false; \ + } \ + TCGv src1 =3D get_gpr(ctx, a->rs1, EXT_NONE); \ + TCGv dest =3D dest_gpr(ctx, a->rd); \ + gen_helper_##NAME(dest, tcg_env, src1); \ + gen_set_gpr(ctx, a->rd, dest); \ + return true; \ +} while (0) + +#define GEN_SIMD_TRANS_R1(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + GEN_SIMD_TRANS_R1_BODY(NAME, false); \ +} + +#define GEN_SIMD_TRANS_R1_VXSAT(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + GEN_SIMD_TRANS_R1_BODY(NAME, true); \ +} + +#if defined(TARGET_RISCV32) +#define GEN_SIMD_TRANS_R1_64(NAME) GEN_SIMD_TRANS_UNAVAILABLE_64(NAME) +#define GEN_SIMD_TRANS_R1_64_VXSAT(NAME) GEN_SIMD_TRANS_UNAVAILABLE_64(NAM= E) +#else +#define GEN_SIMD_TRANS_R1_64(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_64BIT(ctx); \ + GEN_SIMD_TRANS_R1_BODY(NAME, false); \ +} +#define GEN_SIMD_TRANS_R1_64_VXSAT(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_64BIT(ctx); \ + GEN_SIMD_TRANS_R1_BODY(NAME, true); \ +} +#endif + +#define GEN_SIMD_TRANS_IMM_BODY(NAME, VXSAT) \ +do { \ + REQUIRE_RVP(ctx); \ + if (VXSAT && !prepare_rvp_vxsat(ctx)) { \ + return false; \ + } \ + TCGv src1 =3D get_gpr(ctx, a->rs1, EXT_NONE); \ + TCGv imm =3D tcg_constant_tl(a->imm); \ + TCGv dest =3D dest_gpr(ctx, a->rd); \ + gen_helper_##NAME(dest, tcg_env, src1, imm); \ + gen_set_gpr(ctx, a->rd, dest); \ + return true; \ +} while (0) + +#define GEN_SIMD_TRANS_IMM(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + GEN_SIMD_TRANS_IMM_BODY(NAME, false); \ +} + +#define GEN_SIMD_TRANS_IMM_VXSAT(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + GEN_SIMD_TRANS_IMM_BODY(NAME, true); \ +} + +#if defined(TARGET_RISCV32) +#define GEN_SIMD_TRANS_IMM_32(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + GEN_SIMD_TRANS_IMM_BODY(NAME, false); \ +} +#define GEN_SIMD_TRANS_IMM_32_VXSAT(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + GEN_SIMD_TRANS_IMM_BODY(NAME, true); \ +} +#else +#define GEN_SIMD_TRANS_IMM_32(NAME) GEN_SIMD_TRANS_UNAVAILABLE_32(NAME) +#define GEN_SIMD_TRANS_IMM_32_VXSAT(NAME) GEN_SIMD_TRANS_UNAVAILABLE_32(NA= ME) +#endif + +#if defined(TARGET_RISCV32) +#define GEN_SIMD_TRANS_IMM_64(NAME) GEN_SIMD_TRANS_UNAVAILABLE_64(NAME) +#define GEN_SIMD_TRANS_IMM_64_VXSAT(NAME) GEN_SIMD_TRANS_UNAVAILABLE_64(NA= ME) +#else +#define GEN_SIMD_TRANS_IMM_64(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_64BIT(ctx); \ + GEN_SIMD_TRANS_IMM_BODY(NAME, false); \ +} +#define GEN_SIMD_TRANS_IMM_64_VXSAT(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_64BIT(ctx); \ + GEN_SIMD_TRANS_IMM_BODY(NAME, true); \ +} +#endif + +#if defined(TARGET_RISCV32) +#define GEN_SIMD_TRANS_REG_PAIR_SCALAR_OP(NAME, SRC2) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + REQUIRE_RVP(ctx); \ + TCGv_i32 src1 =3D get_gpr(ctx, a->rs1, EXT_NONE); \ + TCGv_i32 src2 =3D SRC2; \ + TCGv_i64 t =3D tcg_temp_new_i64(); \ + gen_helper_##NAME(t, tcg_env, src1, src2); \ + set_pair_regs(ctx, a->rd, t); \ + return true; \ +} + +#define GEN_SIMD_TRANS_REG_PAIR_SCALAR(NAME) \ + GEN_SIMD_TRANS_REG_PAIR_SCALAR_OP(NAME, get_gpr(ctx, a->rs2, EXT_NONE)) + +#define GEN_SIMD_TRANS_REG_PAIR_SCALAR_IMM(NAME) \ + GEN_SIMD_TRANS_REG_PAIR_SCALAR_OP(NAME, tcg_constant_i32(a->imm)) +#else +#define GEN_SIMD_TRANS_REG_PAIR_SCALAR(NAME) GEN_SIMD_TRANS_UNAVAILABLE_32= (NAME) +#define GEN_SIMD_TRANS_REG_PAIR_SCALAR_IMM(NAME) GEN_SIMD_TRANS_UNAVAILABL= E_32(NAME) +#endif + +#if defined(TARGET_RISCV32) +#define GEN_SIMD_TRANS_REG_PAIR_OP(INSN, HELPER, SRC2_0, SRC2_1, VXSAT) \ +static bool trans_##INSN(DisasContext *ctx, arg_##INSN * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + REQUIRE_RVP(ctx); \ + if (VXSAT && !prepare_rvp_vxsat(ctx)) { \ + return false; \ + } \ + TCGv src1_0 =3D get_gpr(ctx, pair_reg(a->rs1, false), EXT_NONE); \ + TCGv src2_0 =3D SRC2_0; \ + TCGv dest_0 =3D dest_gpr(ctx, pair_reg(a->rd, false)); \ + TCGv src1_1 =3D get_gpr(ctx, pair_reg(a->rs1, true), EXT_NONE); \ + TCGv src2_1 =3D SRC2_1; \ + TCGv dest_1 =3D dest_gpr(ctx, pair_reg(a->rd, true)); \ + gen_helper_##HELPER(dest_0, tcg_env, src1_0, src2_0); \ + gen_helper_##HELPER(dest_1, tcg_env, src1_1, src2_1); \ + gen_set_gpr(ctx, pair_reg(a->rd, false), dest_0); \ + gen_set_gpr(ctx, pair_reg(a->rd, true), dest_1); \ + return true; \ +} + +#define GEN_SIMD_TRANS_REG_PAIR_LANE(INSN, HELPER) \ + GEN_SIMD_TRANS_REG_PAIR_OP(INSN, HELPER, \ + get_gpr(ctx, pair_reg(a->rs2, false), EXT_NONE), \ + get_gpr(ctx, pair_reg(a->rs2, true), EXT_NONE), false) + +#define GEN_SIMD_TRANS_REG_PAIR_LANE_VXSAT(INSN, HELPER) \ + GEN_SIMD_TRANS_REG_PAIR_OP(INSN, HELPER, \ + get_gpr(ctx, pair_reg(a->rs2, false), EXT_NONE), \ + get_gpr(ctx, pair_reg(a->rs2, true), EXT_NONE), true) + +#define GEN_SIMD_TRANS_REG_PAIR_LANE_IMM(INSN, HELPER) \ + GEN_SIMD_TRANS_REG_PAIR_OP(INSN, HELPER, \ + tcg_constant_tl(a->imm), tcg_constant_tl(a->imm), false) + +#define GEN_SIMD_TRANS_REG_PAIR_LANE_IMM_VXSAT(INSN, HELPER) \ + GEN_SIMD_TRANS_REG_PAIR_OP(INSN, HELPER, \ + tcg_constant_tl(a->imm), tcg_constant_tl(a->imm), true) +#else +#define GEN_SIMD_TRANS_REG_PAIR_LANE(INSN, HELPER) \ + GEN_SIMD_TRANS_UNAVAILABLE_32(INSN) +#define GEN_SIMD_TRANS_REG_PAIR_LANE_VXSAT(INSN, HELPER) \ + GEN_SIMD_TRANS_UNAVAILABLE_32(INSN) +#define GEN_SIMD_TRANS_REG_PAIR_LANE_IMM(INSN, HELPER) \ + GEN_SIMD_TRANS_UNAVAILABLE_32(INSN) +#define GEN_SIMD_TRANS_REG_PAIR_LANE_IMM_VXSAT(INSN, HELPER) \ + GEN_SIMD_TRANS_UNAVAILABLE_32(INSN) +#endif + +#if defined(TARGET_RISCV32) +#define GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR_OP(INSN, HELPER, VXSAT) \ +static bool trans_##INSN(DisasContext *ctx, arg_##INSN * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + REQUIRE_RVP(ctx); \ + if (VXSAT && !prepare_rvp_vxsat(ctx)) { \ + return false; \ + } \ + TCGv src1_0; \ + TCGv src1_1; \ + if (a->rs1 =3D=3D 0) { \ + src1_0 =3D tcg_constant_tl(0); \ + src1_1 =3D tcg_constant_tl(0); \ + } else { \ + src1_0 =3D get_gpr(ctx, pair_reg(a->rs1, false), EXT_NONE); \ + src1_1 =3D get_gpr(ctx, pair_reg(a->rs1, true), EXT_NONE); \ + } \ + TCGv dest_0 =3D tcg_temp_new(); \ + TCGv dest_1 =3D tcg_temp_new(); \ + TCGv src2 =3D get_gpr(ctx, a->rs2, EXT_NONE); \ + gen_helper_##HELPER(dest_0, tcg_env, src1_0, src2); \ + gen_helper_##HELPER(dest_1, tcg_env, src1_1, src2); \ + if (a->rd !=3D 0) { \ + gen_set_gpr(ctx, pair_reg(a->rd, false), dest_0); \ + gen_set_gpr(ctx, pair_reg(a->rd, true), dest_1); \ + } \ + return true; \ +} + +#define GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR(INSN, HELPER) \ + GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR_OP(INSN, HELPER, false) + +#define GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR_VXSAT(INSN, HELPER) \ + GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR_OP(INSN, HELPER, true) +#else +#define GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR(INSN, HELPER) \ + GEN_SIMD_TRANS_UNAVAILABLE_32(INSN) +#define GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR_VXSAT(INSN, HELPER) \ + GEN_SIMD_TRANS_UNAVAILABLE_32(INSN) +#endif + +#if defined(TARGET_RISCV32) +#define GEN_SIMD_TRANS_REG_PAIR_LANE_UNARY_OP(INSN, HELPER, VXSAT) \ +static bool trans_##INSN(DisasContext *ctx, arg_##INSN * a) \ +{ \ + REQUIRE_RVP(ctx); \ + if (VXSAT && !prepare_rvp_vxsat(ctx)) { \ + return false; \ + } \ + TCGv src1_0 =3D get_gpr(ctx, pair_reg(a->rs1, false), EXT_NONE); \ + TCGv dest_0 =3D dest_gpr(ctx, pair_reg(a->rd, false)); \ + TCGv src1_1 =3D get_gpr(ctx, pair_reg(a->rs1, true), EXT_NONE); \ + TCGv dest_1 =3D dest_gpr(ctx, pair_reg(a->rd, true)); \ + gen_helper_##HELPER(dest_0, tcg_env, src1_0); \ + gen_helper_##HELPER(dest_1, tcg_env, src1_1); \ + gen_set_gpr(ctx, pair_reg(a->rd, false), dest_0); \ + gen_set_gpr(ctx, pair_reg(a->rd, true), dest_1); \ + return true; \ +} + +#define GEN_SIMD_TRANS_REG_PAIR_LANE_UNARY(INSN, HELPER) \ + GEN_SIMD_TRANS_REG_PAIR_LANE_UNARY_OP(INSN, HELPER, false) + +#define GEN_SIMD_TRANS_REG_PAIR_LANE_UNARY_VXSAT(INSN, HELPER) \ + GEN_SIMD_TRANS_REG_PAIR_LANE_UNARY_OP(INSN, HELPER, true) +#else +#define GEN_SIMD_TRANS_REG_PAIR_LANE_UNARY(INSN, HELPER) \ + GEN_SIMD_TRANS_UNAVAILABLE_32(INSN) +#define GEN_SIMD_TRANS_REG_PAIR_LANE_UNARY_VXSAT(INSN, HELPER) \ + GEN_SIMD_TRANS_UNAVAILABLE_32(INSN) +#endif + +#if defined(TARGET_RISCV32) +#define GEN_SIMD_TRANS_REG_PAIR_ACC(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + REQUIRE_RVP(ctx); \ + TCGv src1 =3D get_gpr(ctx, a->rs1, EXT_NONE); \ + TCGv src2 =3D get_gpr(ctx, a->rs2, EXT_NONE); \ + TCGv_i64 t =3D tcg_temp_new_i64(); \ + if (a->rd =3D=3D 0) { \ + tcg_gen_movi_i64(t, 0); \ + } else { \ + get_pair_regs(ctx, t, a->rd); \ + } \ + gen_helper_##NAME(t, tcg_env, src1, src2, t); \ + set_pair_regs(ctx, a->rd, t); \ + return true; \ +} +#else +#define GEN_SIMD_TRANS_REG_PAIR_ACC(NAME) GEN_SIMD_TRANS_UNAVAILABLE_32(NA= ME) +#endif + +#if defined(TARGET_RISCV32) +#define GEN_SIMD_TRANS_REG_PAIR_PREDSUM(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + REQUIRE_RVP(ctx); \ + TCGv_i32 src1_l; \ + TCGv_i32 src1_h; \ + TCGv_i32 src2 =3D get_gpr(ctx, a->rs2, EXT_NONE); \ + TCGv_i32 dest =3D dest_gpr(ctx, a->rd); \ + if (a->rs1 =3D=3D 0) { \ + src1_l =3D tcg_temp_new_i32(); \ + src1_h =3D tcg_temp_new_i32(); \ + tcg_gen_movi_i32(src1_l, 0); \ + tcg_gen_movi_i32(src1_h, 0); \ + } else { \ + src1_l =3D get_gpr(ctx, pair_reg(a->rs1, false), EXT_NONE); \ + src1_h =3D get_gpr(ctx, pair_reg(a->rs1, true), EXT_NONE); \ + } \ + gen_helper_##NAME(dest, tcg_env, src1_l, src1_h, src2); \ + gen_set_gpr(ctx, a->rd, dest); \ + return true; \ +} +#else +#define GEN_SIMD_TRANS_REG_PAIR_PREDSUM(NAME) GEN_SIMD_TRANS_UNAVAILABLE_3= 2(NAME) +#endif + +#if defined(TARGET_RISCV32) +#define GEN_SIMD_TRANS_PN_OP(NAME, SRC2, VXSAT) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + REQUIRE_RVP(ctx); \ + if (VXSAT && !prepare_rvp_vxsat(ctx)) { \ + return false; \ + } \ + TCGv_i64 s1 =3D tcg_temp_new_i64(); \ + if (a->rs1 =3D=3D 0) { \ + tcg_gen_movi_i64(s1, 0); \ + } else { \ + get_pair_regs(ctx, s1, a->rs1); \ + } \ + TCGv src2 =3D SRC2; \ + TCGv dest =3D dest_gpr(ctx, a->rd); \ + gen_helper_##NAME(dest, tcg_env, s1, src2); \ + gen_set_gpr(ctx, a->rd, dest); \ + return true; \ +} + +#define GEN_SIMD_TRANS_PN_OP_IMM(NAME) \ + GEN_SIMD_TRANS_PN_OP(NAME, tcg_constant_tl(a->imm), false) + +#define GEN_SIMD_TRANS_PN_OP_IMM_VXSAT(NAME) \ + GEN_SIMD_TRANS_PN_OP(NAME, tcg_constant_tl(a->imm), true) + +#define GEN_SIMD_TRANS_PN_OP_REG(NAME) \ + GEN_SIMD_TRANS_PN_OP(NAME, get_gpr(ctx, a->rs2, EXT_NONE), false) + +#define GEN_SIMD_TRANS_PN_OP_REG_VXSAT(NAME) \ + GEN_SIMD_TRANS_PN_OP(NAME, get_gpr(ctx, a->rs2, EXT_NONE), true) +#else +#define GEN_SIMD_TRANS_PN_OP_IMM(NAME) GEN_SIMD_TRANS_UNAVAILABLE_32(NAME) +#define GEN_SIMD_TRANS_PN_OP_IMM_VXSAT(NAME) GEN_SIMD_TRANS_UNAVAILABLE_32= (NAME) +#define GEN_SIMD_TRANS_PN_OP_REG(NAME) GEN_SIMD_TRANS_UNAVAILABLE_32(NAME) +#define GEN_SIMD_TRANS_PN_OP_REG_VXSAT(NAME) GEN_SIMD_TRANS_UNAVAILABLE_32= (NAME) +#endif + +/* Packed SIMD - Arithmetic Operations(Non-Saturating and Saturating) */ +GEN_SIMD_TRANS(padd_b) +GEN_SIMD_TRANS(padd_h) +GEN_SIMD_TRANS_64(padd_w) +GEN_SIMD_TRANS(padd_bs) +GEN_SIMD_TRANS(padd_hs) +GEN_SIMD_TRANS_64(padd_ws) +GEN_SIMD_TRANS(psub_b) +GEN_SIMD_TRANS(psub_h) +GEN_SIMD_TRANS_64(psub_w) +GEN_SIMD_TRANS(psh1add_h) +GEN_SIMD_TRANS_64(psh1add_w) +GEN_SIMD_TRANS_VXSAT(pssh1sadd_h) +GEN_SIMD_TRANS_64_VXSAT(pssh1sadd_w) +GEN_SIMD_TRANS_32_VXSAT(ssh1sadd) +GEN_SIMD_TRANS_VXSAT(psadd_b) +GEN_SIMD_TRANS_VXSAT(psadd_h) +GEN_SIMD_TRANS_64_VXSAT(psadd_w) +GEN_SIMD_TRANS_VXSAT(psaddu_b) +GEN_SIMD_TRANS_VXSAT(psaddu_h) +GEN_SIMD_TRANS_64_VXSAT(psaddu_w) +GEN_SIMD_TRANS_32_VXSAT(sadd) +GEN_SIMD_TRANS_32_VXSAT(saddu) +GEN_SIMD_TRANS_VXSAT(pssub_b) +GEN_SIMD_TRANS_VXSAT(pssub_h) +GEN_SIMD_TRANS_64_VXSAT(pssub_w) +GEN_SIMD_TRANS_VXSAT(pssubu_b) +GEN_SIMD_TRANS_VXSAT(pssubu_h) +GEN_SIMD_TRANS_64_VXSAT(pssubu_w) +GEN_SIMD_TRANS_32_VXSAT(ssub) +GEN_SIMD_TRANS_32_VXSAT(ssubu) +GEN_SIMD_TRANS_IMM_VXSAT(psati_h) +GEN_SIMD_TRANS_IMM_VXSAT(pusati_h) +GEN_SIMD_TRANS_IMM_64_VXSAT(psati_w) +GEN_SIMD_TRANS_IMM_64_VXSAT(pusati_w) +GEN_SIMD_TRANS_IMM_32_VXSAT(sati_32) +GEN_SIMD_TRANS_IMM_32_VXSAT(usati_32) +GEN_SIMD_TRANS_IMM_64_VXSAT(sati_64) +GEN_SIMD_TRANS_IMM_64_VXSAT(usati_64) diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helpe= r.c index 488deeadd96..8702b7398b0 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -2044,3 +2044,119 @@ uint32_t HELPER(NAME)(CPURISCVState *env, uint64_t = s1, uint32_t shamt) \ return (uint32_t)(round_shx & 0xFFFFFFFF); \ } \ } + +/* Basic addition operations (non-saturating) */ + +GEN_PSIMD_BINOP(padd_b, target_ulong, uint8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_ADD) +GEN_PSIMD_BINOP(padd_h, target_ulong, uint16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_ADD) +GEN_PSIMD_BINOP(padd_w, uint64_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_ADD) + +GEN_PSIMD_BINOP_SCALAR(padd_bs, target_ulong, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_ADD) +GEN_PSIMD_BINOP_SCALAR(padd_hs, target_ulong, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_ADD) +GEN_PSIMD_BINOP_SCALAR(padd_ws, uint64_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_ADD) + +/* Basic subtraction operations (non-saturating) */ + +GEN_PSIMD_BINOP(psub_b, target_ulong, uint8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_SUB) +GEN_PSIMD_BINOP(psub_h, target_ulong, uint16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_SUB) +GEN_PSIMD_BINOP(psub_w, uint64_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_SUB) + +/* Shift-left-by-one and add operations */ + +GEN_PSIMD_SHADD(psh1add_h, target_ulong, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 1) +GEN_PSIMD_SHADD(psh1add_w, uint64_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 1) + +GEN_PSIMD_SAT_SHADD(pssh1sadd_h, target_ulong, int16_t, int32_t, + EXTRACT16, INSERT16, ELEMS_H, 1, -0x4000, 0x3fff, + SAT_MIN_H, SAT_MAX_H, signed_saturate_h) +GEN_PSIMD_SAT_SHADD(pssh1sadd_w, uint64_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, 1, -0x40000000, + 0x3fffffff, SAT_MIN_W, SAT_MAX_W, signed_saturate_w) + +GEN_PSIMD_SAT_SHADD(ssh1sadd, uint32_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, 1, -0x40000000, + 0x3fffffff, SAT_MIN_W, SAT_MAX_W, signed_saturate_w) + +/* Saturating addition operations */ + +GEN_PSIMD_SAT_BINOP(psadd_b, target_ulong, int8_t, int32_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_ADD, + signed_saturate_b) +GEN_PSIMD_SAT_BINOP(psadd_h, target_ulong, int16_t, int32_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_ADD, + signed_saturate_h) +GEN_PSIMD_SAT_BINOP(psadd_w, uint64_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_ADD, + signed_saturate_w) + +GEN_PSIMD_SAT_BINOP(psaddu_b, target_ulong, uint8_t, uint32_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_ADD, + unsigned_saturate_b) +GEN_PSIMD_SAT_BINOP(psaddu_h, target_ulong, uint16_t, uint32_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_ADD, + unsigned_saturate_h) +GEN_PSIMD_SAT_BINOP(psaddu_w, uint64_t, uint32_t, uint64_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_ADD, + unsigned_saturate_w) + +GEN_PSIMD_SAT_BINOP(sadd, uint32_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_ADD, + signed_saturate_w) +GEN_PSIMD_SAT_BINOP(saddu, uint32_t, uint32_t, uint64_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_ADD, + unsigned_saturate_w) + +/* Saturating subtraction operations */ + +GEN_PSIMD_SAT_BINOP(pssub_b, target_ulong, int8_t, int32_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_SUB, + signed_saturate_b) +GEN_PSIMD_SAT_BINOP(pssub_h, target_ulong, int16_t, int32_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_SUB, + signed_saturate_h) +GEN_PSIMD_SAT_BINOP(pssub_w, uint64_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_SUB, + signed_saturate_w) + +GEN_PSIMD_SAT_USUB(pssubu_b, target_ulong, uint8_t, + EXTRACT8, INSERT8, ELEMS_B) +GEN_PSIMD_SAT_USUB(pssubu_h, target_ulong, uint16_t, + EXTRACT16, INSERT16, ELEMS_H) +GEN_PSIMD_SAT_USUB(pssubu_w, uint64_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W) + +GEN_PSIMD_SAT_BINOP(ssub, uint32_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_SUB, + signed_saturate_w) +GEN_PSIMD_SAT_USUB(ssubu, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W) + +/* Saturation instructions (SAT, USAT) */ + +GEN_PSIMD_SATI(psati_h, target_ulong, int16_t, int64_t, + EXTRACT16, INSERT16, ELEMS_H, 0x0f) +GEN_PSIMD_USATI(pusati_h, target_ulong, int16_t, uint16_t, uint32_t, + EXTRACT16, INSERT16, ELEMS_H, 1U) +GEN_PSIMD_SATI(psati_w, uint64_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, 0x1f) +GEN_PSIMD_USATI(pusati_w, uint64_t, int32_t, uint32_t, uint64_t, + EXTRACT32, INSERT32, ELEMS_W, 1ULL) +GEN_PSIMD_SATI(sati_32, uint32_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, 0x1f) +GEN_PSIMD_USATI(usati_32, uint32_t, int32_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 1U) +GEN_PSIMD_SATI(sati_64, uint64_t, int64_t, int64_t, + EXTRACT64, INSERT64, ELEMS_D, 0x3f) +GEN_PSIMD_USATI(usati_64, uint64_t, int64_t, uint64_t, uint64_t, + EXTRACT64, INSERT64, ELEMS_D, 1ULL) diff --git a/target/riscv/tcg/translate.c b/target/riscv/tcg/translate.c index 9684dbe7528..0df9d4190f1 100644 --- a/target/riscv/tcg/translate.c +++ b/target/riscv/tcg/translate.c @@ -103,6 +103,7 @@ typedef struct DisasContext { bool vstart_eq_zero; bool vl_eq_vlmax; bool altfmt; + uint8_t p_vxsat_excp; CPUState *cs; TCGv zero; /* actual address width */ @@ -1199,6 +1200,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, t= arget_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_rvp.c.inc" #include "insn_trans/trans_rvzicond.c.inc" #include "insn_trans/trans_rvzacas.c.inc" #include "insn_trans/trans_rvzabha.c.inc" @@ -1333,6 +1335,8 @@ static void riscv_tr_init_disas_context(DisasContextB= ase *dcbase, CPUState *cs) ctx->vstart_eq_zero =3D FIELD_EX32(tb_flags, TB_FLAGS, VSTART_EQ_ZERO); ctx->vl_eq_vlmax =3D FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX); ctx->altfmt =3D FIELD_EX64(ext_tb_flags, EXT_TB_FLAGS, ALTFMT); + ctx->p_vxsat_excp =3D FIELD_EX64(ext_tb_flags, EXT_TB_FLAGS, + P_VXSAT_EXCP); ctx->misa_mxl_max =3D mcc->def->misa_mxl_max; ctx->xl =3D FIELD_EX32(tb_flags, TB_FLAGS, XL); ctx->address_xl =3D FIELD_EX32(tb_flags, TB_FLAGS, AXL); --=20 2.34.1 From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789542608969232.57459570956087; Wed, 16 Sep 2026 00:10:08 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jkf-0005fZ-U4; Wed, 16 Sep 2026 03:08:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jkZ-0005cX-E7; Wed, 16 Sep 2026 03:08:11 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jkT-0008J5-Rw; Wed, 16 Sep 2026 03:08:10 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S6; Wed, 16 Sep 2026 15:08:01 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 04/19] target/riscv: Add packed SIMD averaging and rounding instructions Date: Wed, 16 Sep 2026 07:07:06 +0000 Message-Id: <20260916070721.3279229-5-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S6 X-Coremail-Antispam: 1UD129KBjvJXoWxtF4rAw1xWr13AF4xAw4DXFb_yoWxCFyxpa n7G343JFW8tFWaqFySkr45tw13Wws3K3yUur43KFySvay5JF93Jw1Utr4aka13XryDWr1j 9ayFyr98AFWFq3JanT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUQI14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_Xr0_Ar1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAaw2AFwI0_Jrv_JF1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I 8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_JF0_Jw1lYx0Ex4A2jsIE14v26F4j6r4UJwAm72CE 4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4 IIrI8v6xkF7I0E8cxan2IY04v7MxkF7I0En4kS14v26r1q6r43MxAIw28IcxkI7VAKI48J MxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwV AFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6xIIjxv2 0xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWxJVW8Jr1lIxAIcVCF04k26c xKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26F4j6r4UJwCI42IY6I8E87Iv6xkF7I0E 14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7VUbKZX7UUUUU== X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542610310158500 Content-Type: text/plain; charset="utf-8" Implement averaging addition and subtraction operations. Cover signed and unsigned variants across the supported element widths. Add the associated decode entries, translators and helpers. These instructions add or subtract corresponding packed elements and shift each intermediate result right by one bit. The helpers use wider intermediate types to preserve the bits required by the add or subtract operation before shifting, and then truncate each result back to the original element width. Signed-off-by: Molly Chen Reviewed-by: Daniel Henrique Barboza --- target/riscv/helper.h | 18 ++++++++++ target/riscv/insn32.decode | 26 ++++++++++++++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 18 ++++++++++ target/riscv/tcg/psimd_helper.c | 40 +++++++++++++++++++++ 4 files changed, 102 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 23741b2e827..0b0f5791874 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1398,3 +1398,21 @@ DEF_HELPER_3(sati_32, i32, env, i32, i32) DEF_HELPER_3(usati_32, i32, env, i32, i32) DEF_HELPER_3(sati_64, i64, env, i64, i64) DEF_HELPER_3(usati_64, i64, env, i64, i64) + +/* Packed SIMD - Averaging and Rounding Operations */ +DEF_HELPER_3(paadd_b, tl, env, tl, tl) +DEF_HELPER_3(paadd_h, tl, env, tl, tl) +DEF_HELPER_3(paadd_w, i64, env, i64, i64) +DEF_HELPER_3(paaddu_b, tl, env, tl, tl) +DEF_HELPER_3(paaddu_h, tl, env, tl, tl) +DEF_HELPER_3(paaddu_w, i64, env, i64, i64) +DEF_HELPER_3(aadd, i32, env, i32, i32) +DEF_HELPER_3(aaddu, i32, env, i32, i32) +DEF_HELPER_3(pasub_b, tl, env, tl, tl) +DEF_HELPER_3(pasub_h, tl, env, tl, tl) +DEF_HELPER_3(pasub_w, i64, env, i64, i64) +DEF_HELPER_3(pasubu_b, tl, env, tl, tl) +DEF_HELPER_3(pasubu_h, tl, env, tl, tl) +DEF_HELPER_3(pasubu_w, i64, env, i64, i64) +DEF_HELPER_3(asub, i32, env, i32, i32) +DEF_HELPER_3(asubu, i32, env, i32, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index afd096cf5db..e06cc82bdef 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -1149,3 +1149,29 @@ pusati_h 10100 001.... ..... 100 ..... 0011011 @p_= ui16 } sati_64 111001 ...... ..... 100 ..... 0011011 @p_ui64 usati_64 101001 ...... ..... 100 ..... 0011011 @p_ui64 + +# Packed SIMD - Averaging and Rounding Operations +paadd_b 1001110 ..... ..... 000 ..... 0111011 @r +paadd_h 1001100 ..... ..... 000 ..... 0111011 @r +{ + aadd 1001101 ..... ..... 000 ..... 0111011 @r + paadd_w 1001101 ..... ..... 000 ..... 0111011 @r +} +paaddu_b 1011110 ..... ..... 000 ..... 0111011 @r +paaddu_h 1011100 ..... ..... 000 ..... 0111011 @r +{ + aaddu 1011101 ..... ..... 000 ..... 0111011 @r + paaddu_w 1011101 ..... ..... 000 ..... 0111011 @r +} +pasub_b 1101110 ..... ..... 000 ..... 0111011 @r +pasub_h 1101100 ..... ..... 000 ..... 0111011 @r +{ + asub 1101101 ..... ..... 000 ..... 0111011 @r + pasub_w 1101101 ..... ..... 000 ..... 0111011 @r +} +pasubu_b 1111110 ..... ..... 000 ..... 0111011 @r +pasubu_h 1111100 ..... ..... 000 ..... 0111011 @r +{ + asubu 1111101 ..... ..... 000 ..... 0111011 @r + pasubu_w 1111101 ..... ..... 000 ..... 0111011 @r +} diff --git a/target/riscv/tcg/insn_trans/trans_rvp.c.inc b/target/riscv/tcg= /insn_trans/trans_rvp.c.inc index 0c91aac5060..820d11c33b2 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -551,3 +551,21 @@ GEN_SIMD_TRANS_IMM_32_VXSAT(sati_32) GEN_SIMD_TRANS_IMM_32_VXSAT(usati_32) GEN_SIMD_TRANS_IMM_64_VXSAT(sati_64) GEN_SIMD_TRANS_IMM_64_VXSAT(usati_64) + +/* Packed SIMD - Averaging and Rounding Operations */ +GEN_SIMD_TRANS(paadd_b) +GEN_SIMD_TRANS(paadd_h) +GEN_SIMD_TRANS_64(paadd_w) +GEN_SIMD_TRANS(paaddu_b) +GEN_SIMD_TRANS(paaddu_h) +GEN_SIMD_TRANS_64(paaddu_w) +GEN_SIMD_TRANS_32(aadd) +GEN_SIMD_TRANS_32(aaddu) +GEN_SIMD_TRANS(pasub_b) +GEN_SIMD_TRANS(pasub_h) +GEN_SIMD_TRANS_64(pasub_w) +GEN_SIMD_TRANS(pasubu_b) +GEN_SIMD_TRANS(pasubu_h) +GEN_SIMD_TRANS_64(pasubu_w) +GEN_SIMD_TRANS_32(asub) +GEN_SIMD_TRANS_32(asubu) diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helpe= r.c index 8702b7398b0..e2796230710 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -2160,3 +2160,43 @@ GEN_PSIMD_SATI(sati_64, uint64_t, int64_t, int64_t, EXTRACT64, INSERT64, ELEMS_D, 0x3f) GEN_PSIMD_USATI(usati_64, uint64_t, int64_t, uint64_t, uint64_t, EXTRACT64, INSERT64, ELEMS_D, 1ULL) + +/* Averaging Operations (non-saturating) */ + +GEN_PSIMD_AVG_BINOP(paadd_b, target_ulong, int8_t, int16_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_ADD) +GEN_PSIMD_AVG_BINOP(paadd_h, target_ulong, int16_t, int32_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_ADD) +GEN_PSIMD_AVG_BINOP(paadd_w, uint64_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_ADD) + +GEN_PSIMD_AVG_BINOP(paaddu_b, target_ulong, uint8_t, uint16_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_ADD) +GEN_PSIMD_AVG_BINOP(paaddu_h, target_ulong, uint16_t, uint32_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_ADD) +GEN_PSIMD_AVG_BINOP(paaddu_w, uint64_t, uint32_t, uint64_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_ADD) + +GEN_PSIMD_AVG_BINOP(aadd, uint32_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_ADD) +GEN_PSIMD_AVG_BINOP(aaddu, uint32_t, uint32_t, uint64_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_ADD) + +GEN_PSIMD_AVG_BINOP(pasub_b, target_ulong, int8_t, int16_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_SUB) +GEN_PSIMD_AVG_BINOP(pasub_h, target_ulong, int16_t, int32_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_SUB) +GEN_PSIMD_AVG_BINOP(pasub_w, uint64_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_SUB) + +GEN_PSIMD_AVG_BINOP(pasubu_b, target_ulong, uint8_t, uint16_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_SUB) +GEN_PSIMD_AVG_BINOP(pasubu_h, target_ulong, uint16_t, uint32_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_SUB) +GEN_PSIMD_AVG_BINOP(pasubu_w, uint64_t, uint32_t, uint64_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_SUB) + +GEN_PSIMD_AVG_BINOP(asub, uint32_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_SUB) +GEN_PSIMD_AVG_BINOP(asubu, uint32_t, uint32_t, uint64_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_SUB) --=20 2.34.1 From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789542536113257.66129593878736; Wed, 16 Sep 2026 00:08:56 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jkp-0005oy-Jt; Wed, 16 Sep 2026 03:08:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jkZ-0005co-Qj; Wed, 16 Sep 2026 03:08:11 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jkT-0008JC-SW; Wed, 16 Sep 2026 03:08:11 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S7; Wed, 16 Sep 2026 15:08:01 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 05/19] target/riscv: Add packed SIMD absolute, difference, compare and mask instructions Date: Wed, 16 Sep 2026 07:07:07 +0000 Message-Id: <20260916070721.3279229-6-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S7 X-Coremail-Antispam: 1UD129KBjvJXoW3CF18Jr18urWkGFykGw45KFg_yoWkAr1Upa ykGry3WrW0qrWFq34xKr15J3ZxWanIk3y8ur43KF1fZay5XFWkXr1Utr4ayF4UXr9rWFWj gay0y34DAay0v3JanT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUQI14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_Xr0_Ar1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAaw2AFwI0_Jrv_JF1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I 8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_JF0_Jw1lYx0Ex4A2jsIE14v26F4j6r4UJwAm72CE 4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4 IIrI8v6xkF7I0E8cxan2IY04v7MxkF7I0En4kS14v26r1q6r43MxAIw28IcxkI7VAKI48J MxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwV AFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6xIIjxv2 0xvE14v26r1I6r4UMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWxJVW8Jr1lIxAIcVCF04k26c xKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26F4j6r4UJwCI42IY6I8E87Iv6xkF7I0E 14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7VUbKZX7UUUUU== X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542538543158500 Content-Type: text/plain; charset="utf-8" Implement saturating absolute value, absolute difference, sum-of-absolute-differences, accumulated sum-of-absolute-differences, and comparison and mask-generation operations.Add the associated decode entries, translators and helpers. Note that the PSABS.* instructions produce results in the signed element domain. Since the absolute value of the minimum signed value cannot be represented in the same element width, saturate it to the maximum signed value and set vxsat. All other values are converted to their absolute values without saturation. Signed-off-by: Molly Chen --- target/riscv/helper.h | 38 +++++++++ target/riscv/insn32.decode | 44 ++++++++++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 38 +++++++++ target/riscv/tcg/psimd_helper.c | 95 +++++++++++++++++++++ 4 files changed, 215 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 0b0f5791874..d9ea90a5c2e 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1416,3 +1416,41 @@ DEF_HELPER_3(pasubu_h, tl, env, tl, tl) DEF_HELPER_3(pasubu_w, i64, env, i64, i64) DEF_HELPER_3(asub, i32, env, i32, i32) DEF_HELPER_3(asubu, i32, env, i32, i32) + +/* Packed SIMD - Absolute Value and Difference Operations */ +DEF_HELPER_2(psabs_b, tl, env, tl) +DEF_HELPER_2(psabs_h, tl, env, tl) +DEF_HELPER_2(abs, tl, env, tl) +DEF_HELPER_2(absw, i64, env, i64) +DEF_HELPER_3(pabd_b, tl, env, tl, tl) +DEF_HELPER_3(pabdu_b, tl, env, tl, tl) +DEF_HELPER_3(pabd_h, tl, env, tl, tl) +DEF_HELPER_3(pabdu_h, tl, env, tl, tl) +DEF_HELPER_3(pabdsumu_b, tl, env, tl, tl) +DEF_HELPER_4(pabdsumau_b, tl, env, tl, tl, tl) + +/* Packed SIMD - Comparison and Mask Generation Operations */ +DEF_HELPER_3(pmseq_b, tl, env, tl, tl) +DEF_HELPER_3(pmslt_b, tl, env, tl, tl) +DEF_HELPER_3(pmsltu_b, tl, env, tl, tl) +DEF_HELPER_3(pmin_b, tl, env, tl, tl) +DEF_HELPER_3(pminu_b, tl, env, tl, tl) +DEF_HELPER_3(pmax_b, tl, env, tl, tl) +DEF_HELPER_3(pmaxu_b, tl, env, tl, tl) +DEF_HELPER_3(pmseq_h, tl, env, tl, tl) +DEF_HELPER_3(pmslt_h, tl, env, tl, tl) +DEF_HELPER_3(pmsltu_h, tl, env, tl, tl) +DEF_HELPER_3(pmin_h, tl, env, tl, tl) +DEF_HELPER_3(pminu_h, tl, env, tl, tl) +DEF_HELPER_3(pmax_h, tl, env, tl, tl) +DEF_HELPER_3(pmaxu_h, tl, env, tl, tl) +DEF_HELPER_3(pmseq_w, i64, env, i64, i64) +DEF_HELPER_3(pmslt_w, i64, env, i64, i64) +DEF_HELPER_3(pmsltu_w, i64, env, i64, i64) +DEF_HELPER_3(pmin_w, i64, env, i64, i64) +DEF_HELPER_3(pminu_w, i64, env, i64, i64) +DEF_HELPER_3(pmax_w, i64, env, i64, i64) +DEF_HELPER_3(pmaxu_w, i64, env, i64, i64) +DEF_HELPER_3(mseq, i32, env, i32, i32) +DEF_HELPER_3(mslt, i32, env, i32, i32) +DEF_HELPER_3(msltu, i32, env, i32, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index e06cc82bdef..32eb7b153aa 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -1175,3 +1175,47 @@ pasubu_h 1111100 ..... ..... 000 ..... 0111011 @r asubu 1111101 ..... ..... 000 ..... 0111011 @r pasubu_w 1111101 ..... ..... 000 ..... 0111011 @r } + +# Packed SIMD - Absolute Value and Difference Operations +psabs_b 1110010 00111 ..... 010 ..... 0011011 @r2 +psabs_h 1110000 00111 ..... 010 ..... 0011011 @r2 +abs 01100 0000111 ..... 001 ..... 0010011 @r2 +absw 01100 0000111 ..... 001 ..... 0011011 @r2 +pabd_b 1100110 ..... ..... 000 ..... 0111011 @r +pabdu_b 1110110 ..... ..... 000 ..... 0111011 @r +pabd_h 1100100 ..... ..... 000 ..... 0111011 @r +pabdu_h 1110100 ..... ..... 000 ..... 0111011 @r +pabdsumu_b 1011010 ..... ..... 001 ..... 0111011 @r +pabdsumau_b 1011110 ..... ..... 001 ..... 0111011 @r + +# Packed SIMD - Comparison and Mask Generation Operations +pmseq_b 1100010 ..... ..... 110 ..... 0111011 @r +pmslt_b 1101010 ..... ..... 110 ..... 0111011 @r +pmsltu_b 1101110 ..... ..... 110 ..... 0111011 @r +pmin_b 1110010 ..... ..... 110 ..... 0111011 @r +pminu_b 1110110 ..... ..... 110 ..... 0111011 @r +pmax_b 1111010 ..... ..... 110 ..... 0111011 @r +pmaxu_b 1111110 ..... ..... 110 ..... 0111011 @r +pmseq_h 1100000 ..... ..... 110 ..... 0111011 @r +pmslt_h 1101000 ..... ..... 110 ..... 0111011 @r +pmsltu_h 1101100 ..... ..... 110 ..... 0111011 @r +pmin_h 1110000 ..... ..... 110 ..... 0111011 @r +pminu_h 1110100 ..... ..... 110 ..... 0111011 @r +pmax_h 1111000 ..... ..... 110 ..... 0111011 @r +pmaxu_h 1111100 ..... ..... 110 ..... 0111011 @r +{ + mseq 1100001 ..... ..... 110 ..... 0111011 @r + pmseq_w 1100001 ..... ..... 110 ..... 0111011 @r +} +{ + mslt 1101001 ..... ..... 110 ..... 0111011 @r + pmslt_w 1101001 ..... ..... 110 ..... 0111011 @r +} +{ + msltu 1101101 ..... ..... 110 ..... 0111011 @r + pmsltu_w 1101101 ..... ..... 110 ..... 0111011 @r +} +pmin_w 1110001 ..... ..... 110 ..... 0111011 @r +pminu_w 1110101 ..... ..... 110 ..... 0111011 @r +pmax_w 1111001 ..... ..... 110 ..... 0111011 @r +pmaxu_w 1111101 ..... ..... 110 ..... 0111011 @r diff --git a/target/riscv/tcg/insn_trans/trans_rvp.c.inc b/target/riscv/tcg= /insn_trans/trans_rvp.c.inc index 820d11c33b2..81d3f90eb08 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -569,3 +569,41 @@ GEN_SIMD_TRANS(pasubu_h) GEN_SIMD_TRANS_64(pasubu_w) GEN_SIMD_TRANS_32(asub) GEN_SIMD_TRANS_32(asubu) + +/* Packed SIMD - Absolute Value and Difference Operations */ +GEN_SIMD_TRANS_R1_VXSAT(psabs_b) +GEN_SIMD_TRANS_R1_VXSAT(psabs_h) +GEN_SIMD_TRANS_R1(abs) +GEN_SIMD_TRANS_R1_64(absw) +GEN_SIMD_TRANS(pabd_b) +GEN_SIMD_TRANS(pabdu_b) +GEN_SIMD_TRANS(pabd_h) +GEN_SIMD_TRANS(pabdu_h) +GEN_SIMD_TRANS(pabdsumu_b) +GEN_SIMD_TRANS_ACC(pabdsumau_b) + +/* Packed SIMD - Comparison and Mask Generation Operations */ +GEN_SIMD_TRANS(pmseq_b) +GEN_SIMD_TRANS(pmslt_b) +GEN_SIMD_TRANS(pmsltu_b) +GEN_SIMD_TRANS(pmin_b) +GEN_SIMD_TRANS(pminu_b) +GEN_SIMD_TRANS(pmax_b) +GEN_SIMD_TRANS(pmaxu_b) +GEN_SIMD_TRANS(pmseq_h) +GEN_SIMD_TRANS(pmslt_h) +GEN_SIMD_TRANS(pmsltu_h) +GEN_SIMD_TRANS(pmin_h) +GEN_SIMD_TRANS(pminu_h) +GEN_SIMD_TRANS(pmax_h) +GEN_SIMD_TRANS(pmaxu_h) +GEN_SIMD_TRANS_64(pmseq_w) +GEN_SIMD_TRANS_64(pmslt_w) +GEN_SIMD_TRANS_64(pmsltu_w) +GEN_SIMD_TRANS_64(pmin_w) +GEN_SIMD_TRANS_64(pminu_w) +GEN_SIMD_TRANS_64(pmax_w) +GEN_SIMD_TRANS_64(pmaxu_w) +GEN_SIMD_TRANS_32(mseq) +GEN_SIMD_TRANS_32(mslt) +GEN_SIMD_TRANS_32(msltu) diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helpe= r.c index e2796230710..625928dc1dd 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -2200,3 +2200,98 @@ GEN_PSIMD_AVG_BINOP(asub, uint32_t, int32_t, int64_t, EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_SUB) GEN_PSIMD_AVG_BINOP(asubu, uint32_t, uint32_t, uint64_t, EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_SUB) + +/* Absolute value operations */ + +GEN_PSIMD_ABS(psabs_b, target_ulong, int8_t, + EXTRACT8, INSERT8, ELEMS_B, INT8_MIN, INT8_MAX) +GEN_PSIMD_ABS(psabs_h, target_ulong, int16_t, + EXTRACT16, INSERT16, ELEMS_H, INT16_MIN, INT16_MAX) + +GEN_PSIMD_SCALAR_ABS(abs, target_ulong, target_long, target_ulong) +GEN_PSIMD_SCALAR_ABS(absw, uint64_t, int32_t, uint32_t) + +/* Absolute difference operations */ + +GEN_PSIMD_BINOP(pabd_b, target_ulong, int8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_ABD) +GEN_PSIMD_BINOP(pabdu_b, target_ulong, uint8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_ABD) +GEN_PSIMD_BINOP(pabd_h, target_ulong, int16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_ABD) +GEN_PSIMD_BINOP(pabdu_h, target_ulong, uint16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_ABD) + +/** + * PABDSUMU.B - Sum of unsigned absolute differences + * Returns sum(|rs1[i] - rs2[i]|) for all bytes + */ +target_ulong HELPER(pabdsumu_b)(CPURISCVState *env, + target_ulong rs1, target_ulong rs2) +{ + return psimd_abdsumu_b(rs1, rs2, 0); +} + +/** + * PABDSUMAU.B - Accumulated sum of unsigned absolute differences + * rd =3D rd + sum(|rs1[i] - rs2[i]|) + */ +target_ulong HELPER(pabdsumau_b)(CPURISCVState *env, target_ulong rs1, + target_ulong rs2, target_ulong rd) +{ + return psimd_abdsumu_b(rs1, rs2, rd); +} + +/* Comparison operations (producing masks) */ + +GEN_PSIMD_BINOP(pmseq_b, target_ulong, uint8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_EQ_MASK) +GEN_PSIMD_BINOP(pmslt_b, target_ulong, int8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_LT_MASK) +GEN_PSIMD_BINOP(pmsltu_b, target_ulong, uint8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_LT_MASK) +GEN_PSIMD_BINOP(pmin_b, target_ulong, int8_t, int8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_MIN) +GEN_PSIMD_BINOP(pminu_b, target_ulong, uint8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_MIN) +GEN_PSIMD_BINOP(pmax_b, target_ulong, int8_t, int8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_MAX) +GEN_PSIMD_BINOP(pmaxu_b, target_ulong, uint8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_MAX) + +GEN_PSIMD_BINOP(pmseq_h, target_ulong, uint16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_EQ_MASK) +GEN_PSIMD_BINOP(pmslt_h, target_ulong, int16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_LT_MASK) +GEN_PSIMD_BINOP(pmsltu_h, target_ulong, uint16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_LT_MASK) +GEN_PSIMD_BINOP(pmin_h, target_ulong, int16_t, int16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_MIN) +GEN_PSIMD_BINOP(pminu_h, target_ulong, uint16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_MIN) +GEN_PSIMD_BINOP(pmax_h, target_ulong, int16_t, int16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_MAX) +GEN_PSIMD_BINOP(pmaxu_h, target_ulong, uint16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_MAX) + +GEN_PSIMD_BINOP(pmseq_w, uint64_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_EQ_MASK) +GEN_PSIMD_BINOP(pmslt_w, uint64_t, int32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_LT_MASK) +GEN_PSIMD_BINOP(pmsltu_w, uint64_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_LT_MASK) +GEN_PSIMD_BINOP(pmin_w, uint64_t, int32_t, int32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_MIN) +GEN_PSIMD_BINOP(pminu_w, uint64_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_MIN) +GEN_PSIMD_BINOP(pmax_w, uint64_t, int32_t, int32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_MAX) +GEN_PSIMD_BINOP(pmaxu_w, uint64_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_MAX) + +GEN_PSIMD_BINOP(mseq, uint32_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_EQ_MASK) +GEN_PSIMD_BINOP(mslt, uint32_t, int32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_LT_MASK) +GEN_PSIMD_BINOP(msltu, uint32_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_LT_MASK) --=20 2.34.1 From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789542666310930.7803830121924; Wed, 16 Sep 2026 00:11:06 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jkl-0005ny-G6; Wed, 16 Sep 2026 03:08:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jkZ-0005cr-RL; Wed, 16 Sep 2026 03:08:11 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jkT-0008JA-Q8; Wed, 16 Sep 2026 03:08:11 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S8; Wed, 16 Sep 2026 15:08:02 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 06/19] target/riscv: Add packed SIMD shift instructions Date: Wed, 16 Sep 2026 07:07:08 +0000 Message-Id: <20260916070721.3279229-7-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S8 X-Coremail-Antispam: 1UD129KBjvAXoW3tF47GrW7Xw1fAFWxtr48tFb_yoW8GFykKo Z3Gw45Zr1rGr45Z345Cw48XwnFvr92vw4ktrWrZw1UWa92vryagrn8J348Z3WxAr1Yyry7 XrZ3Gw15t3Z3W34Dn29KB7ZKAUJUUUUr529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUOv7AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r126s0DM28Irc Ia0xkI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l 84ACjcxK6xIIjxv20xvE14v26ryj6F1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4UJV WxJr1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE 3s1ln4kS14v26r1Y6r17M2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c 02F40Ex7xfMcIj6xIIjxv20xvE14v26r126r1DMcIj6I8E87Iv67AKxVWxJVW8Jr1lOx8S 6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxw ACI402YVCY1x02628vn2kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxG rwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4 vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IY x2IY67AKxVWUCVW8JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UMIIF0xvE42xK8V AvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWxJVW8Jr1lIxAIcVC2z280aVCY1x02 67AKxVW8Jr0_Cr1UYxBIdaVFxhVjvjDU0xZFpf9x0JULSdkUUUUU= X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542666576158500 Content-Type: text/plain; charset="utf-8" Implement packed logical left and right shifts, arithmetic right shifts, saturating left shifts, rounding right shifts, and bidirectional shift operations. Cover immediate and register-controlled variants across the supported element widths. Add the associated decode entries, translators and helpers. Note that saturating left-shift operations clamp results that cannot be represented in the signed element domain to the corresponding minimum or maximum signed value and set vxsat. Rounding right-shift operations add the required rounding value before shifting and do not affect vxsat. The helper implementation is equivalent to the operation defined in the specification. Signed-off-by: Molly Chen --- target/riscv/helper.h | 43 +++++++ target/riscv/insn32.decode | 57 +++++++++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 43 +++++++ target/riscv/tcg/psimd_helper.c | 123 ++++++++++++++++++++ 4 files changed, 266 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index d9ea90a5c2e..53107334e1f 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1454,3 +1454,46 @@ DEF_HELPER_3(pmaxu_w, i64, env, i64, i64) DEF_HELPER_3(mseq, i32, env, i32, i32) DEF_HELPER_3(mslt, i32, env, i32, i32) DEF_HELPER_3(msltu, i32, env, i32, i32) + +/* Packed SIMD - Shift Operations */ +DEF_HELPER_3(pslli_b, tl, env, tl, tl) +DEF_HELPER_3(psll_bs, tl, env, tl, tl) +DEF_HELPER_3(pslli_h, tl, env, tl, tl) +DEF_HELPER_3(psll_hs, tl, env, tl, tl) +DEF_HELPER_3(pslli_w, i64, env, i64, i64) +DEF_HELPER_3(psll_ws, i64, env, i64, i64) +DEF_HELPER_3(psrli_b, tl, env, tl, tl) +DEF_HELPER_3(psrl_bs, tl, env, tl, tl) +DEF_HELPER_3(psrli_h, tl, env, tl, tl) +DEF_HELPER_3(psrl_hs, tl, env, tl, tl) +DEF_HELPER_3(psrli_w, i64, env, i64, i64) +DEF_HELPER_3(psrl_ws, i64, env, i64, i64) +DEF_HELPER_3(psrai_b, tl, env, tl, tl) +DEF_HELPER_3(psra_bs, tl, env, tl, tl) +DEF_HELPER_3(psrai_h, tl, env, tl, tl) +DEF_HELPER_3(psra_hs, tl, env, tl, tl) +DEF_HELPER_3(psrai_w, i64, env, i64, i64) +DEF_HELPER_3(psra_ws, i64, env, i64, i64) +DEF_HELPER_3(psslai_h, tl, env, tl, tl) +DEF_HELPER_3(psslai_w, i64, env, i64, i64) +DEF_HELPER_3(sslai, i32, env, i32, i32) +DEF_HELPER_3(psrari_h, tl, env, tl, tl) +DEF_HELPER_3(psrari_w, i64, env, i64, i64) +DEF_HELPER_3(srari_32, i32, env, i32, i32) +DEF_HELPER_3(srari_64, i64, env, i64, i64) +DEF_HELPER_3(pssha_hs, tl, env, tl, tl) +DEF_HELPER_3(pssha_ws, i64, env, i64, i64) +DEF_HELPER_3(psshar_hs, tl, env, tl, tl) +DEF_HELPER_3(psshar_ws, i64, env, i64, i64) +DEF_HELPER_3(ssha, i32, env, i32, i32) +DEF_HELPER_3(sshar, i32, env, i32, i32) +DEF_HELPER_3(sha, i64, env, i64, i64) +DEF_HELPER_3(shar, i64, env, i64, i64) +DEF_HELPER_3(psshl_hs, tl, env, tl, tl) +DEF_HELPER_3(psshlr_hs, tl, env, tl, tl) +DEF_HELPER_3(psshl_ws, i64, env, i64, i64) +DEF_HELPER_3(psshlr_ws, i64, env, i64, i64) +DEF_HELPER_3(sshl, i32, env, i32, i32) +DEF_HELPER_3(sshlr, i32, env, i32, i32) +DEF_HELPER_3(shl, i64, env, i64, i64) +DEF_HELPER_3(shlr, i64, env, i64, i64) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 32eb7b153aa..82434b10410 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -40,6 +40,7 @@ %imm_z6 26:1 15:5 %imm_mop5 30:1 26:2 20:2 %imm_mop3 30:1 26:2 +%imm_p_ui8 20:3 %imm_p_ui16 20:4 %imm_p_ui32 20:5 %imm_p_ui64 20:6 @@ -109,6 +110,7 @@ @mop5 . . .. .. .... .. ..... ... ..... ....... &mop5 imm=3D%imm_mop5 %rd = %rs1 @mop3 . . .. .. . ..... ..... ... ..... ....... &mop3 imm=3D%imm_mop3 %rd = %rs1 %rs2 =20 +@p_ui8 ..... .... ... ..... ... ..... ....... &i imm=3D%imm_p_ui8 %rs1 %= rd @p_ui16 ..... .... ... ..... ... ..... ....... &i imm=3D%imm_p_ui16 %rs1 %= rd @p_ui32 ..... .... ... ..... ... ..... ....... &i imm=3D%imm_p_ui32 %rs1 %= rd @p_ui64 ..... .... ... ..... ... ..... ....... &i imm=3D%imm_p_ui64 %rs1 %= rd @@ -1219,3 +1221,58 @@ pmin_w 1110001 ..... ..... 110 ..... 0111011 @r pminu_w 1110101 ..... ..... 110 ..... 0111011 @r pmax_w 1111001 ..... ..... 110 ..... 0111011 @r pmaxu_w 1111101 ..... ..... 110 ..... 0111011 @r + +# Packed SIMD - Shift Operations +pslli_b 10000 0001... ..... 010 ..... 0011011 @p_ui8 +psll_bs 1000110 ..... ..... 010 ..... 0011011 @r +pslli_h 10000 001.... ..... 010 ..... 0011011 @p_ui16 +psll_hs 1000100 ..... ..... 010 ..... 0011011 @r +pslli_w 10000 01..... ..... 010 ..... 0011011 @p_ui32 +psll_ws 1000101 ..... ..... 010 ..... 0011011 @r +psrli_b 10000 0001... ..... 100 ..... 0011011 @p_ui8 +psrl_bs 1000110 ..... ..... 100 ..... 0011011 @r +psrli_h 10000 001.... ..... 100 ..... 0011011 @p_ui16 +psrl_hs 1000100 ..... ..... 100 ..... 0011011 @r +psrli_w 10000 01..... ..... 100 ..... 0011011 @p_ui32 +psrl_ws 1000101 ..... ..... 100 ..... 0011011 @r +psrai_b 11000 0001... ..... 100 ..... 0011011 @p_ui8 +psra_bs 1100110 ..... ..... 100 ..... 0011011 @r +psrai_h 11000 001.... ..... 100 ..... 0011011 @p_ui16 +psra_hs 1100100 ..... ..... 100 ..... 0011011 @r +psrai_w 11000 01..... ..... 100 ..... 0011011 @p_ui32 +psra_ws 1100101 ..... ..... 100 ..... 0011011 @r +psslai_h 11010 001.... ..... 010 ..... 0011011 @p_ui16 +{ + sslai 11010 01..... ..... 010 ..... 0011011 @p_ui32 + psslai_w 11010 01..... ..... 010 ..... 0011011 @p_ui32 +} +psrari_h 11010 001.... ..... 100 ..... 0011011 @p_ui16 +{ + srari_32 11010 01..... ..... 100 ..... 0011011 @p_ui32 + psrari_w 11010 01..... ..... 100 ..... 0011011 @p_ui32 +} +srari_64 110101 ...... ..... 100 ..... 0011011 @p_ui64 +pssha_hs 1110100 ..... ..... 010 ..... 0011011 @r +{ + ssha 1110101 ..... ..... 010 ..... 0011011 @r + pssha_ws 1110101 ..... ..... 010 ..... 0011011 @r +} +psshar_hs 1111100 ..... ..... 010 ..... 0011011 @r +{ + sshar 1111101 ..... ..... 010 ..... 0011011 @r + psshar_ws 1111101 ..... ..... 010 ..... 0011011 @r +} +sha 1110111 ..... ..... 010 ..... 0011011 @r +shar 1111111 ..... ..... 010 ..... 0011011 @r +psshl_hs 1010100 ..... ..... 010 ..... 0011011 @r +psshlr_hs 1011100 ..... ..... 010 ..... 0011011 @r +{ + psshl_ws 1010101 ..... ..... 010 ..... 0011011 @r + sshl 1010101 ..... ..... 010 ..... 0011011 @r +} +{ + psshlr_ws 1011101 ..... ..... 010 ..... 0011011 @r + sshlr 1011101 ..... ..... 010 ..... 0011011 @r +} +shl 1010111 ..... ..... 010 ..... 0011011 @r +shlr 1011111 ..... ..... 010 ..... 0011011 @r diff --git a/target/riscv/tcg/insn_trans/trans_rvp.c.inc b/target/riscv/tcg= /insn_trans/trans_rvp.c.inc index 81d3f90eb08..32b5de9f1b6 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -607,3 +607,46 @@ GEN_SIMD_TRANS_64(pmaxu_w) GEN_SIMD_TRANS_32(mseq) GEN_SIMD_TRANS_32(mslt) GEN_SIMD_TRANS_32(msltu) + +/* Packed SIMD - Shift Operations */ +GEN_SIMD_TRANS_IMM(pslli_b) +GEN_SIMD_TRANS(psll_bs) +GEN_SIMD_TRANS_IMM(pslli_h) +GEN_SIMD_TRANS(psll_hs) +GEN_SIMD_TRANS_IMM_64(pslli_w) +GEN_SIMD_TRANS_64(psll_ws) +GEN_SIMD_TRANS_IMM(psrli_b) +GEN_SIMD_TRANS(psrl_bs) +GEN_SIMD_TRANS_IMM(psrli_h) +GEN_SIMD_TRANS(psrl_hs) +GEN_SIMD_TRANS_IMM_64(psrli_w) +GEN_SIMD_TRANS_64(psrl_ws) +GEN_SIMD_TRANS_IMM(psrai_b) +GEN_SIMD_TRANS(psra_bs) +GEN_SIMD_TRANS_IMM(psrai_h) +GEN_SIMD_TRANS(psra_hs) +GEN_SIMD_TRANS_IMM_64(psrai_w) +GEN_SIMD_TRANS_64(psra_ws) +GEN_SIMD_TRANS_IMM_VXSAT(psslai_h) +GEN_SIMD_TRANS_IMM_64_VXSAT(psslai_w) +GEN_SIMD_TRANS_IMM_32_VXSAT(sslai) +GEN_SIMD_TRANS_IMM(psrari_h) +GEN_SIMD_TRANS_IMM_64(psrari_w) +GEN_SIMD_TRANS_IMM_32(srari_32) +GEN_SIMD_TRANS_IMM_64(srari_64) +GEN_SIMD_TRANS_VXSAT(pssha_hs) +GEN_SIMD_TRANS_64_VXSAT(pssha_ws) +GEN_SIMD_TRANS_VXSAT(psshar_hs) +GEN_SIMD_TRANS_64_VXSAT(psshar_ws) +GEN_SIMD_TRANS_32_VXSAT(ssha) +GEN_SIMD_TRANS_32_VXSAT(sshar) +GEN_SIMD_TRANS_64(sha) +GEN_SIMD_TRANS_64(shar) +GEN_SIMD_TRANS_VXSAT(psshl_hs) +GEN_SIMD_TRANS_VXSAT(psshlr_hs) +GEN_SIMD_TRANS_64_VXSAT(psshl_ws) +GEN_SIMD_TRANS_64_VXSAT(psshlr_ws) +GEN_SIMD_TRANS_32_VXSAT(sshl) +GEN_SIMD_TRANS_32_VXSAT(sshlr) +GEN_SIMD_TRANS_64(shl) +GEN_SIMD_TRANS_64(shlr) diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helpe= r.c index 625928dc1dd..cd110aa1cdc 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -2295,3 +2295,126 @@ GEN_PSIMD_BINOP(mslt, uint32_t, int32_t, uint32_t, EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_LT_MASK) GEN_PSIMD_BINOP(msltu, uint32_t, uint32_t, uint32_t, EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_LT_MASK) + +/* Shift operations (immediate and register) */ + +GEN_PSIMD_SHIFTOP(pslli_b, target_ulong, uint8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, 0x07, PSIMD_DO_SLL) +GEN_PSIMD_SHIFTOP(psll_bs, target_ulong, uint8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, 0x1f, PSIMD_DO_SLL) +GEN_PSIMD_SHIFTOP(pslli_h, target_ulong, uint16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 0x0f, PSIMD_DO_SLL) +GEN_PSIMD_SHIFTOP(psll_hs, target_ulong, uint16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 0x1f, PSIMD_DO_SLL) +GEN_PSIMD_SHIFTOP(pslli_w, uint64_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 0x1f, PSIMD_DO_SLL) +GEN_PSIMD_SHIFTOP(psll_ws, uint64_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 0x1f, PSIMD_DO_SLL) + +GEN_PSIMD_SHIFTOP(psrli_b, target_ulong, uint8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, 0x07, PSIMD_DO_SRL) +GEN_PSIMD_SHIFTOP(psrl_bs, target_ulong, uint8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, 0x1f, PSIMD_DO_SRL) +GEN_PSIMD_SHIFTOP(psrli_h, target_ulong, uint16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 0x0f, PSIMD_DO_SRL) +GEN_PSIMD_SHIFTOP(psrl_hs, target_ulong, uint16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 0x1f, PSIMD_DO_SRL) +GEN_PSIMD_SHIFTOP(psrli_w, uint64_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 0x1f, PSIMD_DO_SRL) +GEN_PSIMD_SHIFTOP(psrl_ws, uint64_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 0x1f, PSIMD_DO_SRL) + +GEN_PSIMD_SHIFTOP(psrai_b, target_ulong, int8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, 0x07, PSIMD_DO_SRA) +GEN_PSIMD_SHIFTOP(psra_bs, target_ulong, int8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, 0x1f, PSIMD_DO_SRA) +GEN_PSIMD_SHIFTOP(psrai_h, target_ulong, int16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 0x0f, PSIMD_DO_SRA) +GEN_PSIMD_SHIFTOP(psra_hs, target_ulong, int16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 0x1f, PSIMD_DO_SRA) +GEN_PSIMD_SHIFTOP(psrai_w, uint64_t, int32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 0x1f, PSIMD_DO_SRA) +GEN_PSIMD_SHIFTOP(psra_ws, uint64_t, int32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 0x1f, PSIMD_DO_SRA) + +/* Saturating shift operations */ + +GEN_PSIMD_SAT_SHIFTOP(psslai_h, target_ulong, int16_t, int32_t, + EXTRACT16, INSERT16, ELEMS_H, 0x0f, + signed_saturate_h) +GEN_PSIMD_SAT_SHIFTOP(psslai_w, uint64_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, 0x1f, + signed_saturate_w) + +GEN_PSIMD_SAT_SHIFTOP(sslai, uint32_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, 0x1f, + signed_saturate_w) + +/* Rounding shift operations */ + +GEN_PSIMD_ROUND_SRAI(psrari_h, target_ulong, int16_t, int32_t, + EXTRACT16, INSERT16, ELEMS_H, 0x0f) +GEN_PSIMD_ROUND_SRAI(psrari_w, uint64_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, 0x1f) + +GEN_PSIMD_ROUND_SRAI(srari_32, uint32_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, 0x1f) + +/** + * SRARI (RV64) - Scalar arithmetic shift right with rounding + */ +uint64_t HELPER(srari_64)(CPURISCVState *env, uint64_t rs1, uint64_t imm) +{ + int64_t a =3D (int64_t)rs1; + uint8_t shamt =3D imm & 0x3F; + + if (shamt =3D=3D 0) { + return rs1; + } + + return (uint64_t)((((__int128_t)a >> (shamt - 1)) + 1) >> 1); +} + +/* Variable shift operations (with saturation and rounding) */ + +GEN_PSIMD_VAR_SSHA(pssha_hs, target_ulong, int16_t, int32_t, + EXTRACT16, INSERT16, ELEMS_H, 16, signed_saturate_h) +GEN_PSIMD_VAR_SSHA(pssha_ws, uint64_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, 32, signed_saturate_w) + +GEN_PSIMD_VAR_SSHAR(psshar_hs, target_ulong, int16_t, int32_t, + EXTRACT16, INSERT16, ELEMS_H, 16, SAT_MIN_H, SAT_MAX_H, + signed_saturate_h) +GEN_PSIMD_VAR_SSHAR(psshar_ws, uint64_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, 32, SAT_MIN_W, SAT_MAX_W, + signed_saturate_w) + +GEN_PSIMD_VAR_SSHA(ssha, uint32_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, 32, signed_saturate_w) +GEN_PSIMD_VAR_SSHAR(sshar, uint32_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, 32, SAT_MIN_W, SAT_MAX_W, + signed_saturate_w) + +GEN_PSIMD_VAR_SRA64(sha, PSIMD_DO_SRA64) +GEN_PSIMD_VAR_SRA64(shar, PSIMD_DO_RNDSRA64) + +GEN_PSIMD_VAR_USHL(psshl_hs, target_ulong, uint16_t, uint32_t, + EXTRACT16, INSERT16, ELEMS_H, 16, unsigned_saturate_h) + +GEN_PSIMD_VAR_USHLR(psshlr_hs, target_ulong, uint16_t, uint32_t, + EXTRACT16, INSERT16, ELEMS_H, 16, unsigned_saturate_h) + +GEN_PSIMD_VAR_USHL(psshl_ws, uint64_t, uint32_t, uint64_t, + EXTRACT32, INSERT32, ELEMS_W, 32, unsigned_saturate_w) + +GEN_PSIMD_VAR_USHLR(psshlr_ws, uint64_t, uint32_t, uint64_t, + EXTRACT32, INSERT32, ELEMS_W, 32, unsigned_saturate_w) + +GEN_PSIMD_VAR_USHL(sshl, uint32_t, uint32_t, uint64_t, + EXTRACT32, INSERT32, ELEMS_W, 32, unsigned_saturate_w) + +GEN_PSIMD_VAR_USHLR(sshlr, uint32_t, uint32_t, uint64_t, + EXTRACT32, INSERT32, ELEMS_W, 32, unsigned_saturate_w) + +GEN_PSIMD_VAR_SRL64(shl, PSIMD_DO_SRL64) +GEN_PSIMD_VAR_SRL64(shlr, PSIMD_DO_RNDSRL64) --=20 2.34.1 From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789542637089383.1120508950628; Wed, 16 Sep 2026 00:10:37 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jkm-0005oM-0N; Wed, 16 Sep 2026 03:08:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jka-0005dL-Ox; Wed, 16 Sep 2026 03:08:13 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jkU-0008JI-TU; Wed, 16 Sep 2026 03:08:12 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S9; Wed, 16 Sep 2026 15:08:02 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 07/19] target/riscv: Add packed SIMD exchange instructions Date: Wed, 16 Sep 2026 07:07:09 +0000 Message-Id: <20260916070721.3279229-8-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S9 X-Coremail-Antispam: 1UD129KBjvJXoW3Gr43tFWfWryfWry5tF47Arb_yoW7tr1fpa 97GFy3WayUKry3t3WSkr45tw13Gw4fKa1kursxKFsYva1DJF43XryUtr12kF47ZF9rXr1U Way0yr98AaykX3JanT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUQa14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_Xr0_Ar1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAaw2AFwI0_Jrv_JF1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I 8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_JF0_Jw1lYx0Ex4A2jsIE14v26F4j6r4UJwAm72CE 4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4 IIrI8v6xkF7I0E8cxan2IY04v7MxkF7I0En4kS14v26r1q6r43MxAIw28IcxkI7VAKI48J MxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwV AFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6xIIjxv2 0xvE14v26r1I6r4UMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr0_Cr1UMIIF0xvE42xK8V AvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWxJVW8Jr1lIxAIcVC2z280aVCY1x02 67AKxVW8Jr0_Cr1UYxBIdaVFxhVjvjDU0xZFpf9x0JULSdkUUUUU= X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542638616158500 Content-Type: text/plain; charset="utf-8" Implement packed add-subtract cross operations. Cover normal, saturating, and averaging variants for halfword and word elements. Add the associated decode entries, translators and helpers. These instructions perform addition and subtraction using crossed source elements within each packed element pair. Note that saturating variants clamp results to the signed element range and set vxsat when saturation occurs, while averaging variants shift the intermediate results right by one bit and do not affect vxsat. Signed-off-by: Molly Chen --- target/riscv/helper.h | 14 +++++++ target/riscv/insn32.decode | 14 +++++++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 14 +++++++ target/riscv/tcg/psimd_helper.c | 44 +++++++++++++++++++++ 4 files changed, 86 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 53107334e1f..cca3b88535d 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1497,3 +1497,17 @@ DEF_HELPER_3(sshl, i32, env, i32, i32) DEF_HELPER_3(sshlr, i32, env, i32, i32) DEF_HELPER_3(shl, i64, env, i64, i64) DEF_HELPER_3(shlr, i64, env, i64, i64) + +/* Packed SIMD - Exchange Operations */ +DEF_HELPER_3(pas_hx, tl, env, tl, tl) +DEF_HELPER_3(psa_hx, tl, env, tl, tl) +DEF_HELPER_3(psas_hx, tl, env, tl, tl) +DEF_HELPER_3(pssa_hx, tl, env, tl, tl) +DEF_HELPER_3(paas_hx, tl, env, tl, tl) +DEF_HELPER_3(pasa_hx, tl, env, tl, tl) +DEF_HELPER_3(pas_wx, i64, env, i64, i64) +DEF_HELPER_3(psa_wx, i64, env, i64, i64) +DEF_HELPER_3(psas_wx, i64, env, i64, i64) +DEF_HELPER_3(pssa_wx, i64, env, i64, i64) +DEF_HELPER_3(paas_wx, i64, env, i64, i64) +DEF_HELPER_3(pasa_wx, i64, env, i64, i64) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 82434b10410..3cfd8602c1c 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -1276,3 +1276,17 @@ psshlr_hs 1011100 ..... ..... 010 ..... 0011011 @r } shl 1010111 ..... ..... 010 ..... 0011011 @r shlr 1011111 ..... ..... 010 ..... 0011011 @r + +# Packed SIMD - Exchange Operations +pas_hx 1000000 ..... ..... 110 ..... 0111011 @r +psa_hx 1000010 ..... ..... 110 ..... 0111011 @r +psas_hx 1001000 ..... ..... 110 ..... 0111011 @r +pssa_hx 1001010 ..... ..... 110 ..... 0111011 @r +paas_hx 1001100 ..... ..... 110 ..... 0111011 @r +pasa_hx 1001110 ..... ..... 110 ..... 0111011 @r +pas_wx 1000001 ..... ..... 110 ..... 0111011 @r +psa_wx 1000011 ..... ..... 110 ..... 0111011 @r +psas_wx 1001001 ..... ..... 110 ..... 0111011 @r +pssa_wx 1001011 ..... ..... 110 ..... 0111011 @r +paas_wx 1001101 ..... ..... 110 ..... 0111011 @r +pasa_wx 1001111 ..... ..... 110 ..... 0111011 @r diff --git a/target/riscv/tcg/insn_trans/trans_rvp.c.inc b/target/riscv/tcg= /insn_trans/trans_rvp.c.inc index 32b5de9f1b6..c991ac37e32 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -650,3 +650,17 @@ GEN_SIMD_TRANS_32_VXSAT(sshl) GEN_SIMD_TRANS_32_VXSAT(sshlr) GEN_SIMD_TRANS_64(shl) GEN_SIMD_TRANS_64(shlr) + +/* Packed SIMD - Exchange Operations */ +GEN_SIMD_TRANS(pas_hx) +GEN_SIMD_TRANS(psa_hx) +GEN_SIMD_TRANS_VXSAT(psas_hx) +GEN_SIMD_TRANS_VXSAT(pssa_hx) +GEN_SIMD_TRANS(paas_hx) +GEN_SIMD_TRANS(pasa_hx) +GEN_SIMD_TRANS_64(pas_wx) +GEN_SIMD_TRANS_64(psa_wx) +GEN_SIMD_TRANS_64_VXSAT(psas_wx) +GEN_SIMD_TRANS_64_VXSAT(pssa_wx) +GEN_SIMD_TRANS_64(paas_wx) +GEN_SIMD_TRANS_64(pasa_wx) diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helpe= r.c index cd110aa1cdc..0cb81151d79 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -2418,3 +2418,47 @@ GEN_PSIMD_VAR_USHLR(sshlr, uint32_t, uint32_t, uint6= 4_t, =20 GEN_PSIMD_VAR_SRL64(shl, PSIMD_DO_SRL64) GEN_PSIMD_VAR_SRL64(shlr, PSIMD_DO_RNDSRL64) + +/* Cross add/subtract operations */ + +GEN_PSIMD_XPAIR_BINOP(pas_hx, target_ulong, int16_t, + EXTRACT16, INSERT16, ELEMS_H, + PSIMD_DO_SUB, PSIMD_DO_ADD) +GEN_PSIMD_XPAIR_BINOP(psa_hx, target_ulong, int16_t, + EXTRACT16, INSERT16, ELEMS_H, + PSIMD_DO_ADD, PSIMD_DO_SUB) + +GEN_PSIMD_XPAIR_SAT_BINOP(psas_hx, target_ulong, int16_t, int32_t, + EXTRACT16, INSERT16, ELEMS_H, + PSIMD_DO_SUB, PSIMD_DO_ADD, signed_saturate_h) +GEN_PSIMD_XPAIR_SAT_BINOP(pssa_hx, target_ulong, int16_t, int32_t, + EXTRACT16, INSERT16, ELEMS_H, + PSIMD_DO_ADD, PSIMD_DO_SUB, signed_saturate_h) + +GEN_PSIMD_XPAIR_AVG_BINOP(paas_hx, target_ulong, int16_t, int32_t, + EXTRACT16, INSERT16, ELEMS_H, + PSIMD_DO_SUB, PSIMD_DO_ADD) +GEN_PSIMD_XPAIR_AVG_BINOP(pasa_hx, target_ulong, int16_t, int32_t, + EXTRACT16, INSERT16, ELEMS_H, + PSIMD_DO_ADD, PSIMD_DO_SUB) + +GEN_PSIMD_XPAIR_BINOP(pas_wx, uint64_t, int32_t, + EXTRACT32, INSERT32, ELEMS_W, + PSIMD_DO_SUB, PSIMD_DO_ADD) +GEN_PSIMD_XPAIR_BINOP(psa_wx, uint64_t, int32_t, + EXTRACT32, INSERT32, ELEMS_W, + PSIMD_DO_ADD, PSIMD_DO_SUB) + +GEN_PSIMD_XPAIR_SAT_BINOP(psas_wx, uint64_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, + PSIMD_DO_SUB, PSIMD_DO_ADD, signed_saturate_w) +GEN_PSIMD_XPAIR_SAT_BINOP(pssa_wx, uint64_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, + PSIMD_DO_ADD, PSIMD_DO_SUB, signed_saturate_w) + +GEN_PSIMD_XPAIR_AVG_BINOP(paas_wx, uint64_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, + PSIMD_DO_SUB, PSIMD_DO_ADD) +GEN_PSIMD_XPAIR_AVG_BINOP(pasa_wx, uint64_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, + PSIMD_DO_ADD, PSIMD_DO_SUB) --=20 2.34.1 From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789542702354940.2372711734654; Wed, 16 Sep 2026 00:11:42 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jkg-0005fq-24; Wed, 16 Sep 2026 03:08:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jkZ-0005cW-DK; Wed, 16 Sep 2026 03:08:11 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jkU-0008JG-HV; Wed, 16 Sep 2026 03:08:10 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S10; Wed, 16 Sep 2026 15:08:02 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 08/19] target/riscv: Add packed SIMD horizontal reduction instructions Date: Wed, 16 Sep 2026 07:07:10 +0000 Message-Id: <20260916070721.3279229-9-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S10 X-Coremail-Antispam: 1UD129KBjvJXoWxZr4UZrW7KF1fuF45CF15urg_yoWrXF15pF s7GrW3JrWUJFyaqas3tr4Y9w13WwsYga15CwsaqFnYvay5JFWru34DKr12kF4UXF9rur1U Wa10yrZxAFWrX3JanT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUQa14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_Xr0_Ar1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAaw2AFwI0_Jrv_JF1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I 8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_JF0_Jw1lYx0Ex4A2jsIE14v26F4j6r4UJwAm72CE 4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4 IIrI8v6xkF7I0E8cxan2IY04v7MxkF7I0En4kS14v26r1q6r43MxAIw28IcxkI7VAKI48J MxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwV AFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6xIIjxv2 0xvE14v26r1I6r4UMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr0_Cr1UMIIF0xvE42xK8V AvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWxJVW8Jr1lIxAIcVC2z280aVCY1x02 67AKxVW8Jr0_Cr1UYxBIdaVFxhVjvjDU0xZFpf9x0JULSdkUUUUU= X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542702927158501 Content-Type: text/plain; charset="utf-8" Implement packed horizontal reduction-sum operations. Cover signed and unsigned variants for byte, halfword, and word elements. These instructions sum all packed elements in rs1 and add the result to rs2. Add the associated decode entries, translators and helpers. Signed-off-by: Molly Chen --- target/riscv/helper.h | 8 ++++++++ target/riscv/insn32.decode | 8 ++++++++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 8 ++++++++ target/riscv/tcg/psimd_helper.c | 15 +++++++++++++++ 4 files changed, 39 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index cca3b88535d..824779f05d0 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1511,3 +1511,11 @@ DEF_HELPER_3(psas_wx, i64, env, i64, i64) DEF_HELPER_3(pssa_wx, i64, env, i64, i64) DEF_HELPER_3(paas_wx, i64, env, i64, i64) DEF_HELPER_3(pasa_wx, i64, env, i64, i64) + +/* Packed SIMD - Horizontal Reduction Operations */ +DEF_HELPER_3(predsum_bs, tl, env, tl, tl) +DEF_HELPER_3(predsumu_bs, tl, env, tl, tl) +DEF_HELPER_3(predsum_hs, tl, env, tl, tl) +DEF_HELPER_3(predsumu_hs, tl, env, tl, tl) +DEF_HELPER_3(predsum_ws, i64, env, i64, i64) +DEF_HELPER_3(predsumu_ws, i64, env, i64, i64) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 3cfd8602c1c..3f8314d382b 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -1290,3 +1290,11 @@ psas_wx 1001001 ..... ..... 110 ..... 0111011 @r pssa_wx 1001011 ..... ..... 110 ..... 0111011 @r paas_wx 1001101 ..... ..... 110 ..... 0111011 @r pasa_wx 1001111 ..... ..... 110 ..... 0111011 @r + +# Packed SIMD - Horizontal Reduction Operations +predsum_bs 1001110 ..... ..... 100 ..... 0011011 @r +predsumu_bs 1011110 ..... ..... 100 ..... 0011011 @r +predsum_hs 1001100 ..... ..... 100 ..... 0011011 @r +predsumu_hs 1011100 ..... ..... 100 ..... 0011011 @r +predsum_ws 1001101 ..... ..... 100 ..... 0011011 @r +predsumu_ws 1011101 ..... ..... 100 ..... 0011011 @r diff --git a/target/riscv/tcg/insn_trans/trans_rvp.c.inc b/target/riscv/tcg= /insn_trans/trans_rvp.c.inc index c991ac37e32..726707b2956 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -664,3 +664,11 @@ GEN_SIMD_TRANS_64_VXSAT(psas_wx) GEN_SIMD_TRANS_64_VXSAT(pssa_wx) GEN_SIMD_TRANS_64(paas_wx) GEN_SIMD_TRANS_64(pasa_wx) + +/* Packed SIMD - Horizontal Reduction Operations */ +GEN_SIMD_TRANS(predsum_bs) +GEN_SIMD_TRANS(predsumu_bs) +GEN_SIMD_TRANS(predsum_hs) +GEN_SIMD_TRANS(predsumu_hs) +GEN_SIMD_TRANS_64(predsum_ws) +GEN_SIMD_TRANS_64(predsumu_ws) diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helpe= r.c index 0cb81151d79..397efa66aeb 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -2462,3 +2462,18 @@ GEN_PSIMD_XPAIR_AVG_BINOP(paas_wx, uint64_t, int32_t= , int64_t, GEN_PSIMD_XPAIR_AVG_BINOP(pasa_wx, uint64_t, int32_t, int64_t, EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_ADD, PSIMD_DO_SUB) + +/* Horizontal sum operations */ + +GEN_PSIMD_REDSUM(predsum_bs, target_ulong, int64_t, int8_t, + EXTRACT8, ELEMS_B, (int64_t)(int32_t)rs2) +GEN_PSIMD_REDSUM(predsumu_bs, target_ulong, uint64_t, uint8_t, + EXTRACT8, ELEMS_B, rs2) +GEN_PSIMD_REDSUM(predsum_hs, target_ulong, int64_t, int16_t, + EXTRACT16, ELEMS_H, (int64_t)(int32_t)rs2) +GEN_PSIMD_REDSUM(predsumu_hs, target_ulong, uint64_t, uint16_t, + EXTRACT16, ELEMS_H, rs2) +GEN_PSIMD_REDSUM(predsum_ws, uint64_t, int64_t, int32_t, + EXTRACT32, ELEMS_W, (int64_t)rs2) +GEN_PSIMD_REDSUM(predsumu_ws, uint64_t, uint64_t, uint32_t, + EXTRACT32, ELEMS_W, rs2) --=20 2.34.1 From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789542722391120.3452935384355; Wed, 16 Sep 2026 00:12:02 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jlA-00069n-5L; Wed, 16 Sep 2026 03:08:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jkt-0005qA-Qt; Wed, 16 Sep 2026 03:08:33 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jkp-0008JX-Hi; Wed, 16 Sep 2026 03:08:31 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S11; Wed, 16 Sep 2026 15:08:02 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 09/19] target/riscv: Add packed SIMD pack, merge and count-leading instructions Date: Wed, 16 Sep 2026 07:07:11 +0000 Message-Id: <20260916070721.3279229-10-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S11 X-Coremail-Antispam: 1UD129KBjvAXoW3CrWkJF17Aw48uryUJrWrXwb_yoW8JF43Go Z3Cr15ZryrGry5X343Cw48Xwn7ZrWIvan5Gr4rZw17Was7Xr1xWr1Dt34UZw1xXry5trW3 Xa9ak3WYy3WSgwnrn29KB7ZKAUJUUUUr529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUO97AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r126s0DM28Irc Ia0xkI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l 84ACjcxK6xIIjxv20xvE14v26ryj6F1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4UJV WxJr1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE 3s1ln4kS14v26r1Y6r17M2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c 02F40Ex7xfMcIj6xIIjxv20xvE14v26r126r1DMcIj6I8E87Iv67AKxVWxJVW8Jr1lOx8S 6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxw ACI402YVCY1x02628vn2kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxG rwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4 vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IY x2IY67AKxVWUCVW8JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw2 0EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Cr0_Gr1UMIIF0xvEx4A2jsIEc7Cj xVAFwI0_Gr1j6F4UJbIYCTnIWIevJa73UjIFyTuYvjfUoBTYUUUUU X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542722854158500 Content-Type: text/plain; charset="utf-8" Implement packed pairing, sign-extension, reversal, zip and unzip, shift-and-merge, narrowing clipping, and count-leading-sign operations. Cover the supported element widths and signed and unsigned clipping variants. Add the associated decode entries, translators and helpers. Note that the narrowing clipping instructions combine elements from two source registers and clamp each result to the destination element range. They set vxsat when saturation occurs. Signed-off-by: Molly Chen --- target/riscv/helper.h | 41 ++++++ target/riscv/insn32.decode | 42 ++++++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 57 ++++++++ target/riscv/tcg/psimd_helper.c | 152 ++++++++++++++++++++ 4 files changed, 292 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 824779f05d0..55d95c6eb6d 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1519,3 +1519,44 @@ DEF_HELPER_3(predsum_hs, tl, env, tl, tl) DEF_HELPER_3(predsumu_hs, tl, env, tl, tl) DEF_HELPER_3(predsum_ws, i64, env, i64, i64) DEF_HELPER_3(predsumu_ws, i64, env, i64, i64) + +/* Packed SIMD - Pack, Unpack, and Merge Operations */ +DEF_HELPER_3(ppaire_b, tl, env, tl, tl) +DEF_HELPER_3(ppaireo_b, tl, env, tl, tl) +DEF_HELPER_3(ppairoe_b, tl, env, tl, tl) +DEF_HELPER_3(ppairo_b, tl, env, tl, tl) +DEF_HELPER_3(ppaire_h, i64, env, i64, i64) +DEF_HELPER_3(ppaireo_h, tl, env, tl, tl) +DEF_HELPER_3(ppairoe_h, tl, env, tl, tl) +DEF_HELPER_3(ppairo_h, tl, env, tl, tl) +DEF_HELPER_3(ppaireo_w, i64, env, i64, i64) +DEF_HELPER_3(ppairoe_w, i64, env, i64, i64) +DEF_HELPER_3(ppairo_w, i64, env, i64, i64) +DEF_HELPER_2(psext_h_b, tl, env, tl) +DEF_HELPER_2(psext_w_b, i64, env, i64) +DEF_HELPER_2(psext_w_h, i64, env, i64) +DEF_HELPER_2(rev, tl, env, tl) +DEF_HELPER_2(rev16, i64, env, i64) +DEF_HELPER_3(zip8p, i64, env, i64, i64) +DEF_HELPER_3(zip8hp, i64, env, i64, i64) +DEF_HELPER_3(unzip8p, i64, env, i64, i64) +DEF_HELPER_3(unzip8hp, i64, env, i64, i64) +DEF_HELPER_3(zip16p, i64, env, i64, i64) +DEF_HELPER_3(zip16hp, i64, env, i64, i64) +DEF_HELPER_3(unzip16p, i64, env, i64, i64) +DEF_HELPER_3(unzip16hp, i64, env, i64, i64) +DEF_HELPER_4(slx, tl, env, tl, tl, tl) +DEF_HELPER_4(srx, tl, env, tl, tl, tl) +DEF_HELPER_4(mvm, tl, env, tl, tl, tl) +DEF_HELPER_4(mvmn, tl, env, tl, tl, tl) +DEF_HELPER_4(merge, tl, env, tl, tl, tl) +DEF_HELPER_3(pnclipp_b, i64, env, i64, i64) +DEF_HELPER_3(pnclipup_b, i64, env, i64, i64) +DEF_HELPER_3(pnclipp_h, i64, env, i64, i64) +DEF_HELPER_3(pnclipup_h, i64, env, i64, i64) +DEF_HELPER_3(pnclipp_w, i64, env, i64, i64) +DEF_HELPER_3(pnclipup_w, i64, env, i64, i64) + +/* Packed SIMD - Count Leading Operations */ +DEF_HELPER_2(cls, tl, env, tl) +DEF_HELPER_2(clsw, i64, env, i64) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 3f8314d382b..38210bb4934 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -1298,3 +1298,45 @@ predsum_hs 1001100 ..... ..... 100 ..... 0011011 @r predsumu_hs 1011100 ..... ..... 100 ..... 0011011 @r predsum_ws 1001101 ..... ..... 100 ..... 0011011 @r predsumu_ws 1011101 ..... ..... 100 ..... 0011011 @r + +# Packed SIMD - Pack, Unpack, and Merge Operations +ppaire_b 1000000 ..... ..... 100 ..... 0111011 @r +ppaireo_b 1001000 ..... ..... 100 ..... 0111011 @r +ppairoe_b 1010000 ..... ..... 100 ..... 0111011 @r +ppairo_b 1011000 ..... ..... 100 ..... 0111011 @r +ppaireo_h 1001001 ..... ..... 100 ..... 0111011 @r +ppairoe_h 1010001 ..... ..... 100 ..... 0111011 @r +ppairo_h 1011001 ..... ..... 100 ..... 0111011 @r +ppaire_h 1000001 ..... ..... 100 ..... 0111011 @r +ppaireo_w 1001011 ..... ..... 100 ..... 0111011 @r +ppairoe_w 1010011 ..... ..... 100 ..... 0111011 @r +ppairo_w 1011011 ..... ..... 100 ..... 0111011 @r +psext_h_b 1110000 00100 ..... 010 ..... 0011011 @r2 +psext_w_b 1110001 00100 ..... 010 ..... 0011011 @r2 +psext_w_h 1110001 00101 ..... 010 ..... 0011011 @r2 +rev_32 01101 0011111 ..... 101 ..... 0010011 @r2 +rev_64 01101 0111111 ..... 101 ..... 0010011 @r2 +rev16 01101 0110000 ..... 101 ..... 0010011 @r2 +zip8p 1111000 ..... ..... 010 ..... 0111011 @r +zip8hp 1111010 ..... ..... 010 ..... 0111011 @r +unzip8p 1110000 ..... ..... 010 ..... 0111011 @r +unzip8hp 1110010 ..... ..... 010 ..... 0111011 @r +zip16p 1111001 ..... ..... 010 ..... 0111011 @r +zip16hp 1111011 ..... ..... 010 ..... 0111011 @r +unzip16p 1110001 ..... ..... 010 ..... 0111011 @r +unzip16hp 1110011 ..... ..... 010 ..... 0111011 @r +slx 1000111 ..... ..... 001 ..... 0111011 @r +srx 1010111 ..... ..... 001 ..... 0111011 @r +mvm 1010100 ..... ..... 001 ..... 0111011 @r +mvmn 1010101 ..... ..... 001 ..... 0111011 @r +merge 1010110 ..... ..... 001 ..... 0111011 @r +pnclipp_b 1100000 ..... ..... 010 ..... 0111011 @r +pnclipup_b 1000000 ..... ..... 010 ..... 0111011 @r +pnclipp_h 1100001 ..... ..... 010 ..... 0111011 @r +pnclipup_h 1000001 ..... ..... 010 ..... 0111011 @r +pnclipp_w 1100011 ..... ..... 010 ..... 0111011 @r +pnclipup_w 1000011 ..... ..... 010 ..... 0111011 @r + +# Packed SIMD - Count Leading Operations +cls 01100 0000011 ..... 001 ..... 0010011 @r2 +clsw 01100 0000011 ..... 001 ..... 0011011 @r2 diff --git a/target/riscv/tcg/insn_trans/trans_rvp.c.inc b/target/riscv/tcg= /insn_trans/trans_rvp.c.inc index 726707b2956..2c9a34b9a7e 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -672,3 +672,60 @@ GEN_SIMD_TRANS(predsum_hs) GEN_SIMD_TRANS(predsumu_hs) GEN_SIMD_TRANS_64(predsum_ws) GEN_SIMD_TRANS_64(predsumu_ws) + +/* Packed SIMD - Pack, Unpack, and Merge Operations */ +GEN_SIMD_TRANS(ppaire_b) +GEN_SIMD_TRANS(ppaireo_b) +GEN_SIMD_TRANS(ppairoe_b) +GEN_SIMD_TRANS(ppairo_b) +GEN_SIMD_TRANS_64(ppaire_h) +GEN_SIMD_TRANS(ppaireo_h) +GEN_SIMD_TRANS(ppairoe_h) +GEN_SIMD_TRANS(ppairo_h) +GEN_SIMD_TRANS_64(ppaireo_w) +GEN_SIMD_TRANS_64(ppairoe_w) +GEN_SIMD_TRANS_64(ppairo_w) +GEN_SIMD_TRANS_R1(psext_h_b) +GEN_SIMD_TRANS_R1_64(psext_w_b) +GEN_SIMD_TRANS_R1_64(psext_w_h) +#if defined(TARGET_RISCV32) +static bool trans_rev_32(DisasContext *ctx, arg_rev_32 * a) +{ + REQUIRE_32BIT(ctx); + GEN_SIMD_TRANS_R1_BODY(rev, false); +} + +GEN_SIMD_TRANS_UNAVAILABLE_64(rev_64) +#else +GEN_SIMD_TRANS_UNAVAILABLE_32(rev_32) + +static bool trans_rev_64(DisasContext *ctx, arg_rev_64 * a) +{ + REQUIRE_64BIT(ctx); + GEN_SIMD_TRANS_R1_BODY(rev, false); +} +#endif +GEN_SIMD_TRANS_R1_64(rev16) +GEN_SIMD_TRANS_64(zip8p) +GEN_SIMD_TRANS_64(zip8hp) +GEN_SIMD_TRANS_64(unzip8p) +GEN_SIMD_TRANS_64(unzip8hp) +GEN_SIMD_TRANS_64(zip16p) +GEN_SIMD_TRANS_64(zip16hp) +GEN_SIMD_TRANS_64(unzip16p) +GEN_SIMD_TRANS_64(unzip16hp) +GEN_SIMD_TRANS_ACC(slx) +GEN_SIMD_TRANS_ACC(srx) +GEN_SIMD_TRANS_ACC(mvm) +GEN_SIMD_TRANS_ACC(mvmn) +GEN_SIMD_TRANS_ACC(merge) +GEN_SIMD_TRANS_64_VXSAT(pnclipp_b) +GEN_SIMD_TRANS_64_VXSAT(pnclipup_b) +GEN_SIMD_TRANS_64_VXSAT(pnclipp_h) +GEN_SIMD_TRANS_64_VXSAT(pnclipup_h) +GEN_SIMD_TRANS_64_VXSAT(pnclipp_w) +GEN_SIMD_TRANS_64_VXSAT(pnclipup_w) + +/* Packed SIMD - Count Leading Operations */ +GEN_SIMD_TRANS_R1(cls) +GEN_SIMD_TRANS_R1_64(clsw) diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helpe= r.c index 397efa66aeb..f883596fe49 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -2477,3 +2477,155 @@ GEN_PSIMD_REDSUM(predsum_ws, uint64_t, int64_t, int= 32_t, EXTRACT32, ELEMS_W, (int64_t)rs2) GEN_PSIMD_REDSUM(predsumu_ws, uint64_t, uint64_t, uint32_t, EXTRACT32, ELEMS_W, rs2) + +/* Packing/unpacking operations */ + +GEN_PSIMD_PAIR_PACK(ppaire_b, target_ulong, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 0x00ff, 8, + PSIMD_PAIR_LO, PSIMD_PAIR_LO) +GEN_PSIMD_PAIR_PACK(ppaireo_b, target_ulong, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 0x00ff, 8, + PSIMD_PAIR_HI, PSIMD_PAIR_LO) +GEN_PSIMD_PAIR_PACK(ppairoe_b, target_ulong, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 0x00ff, 8, + PSIMD_PAIR_LO, PSIMD_PAIR_HI) +GEN_PSIMD_PAIR_PACK(ppairo_b, target_ulong, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 0x00ff, 8, + PSIMD_PAIR_HI, PSIMD_PAIR_HI) + +GEN_PSIMD_PAIR_PACK(ppaire_h, uint64_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 0x0000ffff, 16, + PSIMD_PAIR_LO, PSIMD_PAIR_LO) +GEN_PSIMD_PAIR_PACK(ppaireo_h, target_ulong, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 0x0000ffff, 16, + PSIMD_PAIR_HI, PSIMD_PAIR_LO) +GEN_PSIMD_PAIR_PACK(ppairoe_h, target_ulong, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 0x0000ffff, 16, + PSIMD_PAIR_LO, PSIMD_PAIR_HI) +GEN_PSIMD_PAIR_PACK(ppairo_h, target_ulong, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 0x0000ffff, 16, + PSIMD_PAIR_HI, PSIMD_PAIR_HI) + +GEN_PSIMD_PAIR_WORD(ppaireo_w, 0, 1) +GEN_PSIMD_PAIR_WORD(ppairoe_w, 1, 0) +GEN_PSIMD_PAIR_WORD(ppairo_w, 1, 1) + +GEN_PSIMD_SIGN_EXTEND(psext_h_b, target_ulong, int8_t, int16_t, + EXTRACT8, INSERT16, ELEMS_H, 2) +GEN_PSIMD_SIGN_EXTEND(psext_w_b, uint64_t, int8_t, int32_t, + EXTRACT8, INSERT32, ELEMS_W, 4) +GEN_PSIMD_SIGN_EXTEND(psext_w_h, uint64_t, int16_t, int32_t, + EXTRACT16, INSERT32, ELEMS_W, 2) + +/** + * REV - Reverse the bit order of the full XLEN-wide value + */ +target_ulong HELPER(rev)(CPURISCVState *env, target_ulong rs1) +{ + target_ulong rd =3D 0; + + for (int i =3D 0; i < TARGET_LONG_BITS; i++) { + rd =3D (rd << 1) | (rs1 & 1); + rs1 >>=3D 1; + } + + return rd; +} + +/** + * REV16 - Reverse the order of 16-bit chunks (RV64 only) + */ +uint64_t HELPER(rev16)(CPURISCVState *env, uint64_t rs1) +{ + uint64_t rd =3D 0; + + for (int i =3D 0; i < 4; i++) { + uint16_t chunk =3D EXTRACT16(rs1, i); + rd =3D (rd << 16) | chunk; + } + + return rd; +} + +GEN_PSIMD_ZIP(zip8p, uint8_t, EXTRACT8, 4, 8, 3) +GEN_PSIMD_ZIP(zip8hp, uint8_t, EXTRACT8, 4, 8, 7) +GEN_PSIMD_UNZIP(unzip8p, EXTRACT8, 4, 8, 0) +GEN_PSIMD_UNZIP(unzip8hp, EXTRACT8, 4, 8, 1) + +GEN_PSIMD_ZIP(zip16p, uint16_t, EXTRACT16, 2, 16, 1) +GEN_PSIMD_ZIP(zip16hp, uint16_t, EXTRACT16, 2, 16, 3) +GEN_PSIMD_UNZIP(unzip16p, EXTRACT16, 2, 16, 0) +GEN_PSIMD_UNZIP(unzip16hp, EXTRACT16, 2, 16, 1) + +/* Merge and mask operations */ + +/** + * SLX - Shift left extended (concatenate rd and rs1, shift left, take upp= er) + */ +target_ulong HELPER(slx)(CPURISCVState *env, target_ulong rs1, + target_ulong rs2, target_ulong rd) +{ + int shamt =3D (TARGET_LONG_BITS =3D=3D 32) ? (rs2 & 0x1F) : (rs2 & 0x3= F); + target_ulong xrs1 =3D 0; + target_ulong xrd =3D 0; + + if (shamt =3D=3D 0) { + xrd =3D rd; + } else if (shamt <=3D TARGET_LONG_BITS) { + xrs1 =3D rs1 >> (TARGET_LONG_BITS - shamt); + xrd =3D (rd << shamt) + xrs1; + } else { + xrd =3D rs1 << (shamt - TARGET_LONG_BITS); + } + + return xrd; +} + +/** + * SRX - Shift right extended (concatenate rs1 and rd, shift right, take l= ower) + */ +target_ulong HELPER(srx)(CPURISCVState *env, target_ulong rs1, + target_ulong rs2, target_ulong rd) +{ + int shamt =3D (TARGET_LONG_BITS =3D=3D 32) ? (rs2 & 0x1F) : (rs2 & 0x3= F); + target_ulong xrs1 =3D 0; + target_ulong xrd =3D 0; + + if (shamt =3D=3D 0) { + xrd =3D rd; + } else if (shamt <=3D TARGET_LONG_BITS) { + xrs1 =3D rs1 << (TARGET_LONG_BITS - shamt); + xrd =3D (rd >> shamt) + xrs1; + } else { + xrd =3D rs1 >> (shamt - TARGET_LONG_BITS); + } + + return xrd; +} + +GEN_PSIMD_BIT_SELECT(mvm, rs2, rs1, rd) +GEN_PSIMD_BIT_SELECT(mvmn, rs2, rd, rs1) +GEN_PSIMD_BIT_SELECT(merge, rd, rs2, rs1) + +GEN_PSIMD_NCLIP_PACK(pnclipp_b, int16_t, int8_t, + EXTRACT16, INSERT8, 4, signed_saturate_b) +GEN_PSIMD_NCLIP_PACK(pnclipup_b, uint16_t, uint8_t, + EXTRACT16, INSERT8, 4, unsigned_saturate_b) +GEN_PSIMD_NCLIP_PACK(pnclipp_h, int32_t, int16_t, + EXTRACT32, INSERT16, 2, signed_saturate_h) +GEN_PSIMD_NCLIP_PACK(pnclipup_h, uint32_t, uint16_t, + EXTRACT32, INSERT16, 2, unsigned_saturate_h) +GEN_PSIMD_NCLIP_PACK(pnclipp_w, int64_t, int32_t, + EXTRACT64, INSERT32_64, 1, signed_saturate_w) +GEN_PSIMD_NCLIP_PACK(pnclipup_w, uint64_t, uint32_t, + EXTRACT64, INSERT32_64, 1, unsigned_saturate_w) + +/* Count leading operations */ + +#if TARGET_LONG_BITS =3D=3D 64 +GEN_PSIMD_CLS(cls, target_ulong, uint64_t, clrsb64) +#else +GEN_PSIMD_CLS(cls, target_ulong, uint32_t, clrsb32) +#endif + +GEN_PSIMD_CLS(clsw, uint64_t, uint32_t, clrsb32) --=20 2.34.1 From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789542606627565.7650956076374; Wed, 16 Sep 2026 00:10:06 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jkk-0005nF-Sq; Wed, 16 Sep 2026 03:08:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jkb-0005dj-MA; Wed, 16 Sep 2026 03:08:14 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jkV-0008JK-1m; Wed, 16 Sep 2026 03:08:13 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S12; Wed, 16 Sep 2026 15:08:03 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 10/19] target/riscv: Add packed SIMD pure multiplication instructions Date: Wed, 16 Sep 2026 07:07:12 +0000 Message-Id: <20260916070721.3279229-11-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S12 X-Coremail-Antispam: 1UD129KBjvAXoW3tw15XFWDCF1UAr4fuw45Jrb_yoW8Zr4xJo Z7Cr4rZrWfGw45u343Kw1UX3Z2yrWIv3WDKFW5Zr4UWa4fWry2gryUJ348A3WxArWFyry7 XrZ3C3s8tasaka4Dn29KB7ZKAUJUUUUr529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUO97AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r126s0DM28Irc Ia0xkI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l 84ACjcxK6xIIjxv20xvE14v26ryj6F1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4UJV WxJr1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE 3s1ln4kS14v26r1Y6r17M2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c 02F40Ex7xfMcIj6xIIjxv20xvE14v26r126r1DMcIj6I8E87Iv67AKxVWxJVW8Jr1lOx8S 6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxw ACI402YVCY1x02628vn2kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxG rwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4 vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IY x2IY67AKxVW8JVW5JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw2 0EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Cr0_Gr1UMIIF0xvEx4A2jsIEc7Cj xVAFwI0_Gr1j6F4UJbIYCTnIWIevJa73UjIFyTuYvjfUoBTYUUUUU X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542608811158500 Content-Type: text/plain; charset="utf-8" Implement packed same-width multiply-high, cross-element multiply, and mixed-width multiply-high operations. Cover signed, unsigned, mixed-sign, rounded, and source-element selection variants. Add the associated decode entries, translators and helpers. Note that multiply-high operations retain the upper half of each product, while their rounding variants round the product before extracting the result. Cross-element multiply operations select source subelements and preserve their full products in wider destination elements. These operations do not affect vxsat. Signed-off-by: Molly Chen --- target/riscv/helper.h | 61 +++++++ target/riscv/insn32.decode | 91 ++++++++++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 61 +++++++ target/riscv/tcg/psimd_helper.c | 181 ++++++++++++++++++++ 4 files changed, 394 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 55d95c6eb6d..c6e69163262 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1560,3 +1560,64 @@ DEF_HELPER_3(pnclipup_w, i64, env, i64, i64) /* Packed SIMD - Count Leading Operations */ DEF_HELPER_2(cls, tl, env, tl) DEF_HELPER_2(clsw, i64, env, i64) + +/* Packed SIMD - Pure Multiplication Operations */ +DEF_HELPER_3(pmulh_h, tl, env, tl, tl) +DEF_HELPER_3(pmulhsu_h, tl, env, tl, tl) +DEF_HELPER_3(pmulhu_h, tl, env, tl, tl) +DEF_HELPER_3(pmulhr_h, tl, env, tl, tl) +DEF_HELPER_3(pmulhrsu_h, tl, env, tl, tl) +DEF_HELPER_3(pmulhru_h, tl, env, tl, tl) +DEF_HELPER_3(pmulh_w, i64, env, i64, i64) +DEF_HELPER_3(pmulhr_w, i64, env, i64, i64) +DEF_HELPER_3(pmulhsu_w, i64, env, i64, i64) +DEF_HELPER_3(pmulhrsu_w, i64, env, i64, i64) +DEF_HELPER_3(pmulhu_w, i64, env, i64, i64) +DEF_HELPER_3(pmulhru_w, i64, env, i64, i64) +DEF_HELPER_3(mulhr, i32, env, i32, i32) +DEF_HELPER_3(mulhrsu, i32, env, i32, i32) +DEF_HELPER_3(mulhru, i32, env, i32, i32) +DEF_HELPER_3(pmulh_h_b0, tl, env, tl, tl) +DEF_HELPER_3(pmulh_h_b1, tl, env, tl, tl) +DEF_HELPER_3(pmulhsu_h_b0, tl, env, tl, tl) +DEF_HELPER_3(pmulhsu_h_b1, tl, env, tl, tl) +DEF_HELPER_3(mulh_h0, i32, env, i32, i32) +DEF_HELPER_3(mulh_h1, i32, env, i32, i32) +DEF_HELPER_3(mulhsu_h0, i32, env, i32, i32) +DEF_HELPER_3(mulhsu_h1, i32, env, i32, i32) +DEF_HELPER_3(pmulh_w_h0, i64, env, i64, i64) +DEF_HELPER_3(pmulh_w_h1, i64, env, i64, i64) +DEF_HELPER_3(pmulhsu_w_h0, i64, env, i64, i64) +DEF_HELPER_3(pmulhsu_w_h1, i64, env, i64, i64) +DEF_HELPER_3(pmul_h_b00, tl, env, tl, tl) +DEF_HELPER_3(pmul_h_b01, tl, env, tl, tl) +DEF_HELPER_3(pmul_h_b11, tl, env, tl, tl) +DEF_HELPER_3(pmulsu_h_b00, tl, env, tl, tl) +DEF_HELPER_3(pmulsu_h_b11, tl, env, tl, tl) +DEF_HELPER_3(pmulu_h_b00, tl, env, tl, tl) +DEF_HELPER_3(pmulu_h_b01, tl, env, tl, tl) +DEF_HELPER_3(pmulu_h_b11, tl, env, tl, tl) +DEF_HELPER_3(pmul_w_h00, i64, env, i64, i64) +DEF_HELPER_3(pmul_w_h01, i64, env, i64, i64) +DEF_HELPER_3(pmul_w_h11, i64, env, i64, i64) +DEF_HELPER_3(pmulsu_w_h00, i64, env, i64, i64) +DEF_HELPER_3(pmulsu_w_h11, i64, env, i64, i64) +DEF_HELPER_3(pmulu_w_h00, i64, env, i64, i64) +DEF_HELPER_3(pmulu_w_h01, i64, env, i64, i64) +DEF_HELPER_3(pmulu_w_h11, i64, env, i64, i64) +DEF_HELPER_3(mul_h00, i32, env, i32, i32) +DEF_HELPER_3(mul_h01, i32, env, i32, i32) +DEF_HELPER_3(mul_h11, i32, env, i32, i32) +DEF_HELPER_3(mulsu_h00, i32, env, i32, i32) +DEF_HELPER_3(mulsu_h11, i32, env, i32, i32) +DEF_HELPER_3(mulu_h00, i32, env, i32, i32) +DEF_HELPER_3(mulu_h01, i32, env, i32, i32) +DEF_HELPER_3(mulu_h11, i32, env, i32, i32) +DEF_HELPER_3(mul_w00, i64, env, i64, i64) +DEF_HELPER_3(mul_w01, i64, env, i64, i64) +DEF_HELPER_3(mul_w11, i64, env, i64, i64) +DEF_HELPER_3(mulsu_w00, i64, env, i64, i64) +DEF_HELPER_3(mulsu_w11, i64, env, i64, i64) +DEF_HELPER_3(mulu_w00, i64, env, i64, i64) +DEF_HELPER_3(mulu_w01, i64, env, i64, i64) +DEF_HELPER_3(mulu_w11, i64, env, i64, i64) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 38210bb4934..94736a24038 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -1340,3 +1340,94 @@ pnclipup_w 1000011 ..... ..... 010 ..... 0111011 @r # Packed SIMD - Count Leading Operations cls 01100 0000011 ..... 001 ..... 0010011 @r2 clsw 01100 0000011 ..... 001 ..... 0011011 @r2 + +# Packed SIMD - Pure Multiplication Operations +pmulh_h 10000 00 ..... ..... 111 ..... 0111011 @r +pmulhsu_h 11000 00 ..... ..... 111 ..... 0111011 @r +pmulhu_h 10010 00 ..... ..... 111 ..... 0111011 @r +pmulhr_h 10000 10 ..... ..... 111 ..... 0111011 @r +pmulhrsu_h 11000 10 ..... ..... 111 ..... 0111011 @r +pmulhru_h 10010 10 ..... ..... 111 ..... 0111011 @r +pmulh_w 10000 01 ..... ..... 111 ..... 0111011 @r +{ + mulhr 10000 11 ..... ..... 111 ..... 0111011 @r + pmulhr_w 10000 11 ..... ..... 111 ..... 0111011 @r +} +pmulhsu_w 11000 01 ..... ..... 111 ..... 0111011 @r +{ + mulhrsu 11000 11 ..... ..... 111 ..... 0111011 @r + pmulhrsu_w 11000 11 ..... ..... 111 ..... 0111011 @r +} +pmulhu_w 10010 01 ..... ..... 111 ..... 0111011 @r +{ + mulhru 10010 11 ..... ..... 111 ..... 0111011 @r + pmulhru_w 10010 11 ..... ..... 111 ..... 0111011 @r +} +pmulh_h_b0 10100 00 ..... ..... 111 ..... 0111011 @r +pmulh_h_b1 10110 00 ..... ..... 111 ..... 0111011 @r +pmulhsu_h_b0 10100 10 ..... ..... 111 ..... 0111011 @r +pmulhsu_h_b1 10110 10 ..... ..... 111 ..... 0111011 @r +{ + mulh_h0 10100 01 ..... ..... 111 ..... 0111011 @r + pmulh_w_h0 10100 01 ..... ..... 111 ..... 0111011 @r +} +{ + mulh_h1 10110 01 ..... ..... 111 ..... 0111011 @r + pmulh_w_h1 10110 01 ..... ..... 111 ..... 0111011 @r +} +{ + mulhsu_h0 10100 11 ..... ..... 111 ..... 0111011 @r + pmulhsu_w_h0 10100 11 ..... ..... 111 ..... 0111011 @r +} +{ + mulhsu_h1 10110 11 ..... ..... 111 ..... 0111011 @r + pmulhsu_w_h1 10110 11 ..... ..... 111 ..... 0111011 @r +} +pmul_h_b00 10000 00 ..... ..... 011 ..... 0111011 @r +pmul_h_b01 10010 00 ..... ..... 001 ..... 0111011 @r +pmul_h_b11 10010 00 ..... ..... 011 ..... 0111011 @r +pmulsu_h_b00 11100 00 ..... ..... 011 ..... 0111011 @r +pmulsu_h_b11 11110 00 ..... ..... 011 ..... 0111011 @r +pmulu_h_b00 10100 00 ..... ..... 011 ..... 0111011 @r +pmulu_h_b01 10110 00 ..... ..... 001 ..... 0111011 @r +pmulu_h_b11 10110 00 ..... ..... 011 ..... 0111011 @r +{ + mul_h00 10000 01 ..... ..... 011 ..... 0111011 @r + pmul_w_h00 10000 01 ..... ..... 011 ..... 0111011 @r +} +{ + mul_h01 10010 01 ..... ..... 001 ..... 0111011 @r + pmul_w_h01 10010 01 ..... ..... 001 ..... 0111011 @r +} +{ + mul_h11 10010 01 ..... ..... 011 ..... 0111011 @r + pmul_w_h11 10010 01 ..... ..... 011 ..... 0111011 @r +} +{ + mulsu_h00 11100 01 ..... ..... 011 ..... 0111011 @r + pmulsu_w_h00 11100 01 ..... ..... 011 ..... 0111011 @r +} +{ + mulsu_h11 11110 01 ..... ..... 011 ..... 0111011 @r + pmulsu_w_h11 11110 01 ..... ..... 011 ..... 0111011 @r +} +{ + mulu_h00 10100 01 ..... ..... 011 ..... 0111011 @r + pmulu_w_h00 10100 01 ..... ..... 011 ..... 0111011 @r +} +{ + mulu_h01 10110 01 ..... ..... 001 ..... 0111011 @r + pmulu_w_h01 10110 01 ..... ..... 001 ..... 0111011 @r +} +{ + mulu_h11 10110 01 ..... ..... 011 ..... 0111011 @r + pmulu_w_h11 10110 01 ..... ..... 011 ..... 0111011 @r +} +mul_w00 10000 11 ..... ..... 011 ..... 0111011 @r +mul_w01 10010 11 ..... ..... 001 ..... 0111011 @r +mul_w11 10010 11 ..... ..... 011 ..... 0111011 @r +mulsu_w00 11100 11 ..... ..... 011 ..... 0111011 @r +mulsu_w11 11110 11 ..... ..... 011 ..... 0111011 @r +mulu_w00 10100 11 ..... ..... 011 ..... 0111011 @r +mulu_w01 10110 11 ..... ..... 001 ..... 0111011 @r +mulu_w11 10110 11 ..... ..... 011 ..... 0111011 @r diff --git a/target/riscv/tcg/insn_trans/trans_rvp.c.inc b/target/riscv/tcg= /insn_trans/trans_rvp.c.inc index 2c9a34b9a7e..39bec55bd25 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -729,3 +729,64 @@ GEN_SIMD_TRANS_64_VXSAT(pnclipup_w) /* Packed SIMD - Count Leading Operations */ GEN_SIMD_TRANS_R1(cls) GEN_SIMD_TRANS_R1_64(clsw) + +/* Packed SIMD - Pure Multiplication Operations */ +GEN_SIMD_TRANS(pmulh_h) +GEN_SIMD_TRANS(pmulhsu_h) +GEN_SIMD_TRANS(pmulhu_h) +GEN_SIMD_TRANS(pmulhr_h) +GEN_SIMD_TRANS(pmulhrsu_h) +GEN_SIMD_TRANS(pmulhru_h) +GEN_SIMD_TRANS_64(pmulh_w) +GEN_SIMD_TRANS_64(pmulhr_w) +GEN_SIMD_TRANS_64(pmulhsu_w) +GEN_SIMD_TRANS_64(pmulhrsu_w) +GEN_SIMD_TRANS_64(pmulhu_w) +GEN_SIMD_TRANS_64(pmulhru_w) +GEN_SIMD_TRANS_32(mulhr) +GEN_SIMD_TRANS_32(mulhrsu) +GEN_SIMD_TRANS_32(mulhru) +GEN_SIMD_TRANS(pmulh_h_b0) +GEN_SIMD_TRANS(pmulh_h_b1) +GEN_SIMD_TRANS(pmulhsu_h_b0) +GEN_SIMD_TRANS(pmulhsu_h_b1) +GEN_SIMD_TRANS_32(mulh_h0) +GEN_SIMD_TRANS_32(mulh_h1) +GEN_SIMD_TRANS_32(mulhsu_h0) +GEN_SIMD_TRANS_32(mulhsu_h1) +GEN_SIMD_TRANS_64(pmulh_w_h0) +GEN_SIMD_TRANS_64(pmulh_w_h1) +GEN_SIMD_TRANS_64(pmulhsu_w_h0) +GEN_SIMD_TRANS_64(pmulhsu_w_h1) +GEN_SIMD_TRANS(pmul_h_b00) +GEN_SIMD_TRANS(pmul_h_b01) +GEN_SIMD_TRANS(pmul_h_b11) +GEN_SIMD_TRANS(pmulsu_h_b00) +GEN_SIMD_TRANS(pmulsu_h_b11) +GEN_SIMD_TRANS(pmulu_h_b00) +GEN_SIMD_TRANS(pmulu_h_b01) +GEN_SIMD_TRANS(pmulu_h_b11) +GEN_SIMD_TRANS_64(pmul_w_h00) +GEN_SIMD_TRANS_64(pmul_w_h01) +GEN_SIMD_TRANS_64(pmul_w_h11) +GEN_SIMD_TRANS_64(pmulsu_w_h00) +GEN_SIMD_TRANS_64(pmulsu_w_h11) +GEN_SIMD_TRANS_64(pmulu_w_h00) +GEN_SIMD_TRANS_64(pmulu_w_h01) +GEN_SIMD_TRANS_64(pmulu_w_h11) +GEN_SIMD_TRANS_32(mul_h00) +GEN_SIMD_TRANS_32(mul_h01) +GEN_SIMD_TRANS_32(mul_h11) +GEN_SIMD_TRANS_32(mulsu_h00) +GEN_SIMD_TRANS_32(mulsu_h11) +GEN_SIMD_TRANS_32(mulu_h00) +GEN_SIMD_TRANS_32(mulu_h01) +GEN_SIMD_TRANS_32(mulu_h11) +GEN_SIMD_TRANS_64(mul_w00) +GEN_SIMD_TRANS_64(mul_w01) +GEN_SIMD_TRANS_64(mul_w11) +GEN_SIMD_TRANS_64(mulsu_w00) +GEN_SIMD_TRANS_64(mulsu_w11) +GEN_SIMD_TRANS_64(mulu_w00) +GEN_SIMD_TRANS_64(mulu_w01) +GEN_SIMD_TRANS_64(mulu_w11) diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helpe= r.c index f883596fe49..f84b43bfaa7 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -2629,3 +2629,184 @@ GEN_PSIMD_CLS(cls, target_ulong, uint32_t, clrsb32) #endif =20 GEN_PSIMD_CLS(clsw, uint64_t, uint32_t, clrsb32) + +/* Pure multiplication operations */ + +GEN_PSIMD_MUL_HIGH(pmulh_h, target_ulong, int16_t, int16_t, int32_t, + uint16_t, EXTRACT16, INSERT16, ELEMS_H, 16, 0, + PSIMD_MUL_S32) +GEN_PSIMD_MUL_HIGH(pmulhsu_h, target_ulong, int16_t, uint16_t, int32_t, + uint16_t, EXTRACT16, INSERT16, ELEMS_H, 16, 0, + PSIMD_MUL_SU32) +GEN_PSIMD_MUL_HIGH(pmulhu_h, target_ulong, uint16_t, uint16_t, uint32_t, + uint16_t, EXTRACT16, INSERT16, ELEMS_H, 16, 0, + PSIMD_MUL_U32) +GEN_PSIMD_MUL_HIGH(pmulhr_h, target_ulong, int16_t, int16_t, int32_t, + uint16_t, EXTRACT16, INSERT16, ELEMS_H, 16, 1 << 15, + PSIMD_MUL_S32) +GEN_PSIMD_MUL_HIGH(pmulhrsu_h, target_ulong, int16_t, uint16_t, int32_t, + uint16_t, EXTRACT16, INSERT16, ELEMS_H, 16, 1 << 15, + PSIMD_MUL_SU32) +GEN_PSIMD_MUL_HIGH(pmulhru_h, target_ulong, uint16_t, uint16_t, uint32_t, + uint16_t, EXTRACT16, INSERT16, ELEMS_H, 16, 1 << 15, + PSIMD_MUL_U32) + +GEN_PSIMD_MUL_HIGH(pmulh_w, uint64_t, int32_t, int32_t, int64_t, + uint32_t, EXTRACT32, INSERT32, ELEMS_W, 32, 0, + PSIMD_MUL_S64) +GEN_PSIMD_MUL_HIGH(pmulhr_w, uint64_t, int32_t, int32_t, int64_t, + uint32_t, EXTRACT32, INSERT32, ELEMS_W, 32, 1LL << 31, + PSIMD_MUL_S64) +GEN_PSIMD_MUL_HIGH(pmulhsu_w, uint64_t, int32_t, uint32_t, int64_t, + uint32_t, EXTRACT32, INSERT32, ELEMS_W, 32, 0, + PSIMD_MUL_SU64) +GEN_PSIMD_MUL_HIGH(pmulhrsu_w, uint64_t, int32_t, uint32_t, int64_t, + uint32_t, EXTRACT32, INSERT32, ELEMS_W, 32, 1LL << 31, + PSIMD_MUL_SU64) +GEN_PSIMD_MUL_HIGH(pmulhu_w, uint64_t, uint32_t, uint32_t, uint64_t, + uint32_t, EXTRACT32, INSERT32, ELEMS_W, 32, 0, + PSIMD_MUL_U64) +GEN_PSIMD_MUL_HIGH(pmulhru_w, uint64_t, uint32_t, uint32_t, uint64_t, + uint32_t, EXTRACT32, INSERT32, ELEMS_W, 32, 1LL << 31, + PSIMD_MUL_U64) + +GEN_PSIMD_MUL_HIGH(mulhr, uint32_t, int32_t, int32_t, int64_t, + uint32_t, EXTRACT32, INSERT32, ELEMS_W, 32, 1LL << 31, + PSIMD_MUL_S64) +GEN_PSIMD_MUL_HIGH(mulhrsu, uint32_t, int32_t, uint32_t, int64_t, + uint32_t, EXTRACT32, INSERT32, ELEMS_W, 32, 1LL << 31, + PSIMD_MUL_SU64) +GEN_PSIMD_MUL_HIGH(mulhru, uint32_t, uint32_t, uint32_t, uint64_t, + uint32_t, EXTRACT32, INSERT32, ELEMS_W, 32, 1LL << 31, + PSIMD_MUL_U64) + +GEN_PSIMD_MUL_HIGH_SEL(pmulh_h_b0, target_ulong, int16_t, int8_t, + int32_t, uint16_t, EXTRACT16, EXTRACT8, INSERT16, + ELEMS_H, 2, 0, 8, PSIMD_MUL_S32) +GEN_PSIMD_MUL_HIGH_SEL(pmulh_h_b1, target_ulong, int16_t, int8_t, + int32_t, uint16_t, EXTRACT16, EXTRACT8, INSERT16, + ELEMS_H, 2, 1, 8, PSIMD_MUL_S32) +GEN_PSIMD_MUL_HIGH_SEL(pmulhsu_h_b0, target_ulong, int16_t, uint8_t, + int32_t, uint16_t, EXTRACT16, EXTRACT8, INSERT16, + ELEMS_H, 2, 0, 8, PSIMD_MUL_SU32) +GEN_PSIMD_MUL_HIGH_SEL(pmulhsu_h_b1, target_ulong, int16_t, uint8_t, + int32_t, uint16_t, EXTRACT16, EXTRACT8, INSERT16, + ELEMS_H, 2, 1, 8, PSIMD_MUL_SU32) + +GEN_PSIMD_MUL_HIGH_SEL(mulh_h0, uint32_t, int32_t, int16_t, + int64_t, uint32_t, EXTRACT32, EXTRACT16, INSERT32, + ELEMS_W, 0, 0, 16, PSIMD_MUL_S64) +GEN_PSIMD_MUL_HIGH_SEL(mulh_h1, uint32_t, int32_t, int16_t, + int64_t, uint32_t, EXTRACT32, EXTRACT16, INSERT32, + ELEMS_W, 0, 1, 16, PSIMD_MUL_S64) +GEN_PSIMD_MUL_HIGH_SEL(mulhsu_h0, uint32_t, int32_t, uint16_t, + int64_t, uint32_t, EXTRACT32, EXTRACT16, INSERT32, + ELEMS_W, 0, 0, 16, PSIMD_MUL_SU64) +GEN_PSIMD_MUL_HIGH_SEL(mulhsu_h1, uint32_t, int32_t, uint16_t, + int64_t, uint32_t, EXTRACT32, EXTRACT16, INSERT32, + ELEMS_W, 0, 1, 16, PSIMD_MUL_SU64) + +GEN_PSIMD_MUL_HIGH_SEL(pmulh_w_h0, uint64_t, int32_t, int16_t, + int64_t, uint32_t, EXTRACT32, EXTRACT16, INSERT32, + ELEMS_W, 2, 0, 16, PSIMD_MUL_S64) +GEN_PSIMD_MUL_HIGH_SEL(pmulh_w_h1, uint64_t, int32_t, int16_t, + int64_t, uint32_t, EXTRACT32, EXTRACT16, INSERT32, + ELEMS_W, 2, 1, 16, PSIMD_MUL_S64) +GEN_PSIMD_MUL_HIGH_SEL(pmulhsu_w_h0, uint64_t, int32_t, uint16_t, + int64_t, uint32_t, EXTRACT32, EXTRACT16, INSERT32, + ELEMS_W, 2, 0, 16, PSIMD_MUL_SU64) +GEN_PSIMD_MUL_HIGH_SEL(pmulhsu_w_h1, uint64_t, int32_t, uint16_t, + int64_t, uint32_t, EXTRACT32, EXTRACT16, INSERT32, + ELEMS_W, 2, 1, 16, PSIMD_MUL_SU64) + +GEN_PSIMD_MUL_ELEM_INDEXED(pmul_h_b00, target_ulong, int8_t, int8_t, + int16_t, uint16_t, EXTRACT8, INSERT16, ELEMS_H, + 2, 0, 0, PSIMD_MUL_S32) +GEN_PSIMD_MUL_ELEM_INDEXED(pmul_h_b01, target_ulong, int8_t, int8_t, + int16_t, uint16_t, EXTRACT8, INSERT16, ELEMS_H, + 2, 0, 1, PSIMD_MUL_S32) +GEN_PSIMD_MUL_ELEM_INDEXED(pmul_h_b11, target_ulong, int8_t, int8_t, + int16_t, uint16_t, EXTRACT8, INSERT16, ELEMS_H, + 2, 1, 1, PSIMD_MUL_S32) + +GEN_PSIMD_MUL_ELEM_INDEXED(pmulsu_h_b00, target_ulong, int8_t, uint8_t, + int16_t, uint16_t, EXTRACT8, INSERT16, ELEMS_H, + 2, 0, 0, PSIMD_MUL_SU16) +GEN_PSIMD_MUL_ELEM_INDEXED(pmulsu_h_b11, target_ulong, int8_t, uint8_t, + int16_t, uint16_t, EXTRACT8, INSERT16, ELEMS_H, + 2, 1, 1, PSIMD_MUL_SU16) + +GEN_PSIMD_MUL_ELEM_INDEXED(pmulu_h_b00, target_ulong, uint8_t, uint8_t, + uint16_t, uint16_t, EXTRACT8, INSERT16, ELEMS_H, + 2, 0, 0, PSIMD_MUL_U32) +GEN_PSIMD_MUL_ELEM_INDEXED(pmulu_h_b01, target_ulong, uint8_t, uint8_t, + uint16_t, uint16_t, EXTRACT8, INSERT16, ELEMS_H, + 2, 0, 1, PSIMD_MUL_U32) +GEN_PSIMD_MUL_ELEM_INDEXED(pmulu_h_b11, target_ulong, uint8_t, uint8_t, + uint16_t, uint16_t, EXTRACT8, INSERT16, ELEMS_H, + 2, 1, 1, PSIMD_MUL_U32) + +GEN_PSIMD_MUL_ELEM_INDEXED(pmul_w_h00, uint64_t, int16_t, int16_t, + int32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_W, + 2, 0, 0, PSIMD_MUL_S32) +GEN_PSIMD_MUL_ELEM_INDEXED(pmul_w_h01, uint64_t, int16_t, int16_t, + int32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_W, + 2, 0, 1, PSIMD_MUL_S32) +GEN_PSIMD_MUL_ELEM_INDEXED(pmul_w_h11, uint64_t, int16_t, int16_t, + int32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_W, + 2, 1, 1, PSIMD_MUL_S32) + +GEN_PSIMD_MUL_ELEM_INDEXED(pmulsu_w_h00, uint64_t, int16_t, uint16_t, + int32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_W, + 2, 0, 0, PSIMD_MUL_SU32) +GEN_PSIMD_MUL_ELEM_INDEXED(pmulsu_w_h11, uint64_t, int16_t, uint16_t, + int32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_W, + 2, 1, 1, PSIMD_MUL_SU32) + +GEN_PSIMD_MUL_ELEM_INDEXED(pmulu_w_h00, uint64_t, uint16_t, uint16_t, + uint32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_= W, + 2, 0, 0, PSIMD_MUL_U32) +GEN_PSIMD_MUL_ELEM_INDEXED(pmulu_w_h01, uint64_t, uint16_t, uint16_t, + uint32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_= W, + 2, 0, 1, PSIMD_MUL_U32) +GEN_PSIMD_MUL_ELEM_INDEXED(pmulu_w_h11, uint64_t, uint16_t, uint16_t, + uint32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_= W, + 2, 1, 1, PSIMD_MUL_U32) + +GEN_PSIMD_MUL_ELEM_SCALAR(mul_h00, uint32_t, int16_t, int16_t, + int32_t, EXTRACT16, 0, 0, PSIMD_MUL_S32) +GEN_PSIMD_MUL_ELEM_SCALAR(mul_h01, uint32_t, int16_t, int16_t, + int32_t, EXTRACT16, 0, 1, PSIMD_MUL_S32) +GEN_PSIMD_MUL_ELEM_SCALAR(mul_h11, uint32_t, int16_t, int16_t, + int32_t, EXTRACT16, 1, 1, PSIMD_MUL_S32) + +GEN_PSIMD_MUL_ELEM_SCALAR(mulsu_h00, uint32_t, int16_t, uint16_t, + int32_t, EXTRACT16, 0, 0, PSIMD_MUL_SU32) +GEN_PSIMD_MUL_ELEM_SCALAR(mulsu_h11, uint32_t, int16_t, uint16_t, + int32_t, EXTRACT16, 1, 1, PSIMD_MUL_SU32) + +GEN_PSIMD_MUL_ELEM_SCALAR(mulu_h00, uint32_t, uint16_t, uint16_t, + uint32_t, EXTRACT16, 0, 0, PSIMD_MUL_U32) +GEN_PSIMD_MUL_ELEM_SCALAR(mulu_h01, uint32_t, uint16_t, uint16_t, + uint32_t, EXTRACT16, 0, 1, PSIMD_MUL_U32) +GEN_PSIMD_MUL_ELEM_SCALAR(mulu_h11, uint32_t, uint16_t, uint16_t, + uint32_t, EXTRACT16, 1, 1, PSIMD_MUL_U32) + +GEN_PSIMD_MUL_ELEM_SCALAR(mul_w00, uint64_t, int32_t, int32_t, + int64_t, EXTRACT32, 0, 0, PSIMD_MUL_S64) +GEN_PSIMD_MUL_ELEM_SCALAR(mul_w01, uint64_t, int32_t, int32_t, + int64_t, EXTRACT32, 0, 1, PSIMD_MUL_S64) +GEN_PSIMD_MUL_ELEM_SCALAR(mul_w11, uint64_t, int32_t, int32_t, + int64_t, EXTRACT32, 1, 1, PSIMD_MUL_S64) + +GEN_PSIMD_MUL_ELEM_SCALAR(mulsu_w00, uint64_t, int32_t, uint32_t, + int64_t, EXTRACT32, 0, 0, PSIMD_MUL_SU64) +GEN_PSIMD_MUL_ELEM_SCALAR(mulsu_w11, uint64_t, int32_t, uint32_t, + int64_t, EXTRACT32, 1, 1, PSIMD_MUL_SU64) + +GEN_PSIMD_MUL_ELEM_SCALAR(mulu_w00, uint64_t, uint32_t, uint32_t, + uint64_t, EXTRACT32, 0, 0, PSIMD_MUL_U64) +GEN_PSIMD_MUL_ELEM_SCALAR(mulu_w01, uint64_t, uint32_t, uint32_t, + uint64_t, EXTRACT32, 0, 1, PSIMD_MUL_U64) +GEN_PSIMD_MUL_ELEM_SCALAR(mulu_w11, uint64_t, uint32_t, uint32_t, + uint64_t, EXTRACT32, 1, 1, PSIMD_MUL_U64) --=20 2.34.1 From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789542932276413.15348387497556; Wed, 16 Sep 2026 00:15:32 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jrI-0005f6-At; Wed, 16 Sep 2026 03:15:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jqw-0005bH-Ll; Wed, 16 Sep 2026 03:14:48 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jqs-0000zT-0L; Wed, 16 Sep 2026 03:14:46 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S13; Wed, 16 Sep 2026 15:08:03 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 11/19] target/riscv: Add packed SIMD multiply-accumulate instructions Date: Wed, 16 Sep 2026 07:07:13 +0000 Message-Id: <20260916070721.3279229-12-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S13 X-Coremail-Antispam: 1UD129KBjvAXoWfAw13WF1rZFyrKF17uw4rZrb_yoW8urWrCo Z7Cr1rArW8C3y8urya9w1UXrs2qFW09a1DJay5Zr47XF93Wry2qrW5J348A3Z7CrWayry7 XrZ3C34rtF9ak34Dn29KB7ZKAUJUUUUr529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUO97AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r126s0DM28Irc Ia0xkI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l 84ACjcxK6xIIjxv20xvE14v26ryj6F1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4UJV WxJr1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE 3s1ln4kS14v26r1Y6r17M2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c 02F40Ex7xfMcIj6xIIjxv20xvE14v26r126r1DMcIj6I8E87Iv67AKxVWxJVW8Jr1lOx8S 6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxw ACI402YVCY1x02628vn2kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxG rwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4 vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IY x2IY67AKxVW8JVW5JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw2 0EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Cr0_Gr1UMIIF0xvEx4A2jsIEc7Cj xVAFwI0_Gr1j6F4UJbIYCTnIWIevJa73UjIFyTuYvjfUoBTYUUUUU X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542934126158500 Content-Type: text/plain; charset="utf-8" Implement packed multiply-high accumulate, cross-element multiply-accumulate, and mixed-width multiply-high accumulate operations. Cover signed, unsigned, mixed-sign, rounded, and source-element selection variants.Add the associated decode entries, translators and helpers. Note that same-width multiply-high accumulate operations add the upper half of each product to the corresponding destination element, while their rounding variants round the product before extracting it. Mixed-width variants discard the low bits corresponding to the narrower source element before accumulation. Cross-element variants select source subelements and accumulate their full products into wider destination elements. Accumulation wraps to the destination element width, and these operations do not affect vxsat. Signed-off-by: Molly Chen --- target/riscv/helper.h | 56 ++++++ target/riscv/insn32.decode | 92 +++++++++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 56 ++++++ target/riscv/tcg/psimd_helper.c | 195 ++++++++++++++++++++ 4 files changed, 399 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index c6e69163262..e90e01373ed 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1621,3 +1621,59 @@ DEF_HELPER_3(mulsu_w11, i64, env, i64, i64) DEF_HELPER_3(mulu_w00, i64, env, i64, i64) DEF_HELPER_3(mulu_w01, i64, env, i64, i64) DEF_HELPER_3(mulu_w11, i64, env, i64, i64) + +/* Packed SIMD - Multiply-Accumulate Operations */ +DEF_HELPER_4(pmhacc_h, tl, env, tl, tl, tl) +DEF_HELPER_4(pmhaccsu_h, tl, env, tl, tl, tl) +DEF_HELPER_4(pmhaccu_h, tl, env, tl, tl, tl) +DEF_HELPER_4(pmhracc_h, tl, env, tl, tl, tl) +DEF_HELPER_4(pmhraccsu_h, tl, env, tl, tl, tl) +DEF_HELPER_4(pmhraccu_h, tl, env, tl, tl, tl) +DEF_HELPER_4(pmhacc_w, i64, env, i64, i64, i64) +DEF_HELPER_4(pmhracc_w, i64, env, i64, i64, i64) +DEF_HELPER_4(pmhaccsu_w, i64, env, i64, i64, i64) +DEF_HELPER_4(pmhraccsu_w, i64, env, i64, i64, i64) +DEF_HELPER_4(pmhaccu_w, i64, env, i64, i64, i64) +DEF_HELPER_4(pmhraccu_w, i64, env, i64, i64, i64) +DEF_HELPER_4(mhacc, i32, env, i32, i32, i32) +DEF_HELPER_4(mhracc, i32, env, i32, i32, i32) +DEF_HELPER_4(mhaccsu, i32, env, i32, i32, i32) +DEF_HELPER_4(mhraccsu, i32, env, i32, i32, i32) +DEF_HELPER_4(mhaccu, i32, env, i32, i32, i32) +DEF_HELPER_4(mhraccu, i32, env, i32, i32, i32) +DEF_HELPER_4(pmhacc_h_b0, tl, env, tl, tl, tl) +DEF_HELPER_4(pmhacc_h_b1, tl, env, tl, tl, tl) +DEF_HELPER_4(pmhaccsu_h_b0, tl, env, tl, tl, tl) +DEF_HELPER_4(pmhaccsu_h_b1, tl, env, tl, tl, tl) +DEF_HELPER_4(mhacc_h0, i32, env, i32, i32, i32) +DEF_HELPER_4(mhacc_h1, i32, env, i32, i32, i32) +DEF_HELPER_4(mhaccsu_h0, i32, env, i32, i32, i32) +DEF_HELPER_4(mhaccsu_h1, i32, env, i32, i32, i32) +DEF_HELPER_4(pmhacc_w_h0, i64, env, i64, i64, i64) +DEF_HELPER_4(pmhacc_w_h1, i64, env, i64, i64, i64) +DEF_HELPER_4(pmhaccsu_w_h0, i64, env, i64, i64, i64) +DEF_HELPER_4(pmhaccsu_w_h1, i64, env, i64, i64, i64) +DEF_HELPER_4(pmacc_w_h00, i64, env, i64, i64, i64) +DEF_HELPER_4(pmacc_w_h01, i64, env, i64, i64, i64) +DEF_HELPER_4(pmacc_w_h11, i64, env, i64, i64, i64) +DEF_HELPER_4(pmaccsu_w_h00, i64, env, i64, i64, i64) +DEF_HELPER_4(pmaccsu_w_h11, i64, env, i64, i64, i64) +DEF_HELPER_4(pmaccu_w_h00, i64, env, i64, i64, i64) +DEF_HELPER_4(pmaccu_w_h01, i64, env, i64, i64, i64) +DEF_HELPER_4(pmaccu_w_h11, i64, env, i64, i64, i64) +DEF_HELPER_4(macc_h00, i32, env, i32, i32, i32) +DEF_HELPER_4(macc_h01, i32, env, i32, i32, i32) +DEF_HELPER_4(macc_h11, i32, env, i32, i32, i32) +DEF_HELPER_4(maccsu_h00, i32, env, i32, i32, i32) +DEF_HELPER_4(maccsu_h11, i32, env, i32, i32, i32) +DEF_HELPER_4(maccu_h00, i32, env, i32, i32, i32) +DEF_HELPER_4(maccu_h01, i32, env, i32, i32, i32) +DEF_HELPER_4(maccu_h11, i32, env, i32, i32, i32) +DEF_HELPER_4(macc_w00, i64, env, i64, i64, i64) +DEF_HELPER_4(macc_w01, i64, env, i64, i64, i64) +DEF_HELPER_4(macc_w11, i64, env, i64, i64, i64) +DEF_HELPER_4(maccsu_w00, i64, env, i64, i64, i64) +DEF_HELPER_4(maccsu_w11, i64, env, i64, i64, i64) +DEF_HELPER_4(maccu_w00, i64, env, i64, i64, i64) +DEF_HELPER_4(maccu_w01, i64, env, i64, i64, i64) +DEF_HELPER_4(maccu_w11, i64, env, i64, i64, i64) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 94736a24038..2bf26ec1563 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -1431,3 +1431,95 @@ mulsu_w11 11110 11 ..... ..... 011 ..... 01110= 11 @r mulu_w00 10100 11 ..... ..... 011 ..... 0111011 @r mulu_w01 10110 11 ..... ..... 001 ..... 0111011 @r mulu_w11 10110 11 ..... ..... 011 ..... 0111011 @r + +# Packed SIMD - Multiply-Accumulate Operations +pmhacc_h 10001 00 ..... ..... 111 ..... 0111011 @r +pmhaccsu_h 11001 00 ..... ..... 111 ..... 0111011 @r +pmhaccu_h 10011 00 ..... ..... 111 ..... 0111011 @r +pmhracc_h 10001 10 ..... ..... 111 ..... 0111011 @r +pmhraccsu_h 11001 10 ..... ..... 111 ..... 0111011 @r +pmhraccu_h 10011 10 ..... ..... 111 ..... 0111011 @r +{ + mhacc 10001 01 ..... ..... 111 ..... 0111011 @r + pmhacc_w 10001 01 ..... ..... 111 ..... 0111011 @r +} +{ + mhracc 10001 11 ..... ..... 111 ..... 0111011 @r + pmhracc_w 10001 11 ..... ..... 111 ..... 0111011 @r +} +{ + mhaccsu 11001 01 ..... ..... 111 ..... 0111011 @r + pmhaccsu_w 11001 01 ..... ..... 111 ..... 0111011 @r +} +{ + mhraccsu 11001 11 ..... ..... 111 ..... 0111011 @r + pmhraccsu_w 11001 11 ..... ..... 111 ..... 0111011 @r +} +{ + mhaccu 10011 01 ..... ..... 111 ..... 0111011 @r + pmhaccu_w 10011 01 ..... ..... 111 ..... 0111011 @r +} +{ + mhraccu 10011 11 ..... ..... 111 ..... 0111011 @r + pmhraccu_w 10011 11 ..... ..... 111 ..... 0111011 @r +} +pmhacc_h_b0 10101 00 ..... ..... 111 ..... 0111011 @r +pmhacc_h_b1 10111 00 ..... ..... 111 ..... 0111011 @r +pmhaccsu_h_b0 10101 10 ..... ..... 111 ..... 0111011 @r +pmhaccsu_h_b1 10111 10 ..... ..... 111 ..... 0111011 @r +{ + mhacc_h0 10101 01 ..... ..... 111 ..... 0111011 @r + pmhacc_w_h0 10101 01 ..... ..... 111 ..... 0111011 @r +} +{ + mhacc_h1 10111 01 ..... ..... 111 ..... 0111011 @r + pmhacc_w_h1 10111 01 ..... ..... 111 ..... 0111011 @r +} +{ + mhaccsu_h0 10101 11 ..... ..... 111 ..... 0111011 @r + pmhaccsu_w_h0 10101 11 ..... ..... 111 ..... 0111011 @r +} +{ + mhaccsu_h1 10111 11 ..... ..... 111 ..... 0111011 @r + pmhaccsu_w_h1 10111 11 ..... ..... 111 ..... 0111011 @r +} +{ + macc_h00 10001 01 ..... ..... 011 ..... 0111011 @r + pmacc_w_h00 10001 01 ..... ..... 011 ..... 0111011 @r +} +{ + macc_h01 10011 01 ..... ..... 001 ..... 0111011 @r + pmacc_w_h01 10011 01 ..... ..... 001 ..... 0111011 @r +} +{ + macc_h11 10011 01 ..... ..... 011 ..... 0111011 @r + pmacc_w_h11 10011 01 ..... ..... 011 ..... 0111011 @r +} +{ + maccsu_h00 11101 01 ..... ..... 011 ..... 0111011 @r + pmaccsu_w_h00 11101 01 ..... ..... 011 ..... 0111011 @r +} +{ + maccsu_h11 11111 01 ..... ..... 011 ..... 0111011 @r + pmaccsu_w_h11 11111 01 ..... ..... 011 ..... 0111011 @r +} +{ + maccu_h00 10101 01 ..... ..... 011 ..... 0111011 @r + pmaccu_w_h00 10101 01 ..... ..... 011 ..... 0111011 @r +} +{ + maccu_h01 10111 01 ..... ..... 001 ..... 0111011 @r + pmaccu_w_h01 10111 01 ..... ..... 001 ..... 0111011 @r +} +{ + maccu_h11 10111 01 ..... ..... 011 ..... 0111011 @r + pmaccu_w_h11 10111 01 ..... ..... 011 ..... 0111011 @r +} +macc_w00 10001 11 ..... ..... 011 ..... 0111011 @r +macc_w01 10011 11 ..... ..... 001 ..... 0111011 @r +macc_w11 10011 11 ..... ..... 011 ..... 0111011 @r +maccsu_w00 11101 11 ..... ..... 011 ..... 0111011 @r +maccsu_w11 11111 11 ..... ..... 011 ..... 0111011 @r +maccu_w00 10101 11 ..... ..... 011 ..... 0111011 @r +maccu_w01 10111 11 ..... ..... 001 ..... 0111011 @r +maccu_w11 10111 11 ..... ..... 011 ..... 0111011 @r diff --git a/target/riscv/tcg/insn_trans/trans_rvp.c.inc b/target/riscv/tcg= /insn_trans/trans_rvp.c.inc index 39bec55bd25..5aaa3c6ffa5 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -790,3 +790,59 @@ GEN_SIMD_TRANS_64(mulsu_w11) GEN_SIMD_TRANS_64(mulu_w00) GEN_SIMD_TRANS_64(mulu_w01) GEN_SIMD_TRANS_64(mulu_w11) + +/* Packed SIMD - Multiply-Accumulate Operations */ +GEN_SIMD_TRANS_ACC(pmhacc_h) +GEN_SIMD_TRANS_ACC(pmhaccsu_h) +GEN_SIMD_TRANS_ACC(pmhaccu_h) +GEN_SIMD_TRANS_ACC(pmhracc_h) +GEN_SIMD_TRANS_ACC(pmhraccsu_h) +GEN_SIMD_TRANS_ACC(pmhraccu_h) +GEN_SIMD_TRANS_ACC_64(pmhacc_w) +GEN_SIMD_TRANS_ACC_64(pmhracc_w) +GEN_SIMD_TRANS_ACC_64(pmhaccsu_w) +GEN_SIMD_TRANS_ACC_64(pmhraccsu_w) +GEN_SIMD_TRANS_ACC_64(pmhaccu_w) +GEN_SIMD_TRANS_ACC_64(pmhraccu_w) +GEN_SIMD_TRANS_ACC_32(mhacc) +GEN_SIMD_TRANS_ACC_32(mhracc) +GEN_SIMD_TRANS_ACC_32(mhaccsu) +GEN_SIMD_TRANS_ACC_32(mhraccsu) +GEN_SIMD_TRANS_ACC_32(mhaccu) +GEN_SIMD_TRANS_ACC_32(mhraccu) +GEN_SIMD_TRANS_ACC(pmhacc_h_b0) +GEN_SIMD_TRANS_ACC(pmhacc_h_b1) +GEN_SIMD_TRANS_ACC(pmhaccsu_h_b0) +GEN_SIMD_TRANS_ACC(pmhaccsu_h_b1) +GEN_SIMD_TRANS_ACC_32(mhacc_h0) +GEN_SIMD_TRANS_ACC_32(mhacc_h1) +GEN_SIMD_TRANS_ACC_32(mhaccsu_h0) +GEN_SIMD_TRANS_ACC_32(mhaccsu_h1) +GEN_SIMD_TRANS_ACC_64(pmhacc_w_h0) +GEN_SIMD_TRANS_ACC_64(pmhacc_w_h1) +GEN_SIMD_TRANS_ACC_64(pmhaccsu_w_h0) +GEN_SIMD_TRANS_ACC_64(pmhaccsu_w_h1) +GEN_SIMD_TRANS_ACC_64(pmacc_w_h00) +GEN_SIMD_TRANS_ACC_64(pmacc_w_h01) +GEN_SIMD_TRANS_ACC_64(pmacc_w_h11) +GEN_SIMD_TRANS_ACC_64(pmaccsu_w_h00) +GEN_SIMD_TRANS_ACC_64(pmaccsu_w_h11) +GEN_SIMD_TRANS_ACC_64(pmaccu_w_h00) +GEN_SIMD_TRANS_ACC_64(pmaccu_w_h01) +GEN_SIMD_TRANS_ACC_64(pmaccu_w_h11) +GEN_SIMD_TRANS_ACC_32(macc_h00) +GEN_SIMD_TRANS_ACC_32(macc_h01) +GEN_SIMD_TRANS_ACC_32(macc_h11) +GEN_SIMD_TRANS_ACC_32(maccsu_h00) +GEN_SIMD_TRANS_ACC_32(maccsu_h11) +GEN_SIMD_TRANS_ACC_32(maccu_h00) +GEN_SIMD_TRANS_ACC_32(maccu_h01) +GEN_SIMD_TRANS_ACC_32(maccu_h11) +GEN_SIMD_TRANS_ACC_64(macc_w00) +GEN_SIMD_TRANS_ACC_64(macc_w01) +GEN_SIMD_TRANS_ACC_64(macc_w11) +GEN_SIMD_TRANS_ACC_64(maccsu_w00) +GEN_SIMD_TRANS_ACC_64(maccsu_w11) +GEN_SIMD_TRANS_ACC_64(maccu_w00) +GEN_SIMD_TRANS_ACC_64(maccu_w01) +GEN_SIMD_TRANS_ACC_64(maccu_w11) diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helpe= r.c index f84b43bfaa7..b9bb7d497fc 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -2810,3 +2810,198 @@ GEN_PSIMD_MUL_ELEM_SCALAR(mulu_w01, uint64_t, uint3= 2_t, uint32_t, uint64_t, EXTRACT32, 0, 1, PSIMD_MUL_U64) GEN_PSIMD_MUL_ELEM_SCALAR(mulu_w11, uint64_t, uint32_t, uint32_t, uint64_t, EXTRACT32, 1, 1, PSIMD_MUL_U64) + +/* Multiply-Accumulate Operations */ + +GEN_PSIMD_MUL_HIGH_ACC(pmhacc_h, target_ulong, int16_t, int16_t, int16_t, + int32_t, int16_t, uint16_t, EXTRACT16, INSERT16, + ELEMS_H, 16, 0, PSIMD_MUL_S32) +GEN_PSIMD_MUL_HIGH_ACC(pmhaccsu_h, target_ulong, int16_t, uint16_t, int16_= t, + int32_t, int16_t, uint16_t, EXTRACT16, INSERT16, + ELEMS_H, 16, 0, PSIMD_MUL_SU32) +GEN_PSIMD_MUL_HIGH_ACC(pmhaccu_h, target_ulong, uint16_t, uint16_t, uint16= _t, + uint32_t, uint16_t, uint16_t, EXTRACT16, INSERT16, + ELEMS_H, 16, 0, PSIMD_MUL_U32) +GEN_PSIMD_MUL_HIGH_ACC(pmhracc_h, target_ulong, int16_t, int16_t, int16_t, + int32_t, int16_t, uint16_t, EXTRACT16, INSERT16, + ELEMS_H, 16, 1 << 15, PSIMD_MUL_S32) +GEN_PSIMD_MUL_HIGH_ACC(pmhraccsu_h, target_ulong, int16_t, uint16_t, int16= _t, + int32_t, int16_t, uint16_t, EXTRACT16, INSERT16, + ELEMS_H, 16, 1 << 15, PSIMD_MUL_SU32) +GEN_PSIMD_MUL_HIGH_ACC(pmhraccu_h, target_ulong, uint16_t, uint16_t, + uint16_t, uint32_t, uint16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 16, 1 << 15, + PSIMD_MUL_U32) + +GEN_PSIMD_MUL_HIGH_ACC(pmhacc_w, uint64_t, int32_t, int32_t, int32_t, + int64_t, int32_t, uint32_t, EXTRACT32, INSERT32, + ELEMS_W, 32, 0, PSIMD_MUL_S64) +GEN_PSIMD_MUL_HIGH_ACC(pmhracc_w, uint64_t, int32_t, int32_t, int32_t, + int64_t, int32_t, uint32_t, EXTRACT32, INSERT32, + ELEMS_W, 32, 1LL << 31, PSIMD_MUL_S64) +GEN_PSIMD_MUL_HIGH_ACC(pmhaccsu_w, uint64_t, int32_t, uint32_t, int32_t, + int64_t, int32_t, uint32_t, EXTRACT32, INSERT32, + ELEMS_W, 32, 0, PSIMD_MUL_SU64) +GEN_PSIMD_MUL_HIGH_ACC(pmhraccsu_w, uint64_t, int32_t, uint32_t, int32_t, + int64_t, int32_t, uint32_t, EXTRACT32, INSERT32, + ELEMS_W, 32, 1LL << 31, PSIMD_MUL_SU64) +GEN_PSIMD_MUL_HIGH_ACC(pmhaccu_w, uint64_t, uint32_t, uint32_t, uint32_t, + uint64_t, uint32_t, uint32_t, EXTRACT32, INSERT32, + ELEMS_W, 32, 0, PSIMD_MUL_U64) +GEN_PSIMD_MUL_HIGH_ACC(pmhraccu_w, uint64_t, uint32_t, uint32_t, uint32_t, + uint64_t, uint32_t, uint32_t, EXTRACT32, INSERT32, + ELEMS_W, 32, 1LL << 31, PSIMD_MUL_U64) + +GEN_PSIMD_MUL_HIGH_ACC(mhacc, uint32_t, int32_t, int32_t, int32_t, + int64_t, int32_t, uint32_t, EXTRACT32, INSERT32, + ELEMS_W, 32, 0, PSIMD_MUL_S64) +GEN_PSIMD_MUL_HIGH_ACC(mhracc, uint32_t, int32_t, int32_t, int32_t, + int64_t, int32_t, uint32_t, EXTRACT32, INSERT32, + ELEMS_W, 32, 1LL << 31, PSIMD_MUL_S64) +GEN_PSIMD_MUL_HIGH_ACC(mhaccsu, uint32_t, int32_t, uint32_t, int32_t, + int64_t, int32_t, uint32_t, EXTRACT32, INSERT32, + ELEMS_W, 32, 0, PSIMD_MUL_SU64) +GEN_PSIMD_MUL_HIGH_ACC(mhraccsu, uint32_t, int32_t, uint32_t, int32_t, + int64_t, int32_t, uint32_t, EXTRACT32, INSERT32, + ELEMS_W, 32, 1LL << 31, PSIMD_MUL_SU64) +GEN_PSIMD_MUL_HIGH_ACC(mhaccu, uint32_t, uint32_t, uint32_t, uint32_t, + uint64_t, uint32_t, uint32_t, EXTRACT32, INSERT32, + ELEMS_W, 32, 0, PSIMD_MUL_U64) +GEN_PSIMD_MUL_HIGH_ACC(mhraccu, uint32_t, uint32_t, uint32_t, uint32_t, + uint64_t, uint32_t, uint32_t, EXTRACT32, INSERT32, + ELEMS_W, 32, 1LL << 31, PSIMD_MUL_U64) + +GEN_PSIMD_MUL_HIGH_ACC_SEL(pmhacc_h_b0, target_ulong, int16_t, int8_t, + int16_t, int32_t, int16_t, uint16_t, EXTRACT16, + EXTRACT8, INSERT16, ELEMS_H, 2, 0, 8, + PSIMD_MUL_S32) +GEN_PSIMD_MUL_HIGH_ACC_SEL(pmhacc_h_b1, target_ulong, int16_t, int8_t, + int16_t, int32_t, int16_t, uint16_t, EXTRACT16, + EXTRACT8, INSERT16, ELEMS_H, 2, 1, 8, + PSIMD_MUL_S32) +GEN_PSIMD_MUL_HIGH_ACC_SEL(pmhaccsu_h_b0, target_ulong, int16_t, uint8_t, + int16_t, int32_t, int16_t, uint16_t, EXTRACT16, + EXTRACT8, INSERT16, ELEMS_H, 2, 0, 8, + PSIMD_MUL_SU32) +GEN_PSIMD_MUL_HIGH_ACC_SEL(pmhaccsu_h_b1, target_ulong, int16_t, uint8_t, + int16_t, int32_t, int16_t, uint16_t, EXTRACT16, + EXTRACT8, INSERT16, ELEMS_H, 2, 1, 8, + PSIMD_MUL_SU32) + +GEN_PSIMD_MUL_HIGH_ACC_SEL(mhacc_h0, uint32_t, int32_t, int16_t, int32_t, + int64_t, int32_t, uint32_t, EXTRACT32, + EXTRACT16, INSERT32, ELEMS_W, 0, 0, 16, + PSIMD_MUL_S64) +GEN_PSIMD_MUL_HIGH_ACC_SEL(mhacc_h1, uint32_t, int32_t, int16_t, int32_t, + int64_t, int32_t, uint32_t, EXTRACT32, + EXTRACT16, INSERT32, ELEMS_W, 0, 1, 16, + PSIMD_MUL_S64) +GEN_PSIMD_MUL_HIGH_ACC_SEL(mhaccsu_h0, uint32_t, int32_t, uint16_t, int32_= t, + int64_t, int32_t, uint32_t, EXTRACT32, + EXTRACT16, INSERT32, ELEMS_W, 0, 0, 16, + PSIMD_MUL_SU64) +GEN_PSIMD_MUL_HIGH_ACC_SEL(mhaccsu_h1, uint32_t, int32_t, uint16_t, int32_= t, + int64_t, int32_t, uint32_t, EXTRACT32, + EXTRACT16, INSERT32, ELEMS_W, 0, 1, 16, + PSIMD_MUL_SU64) + +GEN_PSIMD_MUL_HIGH_ACC_SEL(pmhacc_w_h0, uint64_t, int32_t, int16_t, + int32_t, int64_t, int32_t, uint32_t, EXTRACT32, + EXTRACT16, INSERT32, ELEMS_W, 2, 0, 16, + PSIMD_MUL_S64) +GEN_PSIMD_MUL_HIGH_ACC_SEL(pmhacc_w_h1, uint64_t, int32_t, int16_t, + int32_t, int64_t, int32_t, uint32_t, EXTRACT32, + EXTRACT16, INSERT32, ELEMS_W, 2, 1, 16, + PSIMD_MUL_S64) +GEN_PSIMD_MUL_HIGH_ACC_SEL(pmhaccsu_w_h0, uint64_t, int32_t, uint16_t, + int32_t, int64_t, int32_t, uint32_t, EXTRACT32, + EXTRACT16, INSERT32, ELEMS_W, 2, 0, 16, + PSIMD_MUL_SU64) +GEN_PSIMD_MUL_HIGH_ACC_SEL(pmhaccsu_w_h1, uint64_t, int32_t, uint16_t, + int32_t, int64_t, int32_t, uint32_t, EXTRACT32, + EXTRACT16, INSERT32, ELEMS_W, 2, 1, 16, + PSIMD_MUL_SU64) + +GEN_PSIMD_MUL_ACC_INDEXED(pmacc_w_h00, uint64_t, int16_t, int16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 2, 0, 0, PSIMD_MUL_S32) +GEN_PSIMD_MUL_ACC_INDEXED(pmacc_w_h01, uint64_t, int16_t, int16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 2, 0, 1, PSIMD_MUL_S32) +GEN_PSIMD_MUL_ACC_INDEXED(pmacc_w_h11, uint64_t, int16_t, int16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 2, 1, 1, PSIMD_MUL_S32) +GEN_PSIMD_MUL_ACC_INDEXED(pmaccsu_w_h00, uint64_t, int16_t, uint16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 2, 0, 0, PSIMD_MUL_SU32) +GEN_PSIMD_MUL_ACC_INDEXED(pmaccsu_w_h11, uint64_t, int16_t, uint16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 2, 1, 1, PSIMD_MUL_SU32) +GEN_PSIMD_MUL_ACC_INDEXED(pmaccu_w_h00, uint64_t, uint16_t, uint16_t, + uint32_t, uint32_t, uint32_t, EXTRACT16, + EXTRACT32, INSERT32, ELEMS_W, 2, 0, 0, + PSIMD_MUL_U32) +GEN_PSIMD_MUL_ACC_INDEXED(pmaccu_w_h01, uint64_t, uint16_t, uint16_t, + uint32_t, uint32_t, uint32_t, EXTRACT16, + EXTRACT32, INSERT32, ELEMS_W, 2, 0, 1, + PSIMD_MUL_U32) +GEN_PSIMD_MUL_ACC_INDEXED(pmaccu_w_h11, uint64_t, uint16_t, uint16_t, + uint32_t, uint32_t, uint32_t, EXTRACT16, + EXTRACT32, INSERT32, ELEMS_W, 2, 1, 1, + PSIMD_MUL_U32) + +GEN_PSIMD_MUL_ACC_INDEXED(macc_h00, uint32_t, int16_t, int16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 0, 0, 0, PSIMD_MUL_S32) +GEN_PSIMD_MUL_ACC_INDEXED(macc_h01, uint32_t, int16_t, int16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 0, 0, 1, PSIMD_MUL_S32) +GEN_PSIMD_MUL_ACC_INDEXED(macc_h11, uint32_t, int16_t, int16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 0, 1, 1, PSIMD_MUL_S32) +GEN_PSIMD_MUL_ACC_INDEXED(maccsu_h00, uint32_t, int16_t, uint16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 0, 0, 0, PSIMD_MUL_SU32) +GEN_PSIMD_MUL_ACC_INDEXED(maccsu_h11, uint32_t, int16_t, uint16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 0, 1, 1, PSIMD_MUL_SU32) +GEN_PSIMD_MUL_ACC_INDEXED(maccu_h00, uint32_t, uint16_t, uint16_t, + uint32_t, uint32_t, uint32_t, EXTRACT16, + EXTRACT32, INSERT32, ELEMS_W, 0, 0, 0, + PSIMD_MUL_U32) +GEN_PSIMD_MUL_ACC_INDEXED(maccu_h01, uint32_t, uint16_t, uint16_t, + uint32_t, uint32_t, uint32_t, EXTRACT16, + EXTRACT32, INSERT32, ELEMS_W, 0, 0, 1, + PSIMD_MUL_U32) +GEN_PSIMD_MUL_ACC_INDEXED(maccu_h11, uint32_t, uint16_t, uint16_t, + uint32_t, uint32_t, uint32_t, EXTRACT16, + EXTRACT32, INSERT32, ELEMS_W, 0, 1, 1, + PSIMD_MUL_U32) + +GEN_PSIMD_MUL_ACC_INDEXED(macc_w00, uint64_t, int32_t, int32_t, + int64_t, int64_t, uint64_t, EXTRACT32, EXTRACT64, + INSERT64, ELEMS_D, 0, 0, 0, PSIMD_MUL_S64) +GEN_PSIMD_MUL_ACC_INDEXED(macc_w01, uint64_t, int32_t, int32_t, + int64_t, int64_t, uint64_t, EXTRACT32, EXTRACT64, + INSERT64, ELEMS_D, 0, 0, 1, PSIMD_MUL_S64) +GEN_PSIMD_MUL_ACC_INDEXED(macc_w11, uint64_t, int32_t, int32_t, + int64_t, int64_t, uint64_t, EXTRACT32, EXTRACT64, + INSERT64, ELEMS_D, 0, 1, 1, PSIMD_MUL_S64) +GEN_PSIMD_MUL_ACC_INDEXED(maccsu_w00, uint64_t, int32_t, uint32_t, + int64_t, int64_t, uint64_t, EXTRACT32, EXTRACT64, + INSERT64, ELEMS_D, 0, 0, 0, PSIMD_MUL_SU64) +GEN_PSIMD_MUL_ACC_INDEXED(maccsu_w11, uint64_t, int32_t, uint32_t, + int64_t, int64_t, uint64_t, EXTRACT32, EXTRACT64, + INSERT64, ELEMS_D, 0, 1, 1, PSIMD_MUL_SU64) +GEN_PSIMD_MUL_ACC_INDEXED(maccu_w00, uint64_t, uint32_t, uint32_t, + uint64_t, uint64_t, uint64_t, EXTRACT32, + EXTRACT64, INSERT64, ELEMS_D, 0, 0, 0, + PSIMD_MUL_U64) +GEN_PSIMD_MUL_ACC_INDEXED(maccu_w01, uint64_t, uint32_t, uint32_t, + uint64_t, uint64_t, uint64_t, EXTRACT32, + EXTRACT64, INSERT64, ELEMS_D, 0, 0, 1, + PSIMD_MUL_U64) +GEN_PSIMD_MUL_ACC_INDEXED(maccu_w11, uint64_t, uint32_t, uint32_t, + uint64_t, uint64_t, uint64_t, EXTRACT32, + EXTRACT64, INSERT64, ELEMS_D, 0, 1, 1, + PSIMD_MUL_U64) --=20 2.34.1 From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789542913202812.6452822783875; Wed, 16 Sep 2026 00:15:13 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jr2-0005cZ-Uq; Wed, 16 Sep 2026 03:14:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jqv-0005aj-54; Wed, 16 Sep 2026 03:14:45 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jqs-0000zU-13; Wed, 16 Sep 2026 03:14:44 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S14; Wed, 16 Sep 2026 15:08:03 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 12/19] target/riscv: Add packed SIMD Q-format multiplication instructions Date: Wed, 16 Sep 2026 07:07:14 +0000 Message-Id: <20260916070721.3279229-13-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S14 X-Coremail-Antispam: 1UD129KBjvJXoWxXrW7Zw4UGFW7trWruw4kZwb_yoWrur43pF s5G343GrW8JrWfJas3tr4Yyr13Ww4Fkw4Durs3tF1rZay5XFZxZr12vw42kF47XF9rXr1Y 9ayjyr98Aay8t3JanT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUQa14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_Xr0_Ar1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAaw2AFwI0_Jrv_JF1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I 8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_JF0_Jw1lYx0Ex4A2jsIE14v26F4j6r4UJwAm72CE 4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4 IIrI8v6xkF7I0E8cxan2IY04v7MxkF7I0En4kS14v26r1q6r43MxAIw28IcxkI7VAKI48J MxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwV AFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6xIIjxv2 0xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr0_Cr1UMIIF0xvE42xK8V AvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWxJVW8Jr1lIxAIcVC2z280aVCY1x02 67AKxVW8Jr0_Cr1UYxBIdaVFxhVjvjDU0xZFpf9x0JULSdkUUUUU= X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542916469158500 Content-Type: text/plain; charset="utf-8" Implement Q-format multiplication operations. Cover packed halfword and word elements, RV32 scalar forms, and rounded and non-rounded variants. Add the associated decode entries, translators and helpers. Note that these instructions double each signed full-width product and extract a result in the original element width. Rounded variants add the required rounding value before extracting the result. When both source elements are the minimum signed value, the Q-format product cannot be represented in the signed destination range, so saturate it to the maximum signed value and set vxsat. Signed-off-by: Molly Chen --- target/riscv/helper.h | 8 ++++++++ target/riscv/insn32.decode | 12 ++++++++++++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 8 ++++++++ target/riscv/tcg/psimd_helper.c | 18 ++++++++++++++++++ 4 files changed, 46 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index e90e01373ed..40cb4f3825e 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1677,3 +1677,11 @@ DEF_HELPER_4(maccsu_w11, i64, env, i64, i64, i64) DEF_HELPER_4(maccu_w00, i64, env, i64, i64, i64) DEF_HELPER_4(maccu_w01, i64, env, i64, i64, i64) DEF_HELPER_4(maccu_w11, i64, env, i64, i64, i64) + +/* Packed SIMD - Q-Format Multiplication Operations */ +DEF_HELPER_3(pmulq_h, tl, env, tl, tl) +DEF_HELPER_3(pmulqr_h, tl, env, tl, tl) +DEF_HELPER_3(pmulq_w, i64, env, i64, i64) +DEF_HELPER_3(pmulqr_w, i64, env, i64, i64) +DEF_HELPER_3(mulq, i32, env, i32, i32) +DEF_HELPER_3(mulqr, i32, env, i32, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 2bf26ec1563..6f9c40f2db7 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -1523,3 +1523,15 @@ maccsu_w11 11111 11 ..... ..... 011 ..... 01110= 11 @r maccu_w00 10101 11 ..... ..... 011 ..... 0111011 @r maccu_w01 10111 11 ..... ..... 001 ..... 0111011 @r maccu_w11 10111 11 ..... ..... 011 ..... 0111011 @r + +# Packed SIMD - Q-Format Multiplication Operations +pmulq_h 11010 00 ..... ..... 111 ..... 0111011 @r +pmulqr_h 11010 10 ..... ..... 111 ..... 0111011 @r +{ + mulq 11010 01 ..... ..... 111 ..... 0111011 @r + pmulq_w 11010 01 ..... ..... 111 ..... 0111011 @r +} +{ + mulqr 11010 11 ..... ..... 111 ..... 0111011 @r + pmulqr_w 11010 11 ..... ..... 111 ..... 0111011 @r +} diff --git a/target/riscv/tcg/insn_trans/trans_rvp.c.inc b/target/riscv/tcg= /insn_trans/trans_rvp.c.inc index 5aaa3c6ffa5..5eff8031885 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -846,3 +846,11 @@ GEN_SIMD_TRANS_ACC_64(maccsu_w11) GEN_SIMD_TRANS_ACC_64(maccu_w00) GEN_SIMD_TRANS_ACC_64(maccu_w01) GEN_SIMD_TRANS_ACC_64(maccu_w11) + +/* Packed SIMD - Q-Format Multiplication Operations */ +GEN_SIMD_TRANS_VXSAT(pmulq_h) +GEN_SIMD_TRANS_VXSAT(pmulqr_h) +GEN_SIMD_TRANS_64_VXSAT(pmulq_w) +GEN_SIMD_TRANS_64_VXSAT(pmulqr_w) +GEN_SIMD_TRANS_32_VXSAT(mulq) +GEN_SIMD_TRANS_32_VXSAT(mulqr) diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helpe= r.c index b9bb7d497fc..52df992b462 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -3005,3 +3005,21 @@ GEN_PSIMD_MUL_ACC_INDEXED(maccu_w11, uint64_t, uint3= 2_t, uint32_t, uint64_t, uint64_t, uint64_t, EXTRACT32, EXTRACT64, INSERT64, ELEMS_D, 0, 1, 1, PSIMD_MUL_U64) + +/* Q-Format Multiplication Operations */ + +GEN_PSIMD_QMUL(pmulq_h, target_ulong, int16_t, int32_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 15, 0, INT16_MIN, INT16_MAX) +GEN_PSIMD_QMUL(pmulqr_h, target_ulong, int16_t, int32_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 15, 1 << 14, INT16_MIN, + INT16_MAX) +GEN_PSIMD_QMUL(pmulq_w, uint64_t, int32_t, int64_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 31, 0, INT32_MIN, INT32_MAX) +GEN_PSIMD_QMUL(pmulqr_w, uint64_t, int32_t, int64_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 31, 1LL << 30, INT32_MIN, + INT32_MAX) +GEN_PSIMD_QMUL(mulq, uint32_t, int32_t, int64_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 31, 0, INT32_MIN, INT32_MAX) +GEN_PSIMD_QMUL(mulqr, uint32_t, int32_t, int64_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 31, 1LL << 30, INT32_MIN, + INT32_MAX) --=20 2.34.1 From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 178954259423262.119061448370985; Wed, 16 Sep 2026 00:09:54 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jlD-0006ER-1L; Wed, 16 Sep 2026 03:08:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jkt-0005px-Fs; Wed, 16 Sep 2026 03:08:33 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jkp-0008Jf-O3; Wed, 16 Sep 2026 03:08:31 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S15; Wed, 16 Sep 2026 15:08:04 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 13/19] target/riscv: Add packed SIMD Q-format MAC instructions Date: Wed, 16 Sep 2026 07:07:15 +0000 Message-Id: <20260916070721.3279229-14-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S15 X-Coremail-Antispam: 1UD129KBjvJXoW3Jw4DZw4xuw1rKrWrZw1rXrb_yoWfZr18pF Z7GrW7WrWIgr43tFyvgr45Cw4DWr4Skw4DCr13JF15AFZ5XFn8Gryjqw17ua17WFZrXF1Y 9ayIyrWq9aySqwUanT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUQa14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_Ar0_tr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAaw2AFwI0_Jrv_JF1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I 8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_JF0_Jw1lYx0Ex4A2jsIE14v26F4j6r4UJwAm72CE 4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4 IIrI8v6xkF7I0E8cxan2IY04v7MxkF7I0En4kS14v26r1q6r43MxAIw28IcxkI7VAKI48J MxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwV AFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6xIIjxv2 0xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr0_Cr1UMIIF0xvE42xK8V AvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWxJVW8Jr1lIxAIcVC2z280aVCY1x02 67AKxVW8Jr0_Cr1UYxBIdaVFxhVjvjDU0xZFpf9x0JULSdkUUUUU= X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542596574158500 Content-Type: text/plain; charset="utf-8" Implement Q-format multiply-accumulate operations. Cover packed and scalar forms, halfword and word source-element selections, and rounded and non-rounded variants.Add the associated decode entries, translators and helpers. These instructions multiply selected signed source elements, discard the low fractional bits to produce a Q-format result in the wider destination element width, and add it to the corresponding element of rd. Rounded variants add the required rounding value before extracting the product. Accumulation wraps to the destination element width, and these operations do not affect vxsat. Signed-off-by: Molly Chen --- target/riscv/helper.h | 20 ++++++ target/riscv/insn32.decode | 32 +++++++++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 20 ++++++ target/riscv/tcg/psimd_helper.c | 78 +++++++++++++++++++++ 4 files changed, 150 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 40cb4f3825e..7a052991ad1 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1685,3 +1685,23 @@ DEF_HELPER_3(pmulq_w, i64, env, i64, i64) DEF_HELPER_3(pmulqr_w, i64, env, i64, i64) DEF_HELPER_3(mulq, i32, env, i32, i32) DEF_HELPER_3(mulqr, i32, env, i32, i32) + +/* Packed SIMD - Q-Format Multiply-Accumulate Operations */ +DEF_HELPER_4(mqacc_h00, i32, env, i32, i32, i32) +DEF_HELPER_4(mqacc_h01, i32, env, i32, i32, i32) +DEF_HELPER_4(mqacc_h11, i32, env, i32, i32, i32) +DEF_HELPER_4(mqracc_h00, i32, env, i32, i32, i32) +DEF_HELPER_4(mqracc_h01, i32, env, i32, i32, i32) +DEF_HELPER_4(mqracc_h11, i32, env, i32, i32, i32) +DEF_HELPER_4(mqacc_w00, i64, env, i64, i64, i64) +DEF_HELPER_4(mqacc_w01, i64, env, i64, i64, i64) +DEF_HELPER_4(mqacc_w11, i64, env, i64, i64, i64) +DEF_HELPER_4(mqracc_w00, i64, env, i64, i64, i64) +DEF_HELPER_4(mqracc_w01, i64, env, i64, i64, i64) +DEF_HELPER_4(mqracc_w11, i64, env, i64, i64, i64) +DEF_HELPER_4(pmqacc_w_h00, i64, env, i64, i64, i64) +DEF_HELPER_4(pmqacc_w_h01, i64, env, i64, i64, i64) +DEF_HELPER_4(pmqacc_w_h11, i64, env, i64, i64, i64) +DEF_HELPER_4(pmqracc_w_h00, i64, env, i64, i64, i64) +DEF_HELPER_4(pmqracc_w_h01, i64, env, i64, i64, i64) +DEF_HELPER_4(pmqracc_w_h11, i64, env, i64, i64, i64) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 6f9c40f2db7..3d9e79de58f 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -1535,3 +1535,35 @@ pmulqr_h 11010 10 ..... ..... 111 ..... 0111011 @r mulqr 11010 11 ..... ..... 111 ..... 0111011 @r pmulqr_w 11010 11 ..... ..... 111 ..... 0111011 @r } + +# Packed SIMD - Q-Format Multiply-Accumulate Operations +{ + mqacc_h00 11101 00 ..... ..... 111 ..... 0111011 @r + pmqacc_w_h00 11101 00 ..... ..... 111 ..... 0111011 @r +} +{ + mqacc_h01 11111 00 ..... ..... 101 ..... 0111011 @r + pmqacc_w_h01 11111 00 ..... ..... 101 ..... 0111011 @r +} +{ + mqacc_h11 11111 00 ..... ..... 111 ..... 0111011 @r + pmqacc_w_h11 11111 00 ..... ..... 111 ..... 0111011 @r +} +{ + mqracc_h00 11101 10 ..... ..... 111 ..... 0111011 @r + pmqracc_w_h00 11101 10 ..... ..... 111 ..... 0111011 @r +} +{ + mqracc_h01 11111 10 ..... ..... 101 ..... 0111011 @r + pmqracc_w_h01 11111 10 ..... ..... 101 ..... 0111011 @r +} +{ + mqracc_h11 11111 10 ..... ..... 111 ..... 0111011 @r + pmqracc_w_h11 11111 10 ..... ..... 111 ..... 0111011 @r +} +mqacc_w00 11101 01 ..... ..... 111 ..... 0111011 @r +mqacc_w01 11111 01 ..... ..... 101 ..... 0111011 @r +mqacc_w11 11111 01 ..... ..... 111 ..... 0111011 @r +mqracc_w00 11101 11 ..... ..... 111 ..... 0111011 @r +mqracc_w01 11111 11 ..... ..... 101 ..... 0111011 @r +mqracc_w11 11111 11 ..... ..... 111 ..... 0111011 @r diff --git a/target/riscv/tcg/insn_trans/trans_rvp.c.inc b/target/riscv/tcg= /insn_trans/trans_rvp.c.inc index 5eff8031885..ef3c5b00a3a 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -854,3 +854,23 @@ GEN_SIMD_TRANS_64_VXSAT(pmulq_w) GEN_SIMD_TRANS_64_VXSAT(pmulqr_w) GEN_SIMD_TRANS_32_VXSAT(mulq) GEN_SIMD_TRANS_32_VXSAT(mulqr) + +/* Packed SIMD - Q-Format Multiply-Accumulate Operations */ +GEN_SIMD_TRANS_ACC_32(mqacc_h00) +GEN_SIMD_TRANS_ACC_32(mqacc_h01) +GEN_SIMD_TRANS_ACC_32(mqacc_h11) +GEN_SIMD_TRANS_ACC_32(mqracc_h00) +GEN_SIMD_TRANS_ACC_32(mqracc_h01) +GEN_SIMD_TRANS_ACC_32(mqracc_h11) +GEN_SIMD_TRANS_ACC_64(mqacc_w00) +GEN_SIMD_TRANS_ACC_64(mqacc_w01) +GEN_SIMD_TRANS_ACC_64(mqacc_w11) +GEN_SIMD_TRANS_ACC_64(mqracc_w00) +GEN_SIMD_TRANS_ACC_64(mqracc_w01) +GEN_SIMD_TRANS_ACC_64(mqracc_w11) +GEN_SIMD_TRANS_ACC_64(pmqacc_w_h00) +GEN_SIMD_TRANS_ACC_64(pmqacc_w_h01) +GEN_SIMD_TRANS_ACC_64(pmqacc_w_h11) +GEN_SIMD_TRANS_ACC_64(pmqracc_w_h00) +GEN_SIMD_TRANS_ACC_64(pmqracc_w_h01) +GEN_SIMD_TRANS_ACC_64(pmqracc_w_h11) diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helpe= r.c index 52df992b462..feb93561e60 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -3023,3 +3023,81 @@ GEN_PSIMD_QMUL(mulq, uint32_t, int32_t, int64_t, uin= t32_t, GEN_PSIMD_QMUL(mulqr, uint32_t, int32_t, int64_t, uint32_t, EXTRACT32, INSERT32, ELEMS_W, 31, 1LL << 30, INT32_MIN, INT32_MAX) + + +/* Q-Format Multiply-Accumulate Operations */ + +GEN_PSIMD_QMUL_ACC_INDEXED(mqacc_h00, uint32_t, int16_t, int16_t, + int32_t, int64_t, int32_t, uint32_t, EXTRACT16, + EXTRACT32, INSERT32, ELEMS_W, 0, 0, 0, 15, 0, + PSIMD_MUL_S64) +GEN_PSIMD_QMUL_ACC_INDEXED(mqacc_h01, uint32_t, int16_t, int16_t, + int32_t, int64_t, int32_t, uint32_t, EXTRACT16, + EXTRACT32, INSERT32, ELEMS_W, 0, 0, 1, 15, 0, + PSIMD_MUL_S64) +GEN_PSIMD_QMUL_ACC_INDEXED(mqacc_h11, uint32_t, int16_t, int16_t, + int32_t, int64_t, int32_t, uint32_t, EXTRACT16, + EXTRACT32, INSERT32, ELEMS_W, 0, 1, 1, 15, 0, + PSIMD_MUL_S64) +GEN_PSIMD_QMUL_ACC_INDEXED(mqracc_h00, uint32_t, int16_t, int16_t, + int32_t, int64_t, int32_t, uint32_t, EXTRACT16, + EXTRACT32, INSERT32, ELEMS_W, 0, 0, 0, 15, + 1LL << 14, PSIMD_MUL_S64) +GEN_PSIMD_QMUL_ACC_INDEXED(mqracc_h01, uint32_t, int16_t, int16_t, + int32_t, int64_t, int32_t, uint32_t, EXTRACT16, + EXTRACT32, INSERT32, ELEMS_W, 0, 0, 1, 15, + 1LL << 14, PSIMD_MUL_S64) +GEN_PSIMD_QMUL_ACC_INDEXED(mqracc_h11, uint32_t, int16_t, int16_t, + int32_t, int64_t, int32_t, uint32_t, EXTRACT16, + EXTRACT32, INSERT32, ELEMS_W, 0, 1, 1, 15, + 1LL << 14, PSIMD_MUL_S64) + +GEN_PSIMD_QMUL_ACC_INDEXED(mqacc_w00, uint64_t, int32_t, int32_t, + int64_t, int64_t, int64_t, uint64_t, EXTRACT32, + EXTRACT64, INSERT64, ELEMS_D, 0, 0, 0, 31, 0, + PSIMD_MUL_S64) +GEN_PSIMD_QMUL_ACC_INDEXED(mqacc_w01, uint64_t, int32_t, int32_t, + int64_t, int64_t, int64_t, uint64_t, EXTRACT32, + EXTRACT64, INSERT64, ELEMS_D, 0, 0, 1, 31, 0, + PSIMD_MUL_S64) +GEN_PSIMD_QMUL_ACC_INDEXED(mqacc_w11, uint64_t, int32_t, int32_t, + int64_t, int64_t, int64_t, uint64_t, EXTRACT32, + EXTRACT64, INSERT64, ELEMS_D, 0, 1, 1, 31, 0, + PSIMD_MUL_S64) +GEN_PSIMD_QMUL_ACC_INDEXED(mqracc_w00, uint64_t, int32_t, int32_t, + int64_t, int64_t, int64_t, uint64_t, EXTRACT32, + EXTRACT64, INSERT64, ELEMS_D, 0, 0, 0, 31, + 1LL << 30, PSIMD_MUL_S64) +GEN_PSIMD_QMUL_ACC_INDEXED(mqracc_w01, uint64_t, int32_t, int32_t, + int64_t, int64_t, int64_t, uint64_t, EXTRACT32, + EXTRACT64, INSERT64, ELEMS_D, 0, 0, 1, 31, + 1LL << 30, PSIMD_MUL_S64) +GEN_PSIMD_QMUL_ACC_INDEXED(mqracc_w11, uint64_t, int32_t, int32_t, + int64_t, int64_t, int64_t, uint64_t, EXTRACT32, + EXTRACT64, INSERT64, ELEMS_D, 0, 1, 1, 31, + 1LL << 30, PSIMD_MUL_S64) + +GEN_PSIMD_QMUL_ACC_INDEXED(pmqacc_w_h00, uint64_t, int16_t, int16_t, + int32_t, int64_t, int32_t, uint32_t, EXTRACT16, + EXTRACT32, INSERT32, ELEMS_W, 2, 0, 0, 15, 0, + PSIMD_MUL_S64) +GEN_PSIMD_QMUL_ACC_INDEXED(pmqacc_w_h01, uint64_t, int16_t, int16_t, + int32_t, int64_t, int32_t, uint32_t, EXTRACT16, + EXTRACT32, INSERT32, ELEMS_W, 2, 0, 1, 15, 0, + PSIMD_MUL_S64) +GEN_PSIMD_QMUL_ACC_INDEXED(pmqacc_w_h11, uint64_t, int16_t, int16_t, + int32_t, int64_t, int32_t, uint32_t, EXTRACT16, + EXTRACT32, INSERT32, ELEMS_W, 2, 1, 1, 15, 0, + PSIMD_MUL_S64) +GEN_PSIMD_QMUL_ACC_INDEXED(pmqracc_w_h00, uint64_t, int16_t, int16_t, + int32_t, int64_t, int32_t, uint32_t, EXTRACT16, + EXTRACT32, INSERT32, ELEMS_W, 2, 0, 0, 15, + 1LL << 14, PSIMD_MUL_S64) +GEN_PSIMD_QMUL_ACC_INDEXED(pmqracc_w_h01, uint64_t, int16_t, int16_t, + int32_t, int64_t, int32_t, uint32_t, EXTRACT16, + EXTRACT32, INSERT32, ELEMS_W, 2, 0, 1, 15, + 1LL << 14, PSIMD_MUL_S64) +GEN_PSIMD_QMUL_ACC_INDEXED(pmqracc_w_h11, uint64_t, int16_t, int16_t, + int32_t, int64_t, int32_t, uint32_t, EXTRACT16, + EXTRACT32, INSERT32, ELEMS_W, 2, 1, 1, 15, + 1LL << 14, PSIMD_MUL_S64) --=20 2.34.1 From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789542931165315.0646783892902; Wed, 16 Sep 2026 00:15:31 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jrW-0005qO-7Y; Wed, 16 Sep 2026 03:15:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jqw-0005bF-5i; Wed, 16 Sep 2026 03:14:48 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jqs-0000zW-0G; Wed, 16 Sep 2026 03:14:45 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S16; Wed, 16 Sep 2026 15:08:04 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 14/19] target/riscv: Add packed SIMD two-way multiply-add/subtract instructions Date: Wed, 16 Sep 2026 07:07:16 +0000 Message-Id: <20260916070721.3279229-15-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S16 X-Coremail-Antispam: 1UD129KBjvAXoW3CrWDuFyrWryDKFy3ZryUGFg_yoW8GF1rJo Z29r15ZrZ3Cw1Uuryakw1UXFn7XrykX3yDGrWUZr43WFWfXr1agr4UJ34UZ3WIyrWayFW7 XrZakw15tF9a934Dn29KB7ZKAUJUUUUr529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUO97AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r126s0DM28Irc Ia0xkI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l 84ACjcxK6xIIjxv20xvE14v26F1j6w1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4UJV WxJr1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE 3s1ln4kS14v26r1Y6r17M2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c 02F40Ex7xfMcIj6xIIjxv20xvE14v26r126r1DMcIj6I8E87Iv67AKxVWxJVW8Jr1lOx8S 6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxw ACI402YVCY1x02628vn2kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxG rwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4 vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IY x2IY67AKxVW8JVW5JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw2 0EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Cr0_Gr1UMIIF0xvEx4A2jsIEc7Cj xVAFwI0_Gr1j6F4UJbIYCTnIWIevJa73UjIFyTuYvjfUoBTYUUUUU X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542932197158500 Content-Type: text/plain; charset="utf-8" Implement Q-format horizontal multiply-add and PM2 horizontal multiply-add/subtract operations. Cover signed, unsigned, mixed-sign, corresponding and crossed element pairing, accumulating and non-accumulating, and rounded and non-rounded variants. Add the associated decode entries, translators and helpers. These instructions combine two products from each packed element group using addition or subtraction. Q-format variants discard the low fractional bits of each product, while rounded variants add the required rounding value before extraction. Accumulating variants add the combined result to the corresponding element of rd. Note that PM2SADD.H and PM2SADD.HX clamp out-of-range sums to the signed destination range and set vxsat; the other operations wrap to the destination width and do not affect vxsat. Signed-off-by: Molly Chen --- target/riscv/helper.h | 36 ++++++ target/riscv/insn32.decode | 36 ++++++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 36 ++++++ target/riscv/tcg/psimd_helper.c | 119 ++++++++++++++++++++ 4 files changed, 227 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 7a052991ad1..5e33026bcb0 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1705,3 +1705,39 @@ DEF_HELPER_4(pmqacc_w_h11, i64, env, i64, i64, i64) DEF_HELPER_4(pmqracc_w_h00, i64, env, i64, i64, i64) DEF_HELPER_4(pmqracc_w_h01, i64, env, i64, i64, i64) DEF_HELPER_4(pmqracc_w_h11, i64, env, i64, i64, i64) + +/* Packed SIMD - Two-Way Multiply and Accumulate Operations */ +DEF_HELPER_3(pmq2add_h, tl, env, tl, tl) +DEF_HELPER_3(pmqr2add_h, tl, env, tl, tl) +DEF_HELPER_4(pmq2adda_h, tl, env, tl, tl, tl) +DEF_HELPER_4(pmqr2adda_h, tl, env, tl, tl, tl) +DEF_HELPER_3(pmq2add_w, i64, env, i64, i64) +DEF_HELPER_3(pmqr2add_w, i64, env, i64, i64) +DEF_HELPER_4(pmq2adda_w, i64, env, i64, i64, i64) +DEF_HELPER_4(pmqr2adda_w, i64, env, i64, i64, i64) +DEF_HELPER_3(pm2add_h, tl, env, tl, tl) +DEF_HELPER_3(pm2addsu_h, tl, env, tl, tl) +DEF_HELPER_3(pm2addu_h, tl, env, tl, tl) +DEF_HELPER_3(pm2add_hx, tl, env, tl, tl) +DEF_HELPER_3(pm2sub_h, tl, env, tl, tl) +DEF_HELPER_3(pm2sub_hx, tl, env, tl, tl) +DEF_HELPER_3(pm2sadd_h, tl, env, tl, tl) +DEF_HELPER_3(pm2sadd_hx, tl, env, tl, tl) +DEF_HELPER_4(pm2adda_h, tl, env, tl, tl, tl) +DEF_HELPER_4(pm2addasu_h, tl, env, tl, tl, tl) +DEF_HELPER_4(pm2addau_h, tl, env, tl, tl, tl) +DEF_HELPER_4(pm2adda_hx, tl, env, tl, tl, tl) +DEF_HELPER_4(pm2suba_h, tl, env, tl, tl, tl) +DEF_HELPER_4(pm2suba_hx, tl, env, tl, tl, tl) +DEF_HELPER_3(pm2add_w, i64, env, i64, i64) +DEF_HELPER_3(pm2addsu_w, i64, env, i64, i64) +DEF_HELPER_3(pm2addu_w, i64, env, i64, i64) +DEF_HELPER_3(pm2add_wx, i64, env, i64, i64) +DEF_HELPER_3(pm2sub_w, i64, env, i64, i64) +DEF_HELPER_3(pm2sub_wx, i64, env, i64, i64) +DEF_HELPER_4(pm2adda_w, i64, env, i64, i64, i64) +DEF_HELPER_4(pm2addasu_w, i64, env, i64, i64, i64) +DEF_HELPER_4(pm2addau_w, i64, env, i64, i64, i64) +DEF_HELPER_4(pm2adda_wx, i64, env, i64, i64, i64) +DEF_HELPER_4(pm2suba_w, i64, env, i64, i64, i64) +DEF_HELPER_4(pm2suba_wx, i64, env, i64, i64, i64) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 3d9e79de58f..263e02ef903 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -1567,3 +1567,39 @@ mqacc_w11 11111 01 ..... ..... 111 ..... 01110= 11 @r mqracc_w00 11101 11 ..... ..... 111 ..... 0111011 @r mqracc_w01 11111 11 ..... ..... 101 ..... 0111011 @r mqracc_w11 11111 11 ..... ..... 111 ..... 0111011 @r + +# Packed SIMD - Two-Way Multiply and Accumulate Operations +pmq2add_h 10110 00 ..... ..... 101 ..... 0111011 @r +pmqr2add_h 10110 10 ..... ..... 101 ..... 0111011 @r +pmq2adda_h 10111 00 ..... ..... 101 ..... 0111011 @r +pmqr2adda_h 10111 10 ..... ..... 101 ..... 0111011 @r +pmq2add_w 10110 01 ..... ..... 101 ..... 0111011 @r +pmqr2add_w 10110 11 ..... ..... 101 ..... 0111011 @r +pmq2adda_w 10111 01 ..... ..... 101 ..... 0111011 @r +pmqr2adda_w 10111 11 ..... ..... 101 ..... 0111011 @r +pm2add_h 10000 00 ..... ..... 101 ..... 0111011 @r +pm2addsu_h 11100 00 ..... ..... 101 ..... 0111011 @r +pm2addu_h 10100 00 ..... ..... 101 ..... 0111011 @r +pm2add_hx 10010 00 ..... ..... 101 ..... 0111011 @r +pm2sub_h 11000 00 ..... ..... 101 ..... 0111011 @r +pm2sub_hx 11010 00 ..... ..... 101 ..... 0111011 @r +pm2sadd_h 11000 10 ..... ..... 101 ..... 0111011 @r +pm2sadd_hx 11010 10 ..... ..... 101 ..... 0111011 @r +pm2adda_h 10001 00 ..... ..... 101 ..... 0111011 @r +pm2addasu_h 11101 00 ..... ..... 101 ..... 0111011 @r +pm2addau_h 10101 00 ..... ..... 101 ..... 0111011 @r +pm2adda_hx 10011 00 ..... ..... 101 ..... 0111011 @r +pm2suba_h 11001 00 ..... ..... 101 ..... 0111011 @r +pm2suba_hx 11011 00 ..... ..... 101 ..... 0111011 @r +pm2add_w 10000 01 ..... ..... 101 ..... 0111011 @r +pm2addsu_w 11100 01 ..... ..... 101 ..... 0111011 @r +pm2addu_w 10100 01 ..... ..... 101 ..... 0111011 @r +pm2add_wx 10010 01 ..... ..... 101 ..... 0111011 @r +pm2sub_w 11000 01 ..... ..... 101 ..... 0111011 @r +pm2sub_wx 11010 01 ..... ..... 101 ..... 0111011 @r +pm2adda_w 10001 01 ..... ..... 101 ..... 0111011 @r +pm2addasu_w 11101 01 ..... ..... 101 ..... 0111011 @r +pm2addau_w 10101 01 ..... ..... 101 ..... 0111011 @r +pm2adda_wx 10011 01 ..... ..... 101 ..... 0111011 @r +pm2suba_w 11001 01 ..... ..... 101 ..... 0111011 @r +pm2suba_wx 11011 01 ..... ..... 101 ..... 0111011 @r diff --git a/target/riscv/tcg/insn_trans/trans_rvp.c.inc b/target/riscv/tcg= /insn_trans/trans_rvp.c.inc index ef3c5b00a3a..65647fd61eb 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -874,3 +874,39 @@ GEN_SIMD_TRANS_ACC_64(pmqacc_w_h11) GEN_SIMD_TRANS_ACC_64(pmqracc_w_h00) GEN_SIMD_TRANS_ACC_64(pmqracc_w_h01) GEN_SIMD_TRANS_ACC_64(pmqracc_w_h11) + +/* Packed SIMD - Two-Way Multiply and Accumulate Operations */ +GEN_SIMD_TRANS(pmq2add_h) +GEN_SIMD_TRANS(pmqr2add_h) +GEN_SIMD_TRANS_ACC(pmq2adda_h) +GEN_SIMD_TRANS_ACC(pmqr2adda_h) +GEN_SIMD_TRANS_64(pmq2add_w) +GEN_SIMD_TRANS_64(pmqr2add_w) +GEN_SIMD_TRANS_ACC_64(pmq2adda_w) +GEN_SIMD_TRANS_ACC_64(pmqr2adda_w) +GEN_SIMD_TRANS(pm2add_h) +GEN_SIMD_TRANS(pm2addsu_h) +GEN_SIMD_TRANS(pm2addu_h) +GEN_SIMD_TRANS(pm2add_hx) +GEN_SIMD_TRANS(pm2sub_h) +GEN_SIMD_TRANS(pm2sub_hx) +GEN_SIMD_TRANS_VXSAT(pm2sadd_h) +GEN_SIMD_TRANS_VXSAT(pm2sadd_hx) +GEN_SIMD_TRANS_ACC(pm2adda_h) +GEN_SIMD_TRANS_ACC(pm2addasu_h) +GEN_SIMD_TRANS_ACC(pm2addau_h) +GEN_SIMD_TRANS_ACC(pm2adda_hx) +GEN_SIMD_TRANS_ACC(pm2suba_h) +GEN_SIMD_TRANS_ACC(pm2suba_hx) +GEN_SIMD_TRANS_64(pm2add_w) +GEN_SIMD_TRANS_64(pm2addsu_w) +GEN_SIMD_TRANS_64(pm2addu_w) +GEN_SIMD_TRANS_64(pm2add_wx) +GEN_SIMD_TRANS_64(pm2sub_w) +GEN_SIMD_TRANS_64(pm2sub_wx) +GEN_SIMD_TRANS_ACC_64(pm2adda_w) +GEN_SIMD_TRANS_ACC_64(pm2addasu_w) +GEN_SIMD_TRANS_ACC_64(pm2addau_w) +GEN_SIMD_TRANS_ACC_64(pm2adda_wx) +GEN_SIMD_TRANS_ACC_64(pm2suba_w) +GEN_SIMD_TRANS_ACC_64(pm2suba_wx) diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helpe= r.c index feb93561e60..639557351da 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -3101,3 +3101,122 @@ GEN_PSIMD_QMUL_ACC_INDEXED(pmqracc_w_h11, uint64_t,= int16_t, int16_t, int32_t, int64_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, INSERT32, ELEMS_W, 2, 1, 1, 15, 1LL << 14, PSIMD_MUL_S64) + +/* Two-Way Multiply and Accumulate Operations */ + +GEN_PSIMD_Q2ADD(pmq2add_h, target_ulong, int16_t, int32_t, int64_t, + uint32_t, EXTRACT16, INSERT32, ELEMS_W, 2, 15, 0, + PSIMD_MUL_S32) +GEN_PSIMD_Q2ADD(pmqr2add_h, target_ulong, int16_t, int32_t, int64_t, + uint32_t, EXTRACT16, INSERT32, ELEMS_W, 2, 15, 1LL << 14, + PSIMD_MUL_S32) +GEN_PSIMD_Q2ADDA(pmq2adda_h, target_ulong, int16_t, int32_t, int32_t, + int64_t, uint32_t, EXTRACT16, EXTRACT32, INSERT32, + ELEMS_W, 2, 15, 0, PSIMD_MUL_S32) +GEN_PSIMD_Q2ADDA(pmqr2adda_h, target_ulong, int16_t, int32_t, int32_t, + int64_t, uint32_t, EXTRACT16, EXTRACT32, INSERT32, + ELEMS_W, 2, 15, 1LL << 14, PSIMD_MUL_S32) + +GEN_PSIMD_Q2ADD(pmq2add_w, uint64_t, int32_t, int64_t, int64_t, + uint64_t, EXTRACT32, INSERT64, ELEMS_D, 0, 31, 0, + PSIMD_MUL_S64) +GEN_PSIMD_Q2ADD(pmqr2add_w, uint64_t, int32_t, int64_t, int64_t, + uint64_t, EXTRACT32, INSERT64, ELEMS_D, 0, 31, 1LL << 30, + PSIMD_MUL_S64) +GEN_PSIMD_Q2ADDA(pmq2adda_w, uint64_t, int32_t, int64_t, int64_t, + int64_t, uint64_t, EXTRACT32, EXTRACT64, INSERT64, + ELEMS_D, 0, 31, 0, PSIMD_MUL_S64) +GEN_PSIMD_Q2ADDA(pmqr2adda_w, uint64_t, int32_t, int64_t, int64_t, + int64_t, uint64_t, EXTRACT32, EXTRACT64, INSERT64, + ELEMS_D, 0, 31, 1LL << 30, PSIMD_MUL_S64) + +GEN_PSIMD_2WAY_MUL(pm2add_h, target_ulong, int16_t, int16_t, + int32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_W, 2, + 0, 1, 0, 1, PSIMD_MUL_S32, PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL(pm2addsu_h, target_ulong, int16_t, uint16_t, + int32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_W, 2, + 0, 1, 0, 1, PSIMD_MUL_SU32, PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL(pm2addu_h, target_ulong, uint16_t, uint16_t, + uint32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_W, 2, + 0, 1, 0, 1, PSIMD_MUL_U32, PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL(pm2add_hx, target_ulong, int16_t, int16_t, + int32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_W, 2, + 0, 1, 1, 0, PSIMD_MUL_S32, PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL(pm2sub_h, target_ulong, int16_t, int16_t, + int32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_W, 2, + 0, 1, 0, 1, PSIMD_MUL_S32, PSIMD_COMB_SUB) +GEN_PSIMD_2WAY_MUL(pm2sub_hx, target_ulong, int16_t, int16_t, + int32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_W, 2, + 0, 1, 1, 0, PSIMD_MUL_S32, PSIMD_COMB_SUB) + +GEN_PSIMD_2WAY_SAT_MUL(pm2sadd_h, 0, 1, 0, 1) +GEN_PSIMD_2WAY_SAT_MUL(pm2sadd_hx, 0, 1, 1, 0) + +GEN_PSIMD_2WAY_MUL_ACC(pm2adda_h, target_ulong, int16_t, int16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 2, 0, 1, 0, 1, PSIMD_MUL_S32, + PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL_ACC(pm2addasu_h, target_ulong, int16_t, uint16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 2, 0, 1, 0, 1, PSIMD_MUL_SU32, + PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL_ACC(pm2addau_h, target_ulong, uint16_t, uint16_t, + uint32_t, uint32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 2, 0, 1, 0, 1, PSIMD_MUL_U32, + PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL_ACC(pm2adda_hx, target_ulong, int16_t, int16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 2, 0, 1, 1, 0, PSIMD_MUL_S32, + PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL_ACC(pm2suba_h, target_ulong, int16_t, int16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 2, 0, 1, 0, 1, PSIMD_MUL_S32, + PSIMD_COMB_SUB) +GEN_PSIMD_2WAY_MUL_ACC(pm2suba_hx, target_ulong, int16_t, int16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 2, 0, 1, 1, 0, PSIMD_MUL_S32, + PSIMD_COMB_SUB) + +GEN_PSIMD_2WAY_MUL(pm2add_w, uint64_t, int32_t, int32_t, + int64_t, uint64_t, EXTRACT32, INSERT64, ELEMS_D, 0, + 0, 1, 0, 1, PSIMD_MUL_S64, PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL(pm2addsu_w, uint64_t, int32_t, uint32_t, + int64_t, uint64_t, EXTRACT32, INSERT64, ELEMS_D, 0, + 0, 1, 0, 1, PSIMD_MUL_SU64, PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL(pm2addu_w, uint64_t, uint32_t, uint32_t, + uint64_t, uint64_t, EXTRACT32, INSERT64, ELEMS_D, 0, + 0, 1, 0, 1, PSIMD_MUL_U64, PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL(pm2add_wx, uint64_t, int32_t, int32_t, + int64_t, uint64_t, EXTRACT32, INSERT64, ELEMS_D, 0, + 0, 1, 1, 0, PSIMD_MUL_S64, PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL(pm2sub_w, uint64_t, int32_t, int32_t, + int64_t, uint64_t, EXTRACT32, INSERT64, ELEMS_D, 0, + 0, 1, 0, 1, PSIMD_MUL_S64, PSIMD_COMB_SUB) +GEN_PSIMD_2WAY_MUL(pm2sub_wx, uint64_t, int32_t, int32_t, + int64_t, uint64_t, EXTRACT32, INSERT64, ELEMS_D, 0, + 0, 1, 1, 0, PSIMD_MUL_S64, PSIMD_COMB_SUB) + +GEN_PSIMD_2WAY_MUL_ACC(pm2adda_w, uint64_t, int32_t, int32_t, + int64_t, int64_t, uint64_t, EXTRACT32, EXTRACT64, + INSERT64, ELEMS_D, 0, 0, 1, 0, 1, PSIMD_MUL_S64, + PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL_ACC(pm2addasu_w, uint64_t, int32_t, uint32_t, + int64_t, int64_t, uint64_t, EXTRACT32, EXTRACT64, + INSERT64, ELEMS_D, 0, 0, 1, 0, 1, PSIMD_MUL_SU64, + PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL_ACC(pm2addau_w, uint64_t, uint32_t, uint32_t, + uint64_t, uint64_t, uint64_t, EXTRACT32, EXTRACT64, + INSERT64, ELEMS_D, 0, 0, 1, 0, 1, PSIMD_MUL_U64, + PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL_ACC(pm2adda_wx, uint64_t, int32_t, int32_t, + int64_t, int64_t, uint64_t, EXTRACT32, EXTRACT64, + INSERT64, ELEMS_D, 0, 0, 1, 1, 0, PSIMD_MUL_S64, + PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL_ACC(pm2suba_w, uint64_t, int32_t, int32_t, + int64_t, int64_t, uint64_t, EXTRACT32, EXTRACT64, + INSERT64, ELEMS_D, 0, 0, 1, 0, 1, PSIMD_MUL_S64, + PSIMD_COMB_SUB) +GEN_PSIMD_2WAY_MUL_ACC(pm2suba_wx, uint64_t, int32_t, int32_t, + int64_t, int64_t, uint64_t, EXTRACT32, EXTRACT64, + INSERT64, ELEMS_D, 0, 0, 1, 1, 0, PSIMD_MUL_S64, + PSIMD_COMB_SUB) --=20 2.34.1 From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789542728706288.8932509248983; Wed, 16 Sep 2026 00:12:08 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jlA-0006AS-II; Wed, 16 Sep 2026 03:08:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jkv-0005w4-Hi; Wed, 16 Sep 2026 03:08:36 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jkq-0008Jt-Eh; Wed, 16 Sep 2026 03:08:32 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S17; Wed, 16 Sep 2026 15:08:04 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 15/19] target/riscv: Add packed SIMD four-way multiply-add instructions Date: Wed, 16 Sep 2026 07:07:17 +0000 Message-Id: <20260916070721.3279229-16-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S17 X-Coremail-Antispam: 1UD129KBjvJXoWxtrW5Cw1fCw17JrWxJFWfGrg_yoWxWrWrpa 18Gry3WFWxGFyfXas3tr43Jw43Xrsa9w18WF4fJF1UZFW5JFykWw1jqr12yF43XFyDuF1U Wa4vkryDAaykJwUanT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUQa14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_Ar0_tr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAaw2AFwI0_Jrv_JF1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I 8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_JF0_Jw1lYx0Ex4A2jsIE14v26F4j6r4UJwAm72CE 4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4 IIrI8v6xkF7I0E8cxan2IY04v7MxkF7I0En4kS14v26r1q6r43MxAIw28IcxkI7VAKI48J MxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwV AFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6xIIjxv2 0xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr0_Cr1UMIIF0xvE42xK8V AvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWxJVW8Jr1lIxAIcVC2z280aVCY1x02 67AKxVW8Jr0_Cr1UYxBIdaVFxhVjvjDU0xZFpf9x0JULSdkUUUUU= X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542729004158500 Content-Type: text/plain; charset="utf-8" Implement PM4 horizontal multiply-add operations. Cover byte and halfword source elements, signed, unsigned, and mixed-sign products, and accumulating and non-accumulating variants. Add the associated decode entries, translators and helpers. These instructions multiply four corresponding packed element pairs and sum the four full products into a wider destination element. Accumulating variants add the combined result to the corresponding element of rd. Accumulation wraps to the destination element width, and these operations do not affect vxsat. Signed-off-by: Molly Chen --- target/riscv/helper.h | 14 +++++++ target/riscv/insn32.decode | 14 +++++++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 14 +++++++ target/riscv/tcg/psimd_helper.c | 41 +++++++++++++++++++++ 4 files changed, 83 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 5e33026bcb0..9a75a13d06d 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1741,3 +1741,17 @@ DEF_HELPER_4(pm2addau_w, i64, env, i64, i64, i64) DEF_HELPER_4(pm2adda_wx, i64, env, i64, i64, i64) DEF_HELPER_4(pm2suba_w, i64, env, i64, i64, i64) DEF_HELPER_4(pm2suba_wx, i64, env, i64, i64, i64) + +/* Packed SIMD - Four-Way Multiply and Accumulate Operations */ +DEF_HELPER_3(pm4add_b, tl, env, tl, tl) +DEF_HELPER_3(pm4addsu_b, tl, env, tl, tl) +DEF_HELPER_3(pm4addu_b, tl, env, tl, tl) +DEF_HELPER_4(pm4adda_b, tl, env, tl, tl, tl) +DEF_HELPER_4(pm4addasu_b, tl, env, tl, tl, tl) +DEF_HELPER_4(pm4addau_b, tl, env, tl, tl, tl) +DEF_HELPER_3(pm4add_h, i64, env, i64, i64) +DEF_HELPER_3(pm4addsu_h, i64, env, i64, i64) +DEF_HELPER_3(pm4addu_h, i64, env, i64, i64) +DEF_HELPER_4(pm4adda_h, i64, env, i64, i64, i64) +DEF_HELPER_4(pm4addasu_h, i64, env, i64, i64, i64) +DEF_HELPER_4(pm4addau_h, i64, env, i64, i64, i64) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 263e02ef903..f9c3adc5ffc 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -1603,3 +1603,17 @@ pm2addau_w 10101 01 ..... ..... 101 ..... 01110= 11 @r pm2adda_wx 10011 01 ..... ..... 101 ..... 0111011 @r pm2suba_w 11001 01 ..... ..... 101 ..... 0111011 @r pm2suba_wx 11011 01 ..... ..... 101 ..... 0111011 @r + +# Packed SIMD - Four-Way Multiply and Accumulate Operations +pm4add_b 10000 10 ..... ..... 101 ..... 0111011 @r +pm4addsu_b 11100 10 ..... ..... 101 ..... 0111011 @r +pm4addu_b 10100 10 ..... ..... 101 ..... 0111011 @r +pm4adda_b 10001 10 ..... ..... 101 ..... 0111011 @r +pm4addasu_b 11101 10 ..... ..... 101 ..... 0111011 @r +pm4addau_b 10101 10 ..... ..... 101 ..... 0111011 @r +pm4add_h 10000 11 ..... ..... 101 ..... 0111011 @r +pm4addsu_h 11100 11 ..... ..... 101 ..... 0111011 @r +pm4addu_h 10100 11 ..... ..... 101 ..... 0111011 @r +pm4adda_h 10001 11 ..... ..... 101 ..... 0111011 @r +pm4addasu_h 11101 11 ..... ..... 101 ..... 0111011 @r +pm4addau_h 10101 11 ..... ..... 101 ..... 0111011 @r diff --git a/target/riscv/tcg/insn_trans/trans_rvp.c.inc b/target/riscv/tcg= /insn_trans/trans_rvp.c.inc index 65647fd61eb..eba377fac6b 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -910,3 +910,17 @@ GEN_SIMD_TRANS_ACC_64(pm2addau_w) GEN_SIMD_TRANS_ACC_64(pm2adda_wx) GEN_SIMD_TRANS_ACC_64(pm2suba_w) GEN_SIMD_TRANS_ACC_64(pm2suba_wx) + +/* Packed SIMD - Four-Way Multiply and Accumulate Operations */ +GEN_SIMD_TRANS(pm4add_b) +GEN_SIMD_TRANS(pm4addsu_b) +GEN_SIMD_TRANS(pm4addu_b) +GEN_SIMD_TRANS_ACC(pm4adda_b) +GEN_SIMD_TRANS_ACC(pm4addasu_b) +GEN_SIMD_TRANS_ACC(pm4addau_b) +GEN_SIMD_TRANS_64(pm4add_h) +GEN_SIMD_TRANS_64(pm4addsu_h) +GEN_SIMD_TRANS_64(pm4addu_h) +GEN_SIMD_TRANS_ACC_64(pm4adda_h) +GEN_SIMD_TRANS_ACC_64(pm4addasu_h) +GEN_SIMD_TRANS_ACC_64(pm4addau_h) diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helpe= r.c index 639557351da..94eb68776aa 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -3220,3 +3220,44 @@ GEN_PSIMD_2WAY_MUL_ACC(pm2suba_wx, uint64_t, int32_t= , int32_t, int64_t, int64_t, uint64_t, EXTRACT32, EXTRACT64, INSERT64, ELEMS_D, 0, 0, 1, 1, 0, PSIMD_MUL_S64, PSIMD_COMB_SUB) + + +/* Four-Way Multiply and Accumulate Operations */ + +GEN_PSIMD_4WAY_MUL(pm4add_b, target_ulong, int8_t, int8_t, + int32_t, uint32_t, EXTRACT8, INSERT32, ELEMS_W, 4, + PSIMD_MUL_S32) +GEN_PSIMD_4WAY_MUL(pm4addsu_b, target_ulong, int8_t, uint8_t, + int32_t, uint32_t, EXTRACT8, INSERT32, ELEMS_W, 4, + PSIMD_MUL_SU32) +GEN_PSIMD_4WAY_MUL(pm4addu_b, target_ulong, uint8_t, uint8_t, + uint32_t, uint32_t, EXTRACT8, INSERT32, ELEMS_W, 4, + PSIMD_MUL_U32) +GEN_PSIMD_4WAY_MUL_ACC(pm4adda_b, target_ulong, int8_t, int8_t, + int32_t, int32_t, uint32_t, EXTRACT8, EXTRACT32, + INSERT32, ELEMS_W, 4, PSIMD_MUL_S32) +GEN_PSIMD_4WAY_MUL_ACC(pm4addasu_b, target_ulong, int8_t, uint8_t, + int32_t, int32_t, uint32_t, EXTRACT8, EXTRACT32, + INSERT32, ELEMS_W, 4, PSIMD_MUL_SU32) +GEN_PSIMD_4WAY_MUL_ACC(pm4addau_b, target_ulong, uint8_t, uint8_t, + uint32_t, uint32_t, uint32_t, EXTRACT8, EXTRACT32, + INSERT32, ELEMS_W, 4, PSIMD_MUL_U32) + +GEN_PSIMD_4WAY_MUL(pm4add_h, uint64_t, int16_t, int16_t, + int64_t, uint64_t, EXTRACT16, INSERT64, ELEMS_D, 0, + PSIMD_MUL_S64) +GEN_PSIMD_4WAY_MUL(pm4addsu_h, uint64_t, int16_t, uint16_t, + int64_t, uint64_t, EXTRACT16, INSERT64, ELEMS_D, 0, + PSIMD_MUL_SU64) +GEN_PSIMD_4WAY_MUL(pm4addu_h, uint64_t, uint16_t, uint16_t, + uint64_t, uint64_t, EXTRACT16, INSERT64, ELEMS_D, 0, + PSIMD_MUL_U64) +GEN_PSIMD_4WAY_MUL_ACC(pm4adda_h, uint64_t, int16_t, int16_t, + int64_t, int64_t, uint64_t, EXTRACT16, EXTRACT64, + INSERT64, ELEMS_D, 0, PSIMD_MUL_S64) +GEN_PSIMD_4WAY_MUL_ACC(pm4addasu_h, uint64_t, int16_t, uint16_t, + int64_t, int64_t, uint64_t, EXTRACT16, EXTRACT64, + INSERT64, ELEMS_D, 0, PSIMD_MUL_SU64) +GEN_PSIMD_4WAY_MUL_ACC(pm4addau_h, uint64_t, uint16_t, uint16_t, + uint64_t, uint64_t, uint64_t, EXTRACT16, EXTRACT64, + INSERT64, ELEMS_D, 0, PSIMD_MUL_U64) --=20 2.34.1 From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789542655845399.63944495354565; Wed, 16 Sep 2026 00:10:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jlE-0006Jb-Bz; Wed, 16 Sep 2026 03:08:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jkv-0005w5-If; Wed, 16 Sep 2026 03:08:37 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jkr-0008KA-0Y; Wed, 16 Sep 2026 03:08:32 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S18; Wed, 16 Sep 2026 15:08:04 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 16/19] target/riscv: Add packed SIMD load-replicate instructions Date: Wed, 16 Sep 2026 07:07:18 +0000 Message-Id: <20260916070721.3279229-17-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S18 X-Coremail-Antispam: 1UD129KBjvJXoWxXw4rtFyfWFWDJw1DKFW5trb_yoWrWw4DpF 48Kr17KrW8Jry7AF1fKr45Jr17XrsxG3yUJrnxXwnxZF45JFyrA34Ut3yUKrWYqFyDWFWU WF1qyryUuaykJwUanT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUQa14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_Ar0_tr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAaw2AFwI0_Jrv_JF1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I 8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_JF0_Jw1lYx0Ex4A2jsIE14v26F4j6r4UJwAm72CE 4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4 IIrI8v6xkF7I0E8cxan2IY04v7MxkF7I0En4kS14v26r1q6r43MxAIw28IcxkI7VAKI48J MxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwV AFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6xIIjxv2 0xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr0_Cr1UMIIF0xvE42xK8V AvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWxJVW8Jr1lIxAIcVC2z280aVCY1x02 67AKxVW8Jr0_Cr1UYxBIdaVFxhVjvjDU0xZFpf9x0JULSdkUUUUU= X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542657478158500 Content-Type: text/plain; charset="utf-8" Implement packed load-immediate and load-upper-immediate operations. Cover byte, halfword, and word elements across the supported register widths. Add the associated decode entries, translators and helpers. These instructions construct an element-sized value from the encoded immediate and replicate it into every packed destination element. PLI.H and PLI.W sign-extend their 10-bit immediates, while PLUI.H and PLUI.W place their immediates in the upper bits of each element and clear the lower bits. These operations do not affect vxsat. Signed-off-by: Molly Chen --- target/riscv/insn32.decode | 16 +++++++++++++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 25 +++++++++++++++++++++ target/riscv/tcg/translate.c | 2 ++ 3 files changed, 43 insertions(+) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index f9c3adc5ffc..b7651bdcba3 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -44,6 +44,10 @@ %imm_p_ui16 20:4 %imm_p_ui32 20:5 %imm_p_ui64 20:6 +%imm_p_l1 16:8 +%imm_p_l2 15:s1 16:9 +%imm_p_l3 15:s9 24:1 !function=3Dex_shift_6 +%imm_p_l4 15:s9 24:1 !function=3Dex_shift_22 =20 # Argument sets: &empty @@ -53,6 +57,7 @@ &r rd rs1 rs2 &r2 rd rs1 &r2_s rs1 rs2 +&p_l imm rd &s imm rs1 rs2 &u imm rd &shift shamt rs1 rd @@ -114,6 +119,10 @@ @p_ui16 ..... .... ... ..... ... ..... ....... &i imm=3D%imm_p_ui16 %rs1 %= rd @p_ui32 ..... .... ... ..... ... ..... ....... &i imm=3D%imm_p_ui32 %rs1 %= rd @p_ui64 ..... .... ... ..... ... ..... ....... &i imm=3D%imm_p_ui64 %rs1 %= rd +@p_l1 ........ ........ .... ..... ....... &p_l imm=3D%imm_p_l1 = %rd +@p_l2 ....... .......... ... ..... ....... &p_l imm=3D%imm_p_l2 = %rd +@p_l3 ....... .......... ... ..... ....... &p_l imm=3D%imm_p_l3 = %rd +@p_l4 ....... .......... ... ..... ....... &p_l imm=3D%imm_p_l4 = %rd =20 # Formats 64: @sh5 ....... ..... ..... ... ..... ....... &shift shamt=3D%sh5 = %rs1 %rd @@ -1617,3 +1626,10 @@ pm4addu_h 10100 11 ..... ..... 101 ..... 01110= 11 @r pm4adda_h 10001 11 ..... ..... 101 ..... 0111011 @r pm4addasu_h 11101 11 ..... ..... 101 ..... 0111011 @r pm4addau_h 10101 11 ..... ..... 101 ..... 0111011 @r + +# Packed SIMD - Load and Replicate instructions +pli_b 10110100 ........ 0010 ..... 0011011 @p_l1 +pli_h 1011000 .......... 010 ..... 0011011 @p_l2 +plui_h 1111000 .......... 010 ..... 0011011 @p_l3 +pli_w 1011001 ..... ..... 010 ..... 0011011 @p_l2 +plui_w 1111001 ..... ..... 010 ..... 0011011 @p_l4 diff --git a/target/riscv/tcg/insn_trans/trans_rvp.c.inc b/target/riscv/tcg= /insn_trans/trans_rvp.c.inc index eba377fac6b..c172c8e4e0a 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -924,3 +924,28 @@ GEN_SIMD_TRANS_64(pm4addu_h) GEN_SIMD_TRANS_ACC_64(pm4adda_h) GEN_SIMD_TRANS_ACC_64(pm4addasu_h) GEN_SIMD_TRANS_ACC_64(pm4addau_h) + +#define GEN_PLI(NAME, PRE_REQ, IMM_TYPE, LIMIT, SHIFT, ADDEND) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + PRE_REQ \ + REQUIRE_RVP(ctx); \ + int i =3D 1; \ + IMM_TYPE imm =3D a->imm; \ + while (i < (LIMIT)) { \ + imm =3D (imm << (SHIFT)) + (ADDEND); \ + i++; \ + } \ + gen_set_gpri(ctx, a->rd, imm); \ + return true; \ +} + +GEN_PLI(pli_b, , target_long, TARGET_LONG_SIZE, 8, a->imm) +GEN_PLI(pli_h, , target_long, TARGET_LONG_SIZE / 2, 16, + a->imm & 0xFFFF) +GEN_PLI(plui_h, , target_long, TARGET_LONG_SIZE / 2, 16, + a->imm & 0xFFFF) +GEN_PLI(pli_w, REQUIRE_64BIT(ctx); , int64_t, TARGET_LONG_SIZE / 4, 32, + a->imm & 0xFFFFFFFF) +GEN_PLI(plui_w, REQUIRE_64BIT(ctx); , int64_t, TARGET_LONG_SIZE / 4, 32, + a->imm & 0xFFFFFFFF) diff --git a/target/riscv/tcg/translate.c b/target/riscv/tcg/translate.c index 0df9d4190f1..668ec3120af 100644 --- a/target/riscv/tcg/translate.c +++ b/target/riscv/tcg/translate.c @@ -790,7 +790,9 @@ EX_SH(1) EX_SH(2) EX_SH(3) EX_SH(4) +EX_SH(6) EX_SH(12) +EX_SH(22) =20 #define REQUIRE_EXT(ctx, ext) do { \ if (!has_ext(ctx, ext)) { \ --=20 2.34.1 From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789542941486861.2358443029802; Wed, 16 Sep 2026 00:15:41 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jrV-0005pr-8z; Wed, 16 Sep 2026 03:15:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jqy-0005bK-7c; Wed, 16 Sep 2026 03:14:48 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jqr-0000zV-UP; Wed, 16 Sep 2026 03:14:48 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S19; Wed, 16 Sep 2026 15:08:05 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 17/19] target/riscv: Add packed SIMD RV32 only instructions Date: Wed, 16 Sep 2026 07:07:19 +0000 Message-Id: <20260916070721.3279229-18-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S19 X-Coremail-Antispam: 1UD129KBjvAXoWDCw4DtFykWF1ruw15Kw4rKrg_yoW7uw17Co WrCw15Zrn7G348X34akw4UZFyUZrZ2vwn3KrW5Zr47Za93Jr9rGr1DJ34rZa48Zry5tFWf JrZ3Gwn8trnIgw1Dn29KB7ZKAUJUUUUr529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUO97AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r126s0DM28Irc Ia0xkI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l 84ACjcxK6xIIjxv20xvE14v26F1j6w1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4UJV WxJr1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE 3s1ln4kS14v26r1Y6r17M2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c 02F40Ex7xfMcIj6xIIjxv20xvE14v26r126r1DMcIj6I8E87Iv67AKxVWxJVW8Jr1lOx8S 6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxw ACI402YVCY1x02628vn2kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxG rwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4 vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IY x2IY67AKxVW8JVW5JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAIw2 0EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Cr0_Gr1UMIIF0xvEx4A2jsIEc7Cj xVAFwI0_Gr1j6F4UJbIYCTnIWIevJa73UjIFyTuYvjfUoBTYUUUUU X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542942393158500 Content-Type: text/plain; charset="utf-8" Implement RV32-only register-pair operations. Cover widening arithmetic, shifts, multiplication and multiply-accumulate operations, double-register equivalents of packed operations, horizontal reductions, element rearrangement, comparisons, and narrowing shift and clipping operations. Add the associated decode entries, translators and hel= pers. These instructions represent 64-bit operands or results using even-odd pairs of 32-bit registers. The helpers combine source register pairs before performing each operation and split results when writing a destination pair. A zero register-pair selector supplies a zero source or suppresses the destination write as defined by the specification. Saturating and clipping variants clamp out-of-range results and set vxsat. Signed-off-by: Molly Chen --- target/riscv/helper.h | 131 ++++++ target/riscv/insn32.decode | 285 +++++++++++- target/riscv/tcg/insn_trans/trans_rvp.c.inc | 488 ++++++++++++++++++++ target/riscv/tcg/psimd_helper.c | 273 +++++++++++ 4 files changed, 1176 insertions(+), 1 deletion(-) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 9a75a13d06d..1feddeb1d65 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1755,3 +1755,134 @@ DEF_HELPER_3(pm4addu_h, i64, env, i64, i64) DEF_HELPER_4(pm4adda_h, i64, env, i64, i64, i64) DEF_HELPER_4(pm4addasu_h, i64, env, i64, i64, i64) DEF_HELPER_4(pm4addau_h, i64, env, i64, i64, i64) + +/* Packed SIMD - Double-Width Operations (RV32 only, register pairs) */ +DEF_HELPER_3(pwadd_b, i64, env, i32, i32) +DEF_HELPER_4(pwadda_b, i64, env, i32, i32, i64) +DEF_HELPER_3(pwaddu_b, i64, env, i32, i32) +DEF_HELPER_4(pwaddau_b, i64, env, i32, i32, i64) +DEF_HELPER_3(pwsub_b, i64, env, i32, i32) +DEF_HELPER_4(pwsuba_b, i64, env, i32, i32, i64) +DEF_HELPER_3(pwsubu_b, i64, env, i32, i32) +DEF_HELPER_4(pwsubau_b, i64, env, i32, i32, i64) +DEF_HELPER_3(pwslli_b, i64, env, i32, i32) +DEF_HELPER_3(pwsll_bs, i64, env, i32, i32) +DEF_HELPER_3(pwslai_b, i64, env, i32, i32) +DEF_HELPER_3(pwsla_bs, i64, env, i32, i32) + +DEF_HELPER_3(pwadd_h, i64, env, i32, i32) +DEF_HELPER_4(pwadda_h, i64, env, i32, i32, i64) +DEF_HELPER_3(pwaddu_h, i64, env, i32, i32) +DEF_HELPER_4(pwaddau_h, i64, env, i32, i32, i64) +DEF_HELPER_3(pwsub_h, i64, env, i32, i32) +DEF_HELPER_4(pwsuba_h, i64, env, i32, i32, i64) +DEF_HELPER_3(pwsubu_h, i64, env, i32, i32) +DEF_HELPER_4(pwsubau_h, i64, env, i32, i32, i64) +DEF_HELPER_3(pwslli_h, i64, env, i32, i32) +DEF_HELPER_3(pwsll_hs, i64, env, i32, i32) +DEF_HELPER_3(pwslai_h, i64, env, i32, i32) +DEF_HELPER_3(pwsla_hs, i64, env, i32, i32) + +DEF_HELPER_3(wadd, i64, env, i32, i32) +DEF_HELPER_4(wadda, i64, env, i32, i32, i64) +DEF_HELPER_3(waddu, i64, env, i32, i32) +DEF_HELPER_4(waddau, i64, env, i32, i32, i64) +DEF_HELPER_3(wsub, i64, env, i32, i32) +DEF_HELPER_4(wsuba, i64, env, i32, i32, i64) +DEF_HELPER_3(wsubu, i64, env, i32, i32) +DEF_HELPER_4(wsubau, i64, env, i32, i32, i64) +DEF_HELPER_3(wslli, i64, env, i32, i32) +DEF_HELPER_3(wsll, i64, env, i32, i32) +DEF_HELPER_3(wslai, i64, env, i32, i32) +DEF_HELPER_3(wsla, i64, env, i32, i32) + +DEF_HELPER_3(wzip8p, i64, env, i32, i32) +DEF_HELPER_3(wzip16p, i64, env, i32, i32) + +DEF_HELPER_4(predsum_dbs, i32, env, i32, i32, i32) +DEF_HELPER_4(predsumu_dbs, i32, env, i32, i32, i32) +DEF_HELPER_4(predsum_dhs, i32, env, i32, i32, i32) +DEF_HELPER_4(predsumu_dhs, i32, env, i32, i32, i32) + +DEF_HELPER_3(pnsrli_b, i32, env, i64, i32) +DEF_HELPER_3(pnsrai_b, i32, env, i64, i32) +DEF_HELPER_3(pnsrari_b, i32, env, i64, i32) +DEF_HELPER_3(pnclipi_b, i32, env, i64, i32) +DEF_HELPER_3(pnclipri_b, i32, env, i64, i32) +DEF_HELPER_3(pnclipiu_b, i32, env, i64, i32) +DEF_HELPER_3(pnclipriu_b, i32, env, i64, i32) +DEF_HELPER_3(pnsrl_bs, i32, env, i64, i32) +DEF_HELPER_3(pnsra_bs, i32, env, i64, i32) +DEF_HELPER_3(pnsrar_bs, i32, env, i64, i32) +DEF_HELPER_3(pnclip_bs, i32, env, i64, i32) +DEF_HELPER_3(pnclipr_bs, i32, env, i64, i32) +DEF_HELPER_3(pnclipu_bs, i32, env, i64, i32) +DEF_HELPER_3(pnclipru_bs, i32, env, i64, i32) + +DEF_HELPER_3(pnsrli_h, i32, env, i64, i32) +DEF_HELPER_3(pnsrai_h, i32, env, i64, i32) +DEF_HELPER_3(pnsrari_h, i32, env, i64, i32) +DEF_HELPER_3(pnclipi_h, i32, env, i64, i32) +DEF_HELPER_3(pnclipri_h, i32, env, i64, i32) +DEF_HELPER_3(pnclipiu_h, i32, env, i64, i32) +DEF_HELPER_3(pnclipriu_h, i32, env, i64, i32) +DEF_HELPER_3(pnsrl_hs, i32, env, i64, i32) +DEF_HELPER_3(pnsra_hs, i32, env, i64, i32) +DEF_HELPER_3(pnsrar_hs, i32, env, i64, i32) +DEF_HELPER_3(pnclip_hs, i32, env, i64, i32) +DEF_HELPER_3(pnclipr_hs, i32, env, i64, i32) +DEF_HELPER_3(pnclipu_hs, i32, env, i64, i32) +DEF_HELPER_3(pnclipru_hs, i32, env, i64, i32) + +DEF_HELPER_3(nsrli, i32, env, i64, i32) +DEF_HELPER_3(nsrai, i32, env, i64, i32) +DEF_HELPER_3(nsrari, i32, env, i64, i32) +DEF_HELPER_3(nclipi, i32, env, i64, i32) +DEF_HELPER_3(nclipri, i32, env, i64, i32) +DEF_HELPER_3(nclipiu, i32, env, i64, i32) +DEF_HELPER_3(nclipriu, i32, env, i64, i32) +DEF_HELPER_3(nsrl, i32, env, i64, i32) +DEF_HELPER_3(nsra, i32, env, i64, i32) +DEF_HELPER_3(nsrar, i32, env, i64, i32) +DEF_HELPER_3(nclip, i32, env, i64, i32) +DEF_HELPER_3(nclipr, i32, env, i64, i32) +DEF_HELPER_3(nclipu, i32, env, i64, i32) +DEF_HELPER_3(nclipru, i32, env, i64, i32) + +DEF_HELPER_4(pmqwacc_h, i64, env, i32, i32, i64) +DEF_HELPER_4(pmqrwacc_h, i64, env, i32, i32, i64) +DEF_HELPER_4(mqwacc, i64, env, i32, i32, i64) +DEF_HELPER_4(mqrwacc, i64, env, i32, i32, i64) + +DEF_HELPER_3(pwmul_b, i64, env, i32, i32) +DEF_HELPER_3(pwmulsu_b, i64, env, i32, i32) +DEF_HELPER_3(pwmulu_b, i64, env, i32, i32) +DEF_HELPER_3(pwmul_h, i64, env, i32, i32) +DEF_HELPER_3(pwmulsu_h, i64, env, i32, i32) +DEF_HELPER_3(pwmulu_h, i64, env, i32, i32) + +DEF_HELPER_4(pwmacc_h, i64, env, i32, i32, i64) +DEF_HELPER_4(pwmaccsu_h, i64, env, i32, i32, i64) +DEF_HELPER_4(pwmaccu_h, i64, env, i32, i32, i64) + +DEF_HELPER_3(wmul, i64, env, i32, i32) +DEF_HELPER_3(wmulsu, i64, env, i32, i32) +DEF_HELPER_3(wmulu, i64, env, i32, i32) + +DEF_HELPER_4(wmacc, i64, env, i32, i32, i64) +DEF_HELPER_4(wmaccsu, i64, env, i32, i32, i64) +DEF_HELPER_4(wmaccu, i64, env, i32, i32, i64) + +DEF_HELPER_3(pm2wadd_h, i64, env, i32, i32) +DEF_HELPER_3(pm2waddsu_h, i64, env, i32, i32) +DEF_HELPER_3(pm2waddu_h, i64, env, i32, i32) +DEF_HELPER_3(pm2wadd_hx, i64, env, i32, i32) +DEF_HELPER_4(pm2wadda_h, i64, env, i32, i32, i64) +DEF_HELPER_4(pm2waddasu_h, i64, env, i32, i32, i64) +DEF_HELPER_4(pm2waddau_h, i64, env, i32, i32, i64) +DEF_HELPER_4(pm2wadda_hx, i64, env, i32, i32, i64) + +DEF_HELPER_3(pm2wsub_h, i64, env, i32, i32) +DEF_HELPER_3(pm2wsub_hx, i64, env, i32, i32) +DEF_HELPER_4(pm2wsuba_h, i64, env, i32, i32, i64) +DEF_HELPER_4(pm2wsuba_hx, i64, env, i32, i32, i64) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index b7651bdcba3..9aabc45d5ca 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -23,6 +23,9 @@ %rd 7:5 %sh5 20:5 %sh6 20:6 +%rs2_p 21:4 +%rs1_p 16:4 +%rd_p 8:4 =20 %sh7 20:7 %csr 20:12 @@ -57,7 +60,6 @@ &r rd rs1 rs2 &r2 rd rs1 &r2_s rs1 rs2 -&p_l imm rd &s imm rs1 rs2 &u imm rd &shift shamt rs1 rd @@ -69,6 +71,7 @@ &k_aes shamt rs2 rs1 rd &mop5 imm rd rs1 &mop3 imm rd rs1 rs2 +&p_l imm rd &p_ui imm rs1 rd =20 # Formats 32: @@ -102,6 +105,11 @@ @r2_zimm11 . zimm:11 ..... ... ..... ....... %rs1 %rd @r2_zimm10 .. zimm:10 ..... ... ..... ....... %rs1 %rd @r2_s ....... ..... ..... ... ..... ....... %rs2 %rs1 +@r_p_1 ....... ..... ..... ... ..... ....... &r %rs2 %rs1 rd=3D= %rd_p +@r_p_2 ....... ..... ..... ... ..... ....... &r rs2=3D%rs2_p rs1= =3D%rs1_p rd=3D%rd_p +@r_p_3 ....... ..... ..... ... ..... ....... &r %rs2 rs1=3D%rs1_p= rd=3D%rd_p +@r_p_4 ....... ..... ..... ... ..... ....... &r %rs2 rs1=3D%rs1_p= %rd +@r2_p ....... ..... ..... ... ..... ....... &r2 rs1=3D%rs1_p rd= =3D%rd_p =20 @hfence_gvma ....... ..... ..... ... ..... ....... %rs2 %rs1 @hfence_vvma ....... ..... ..... ... ..... ....... %rs2 %rs1 @@ -123,6 +131,18 @@ @p_l2 ....... .......... ... ..... ....... &p_l imm=3D%imm_p_l2 = %rd @p_l3 ....... .......... ... ..... ....... &p_l imm=3D%imm_p_l3 = %rd @p_l4 ....... .......... ... ..... ....... &p_l imm=3D%imm_p_l4 = %rd +@p_l1_p ........ ........ .... ..... ....... &p_l imm=3D%imm_p_l1 = rd=3D%rd_p +@p_l2_p ........ ........ .... ..... ....... &p_l imm=3D%imm_p_l2 = rd=3D%rd_p +@p_l3_p ....... .......... ... ..... ....... &p_l imm=3D%imm_p_l3 = rd=3D%rd_p +@p_ui8_p ..... .... ... ..... ... ..... ....... &i imm=3D%imm_p_ui8 rs1= =3D%rs1_p rd=3D%rd_p +@p_ui16_p ..... .... ... ..... ... ..... ....... &p_ui imm=3D%imm_p_ui16 %= rs1 rd=3D%rd_p +@p_ui16_p_2 ..... .... ... ..... ... ..... ....... &p_ui imm=3D%imm_p_ui16= rs1=3D%rs1_p rd=3D%rd_p +@p_ui16_p_3 ..... .... ... .... .... ..... ....... &p_ui imm=3D%imm_p_ui16= rs1=3D%rs1_p %rd +@p_ui32_p ..... .... ... ..... ... ..... ....... &p_ui imm=3D%imm_p_ui32 %= rs1 rd=3D%rd_p +@p_ui32_p_2 ..... .... ... ..... ... ..... ....... &p_ui imm=3D%imm_p_ui32= rs1=3D%rs1_p rd=3D%rd_p +@p_ui32_p_3 ..... .... ... ..... ... ..... ....... &p_ui imm=3D%imm_p_ui32= rs1=3D%rs1_p %rd +@p_ui64_p ..... .... ... ..... ... ..... ....... &p_ui imm=3D%imm_p_ui64 %= rs1 rd=3D%rd_p +@p_ui64_p_2 ..... .... ... ..... ... ..... ....... &p_ui imm=3D%imm_p_ui64= rs1=3D%rs1_p %rd =20 # Formats 64: @sh5 ....... ..... ..... ... ..... ....... &shift shamt=3D%sh5 = %rs1 %rd @@ -1633,3 +1653,266 @@ pli_h 1011000 .......... 010 ..... 0011011 @p_l2 plui_h 1111000 .......... 010 ..... 0011011 @p_l3 pli_w 1011001 ..... ..... 010 ..... 0011011 @p_l2 plui_w 1111001 ..... ..... 010 ..... 0011011 @p_l4 + +# Packed SIMD - Double-Width Operations (RV32 only, register pairs) +# register-pair destination +pwadd_b 0000010 ..... ..... 010 .... 10011011 @r_p_1 +pwadda_b 0000110 ..... ..... 010 .... 10011011 @r_p_1 +pwaddu_b 0001010 ..... ..... 010 .... 10011011 @r_p_1 +pwaddau_b 0001110 ..... ..... 010 .... 10011011 @r_p_1 +pwsub_b 0100010 ..... ..... 010 .... 10011011 @r_p_1 +pwsuba_b 0100110 ..... ..... 010 .... 10011011 @r_p_1 +pwsubu_b 0101010 ..... ..... 010 .... 10011011 @r_p_1 +pwsubau_b 0101110 ..... ..... 010 .... 10011011 @r_p_1 +pwslli_b 00000 001.... ..... 010 .... 00011011 @p_ui16_p +pwsll_bs 0000100 ..... ..... 010 .... 00011011 @r_p_1 +pwslai_b 01000 001.... ..... 010 .... 00011011 @p_ui16_p +pwsla_bs 0100100 ..... ..... 010 .... 00011011 @r_p_1 + +pwadd_h 0000000 ..... ..... 010 .... 10011011 @r_p_1 +pwadda_h 0000100 ..... ..... 010 .... 10011011 @r_p_1 +pwaddu_h 0001000 ..... ..... 010 .... 10011011 @r_p_1 +pwaddau_h 0001100 ..... ..... 010 .... 10011011 @r_p_1 +pwsub_h 0100000 ..... ..... 010 .... 10011011 @r_p_1 +pwsuba_h 0100100 ..... ..... 010 .... 10011011 @r_p_1 +pwsubu_h 0101000 ..... ..... 010 .... 10011011 @r_p_1 +pwsubau_h 0101100 ..... ..... 010 .... 10011011 @r_p_1 +pwslli_h 00000 01..... ..... 010 .... 00011011 @p_ui32_p +pwsll_hs 0000101 ..... ..... 010 .... 00011011 @r_p_1 +pwslai_h 01000 01..... ..... 010 .... 00011011 @p_ui32_p +pwsla_hs 0100101 ..... ..... 010 .... 00011011 @r_p_1 + +wadd 0000001 ..... ..... 010 .... 10011011 @r_p_1 +wadda 0000101 ..... ..... 010 .... 10011011 @r_p_1 +waddu 0001001 ..... ..... 010 .... 10011011 @r_p_1 +waddau 0001101 ..... ..... 010 .... 10011011 @r_p_1 +wsub 0100001 ..... ..... 010 .... 10011011 @r_p_1 +wsuba 0100101 ..... ..... 010 .... 10011011 @r_p_1 +wsubu 0101001 ..... ..... 010 .... 10011011 @r_p_1 +wsubau 0101101 ..... ..... 010 .... 10011011 @r_p_1 +wslli 00000 1...... ..... 010 .... 00011011 @p_ui64_p +wsll 0000111 ..... ..... 010 .... 00011011 @r_p_1 +wslai 01000 1...... ..... 010 .... 00011011 @p_ui64_p +wsla 0100111 ..... ..... 010 .... 00011011 @r_p_1 + +wzip8p 0111100 ..... ..... 010 .... 00011011 @r_p_1 +wzip16p 0111101 ..... ..... 010 .... 00011011 @r_p_1 + +#register-pair operands +pli_db 00110100 ........ 0010 .... 00011011 @p_l1_p +padd_db 1000010 .... 0 .... 0110 .... 00011011 @r_p_2 +psub_db 1100010 .... 0 .... 0110 .... 00011011 @r_p_2 +psadd_db 1001010 .... 0 .... 0110 .... 00011011 @r_p_2 +psaddu_db 1011010 .... 0 .... 0110 .... 00011011 @r_p_2 +pssub_db 1101010 .... 0 .... 0110 .... 00011011 @r_p_2 +pssubu_db 1111010 .... 0 .... 0110 .... 00011011 @r_p_2 +paadd_db 1001110 .... 0 .... 0110 .... 00011011 @r_p_2 +paaddu_db 1011110 .... 0 .... 0110 .... 00011011 @r_p_2 +pasub_db 1101110 .... 0 .... 0110 .... 00011011 @r_p_2 +pasubu_db 1111110 .... 0 .... 0110 .... 00011011 @r_p_2 +pabd_db 1100110 .... 0 .... 0110 .... 00011011 @r_p_2 +pabdu_db 1110110 .... 0 .... 0110 .... 00011011 @r_p_2 +psabs_db 0110010 00111 .... 0110 .... 00011011 @r2_p +pli_dh 0011000 .......... 010 .... 00011011 @p_l2_p +plui_dh 0111000 .......... 010 .... 00011011 @p_l3_p +padd_dh 1000000 .... 0 .... 0110 .... 00011011 @r_p_2 +psub_dh 1100000 .... 0 .... 0110 .... 00011011 @r_p_2 +psadd_dh 1001000 .... 0 .... 0110 .... 00011011 @r_p_2 +psaddu_dh 1011000 .... 0 .... 0110 .... 00011011 @r_p_2 +pssub_dh 1101000 .... 0 .... 0110 .... 00011011 @r_p_2 +pssubu_dh 1111000 .... 0 .... 0110 .... 00011011 @r_p_2 +paadd_dh 1001100 .... 0 .... 0110 .... 00011011 @r_p_2 +paaddu_dh 1011100 .... 0 .... 0110 .... 00011011 @r_p_2 +pasub_dh 1101100 .... 0 .... 0110 .... 00011011 @r_p_2 +pasubu_dh 1111100 .... 0 .... 0110 .... 00011011 @r_p_2 +psh1add_dh 1010000 .... 1 .... 0110 .... 00011011 @r_p_2 +pssh1sadd_dh 1011000 .... 1 .... 0110 .... 00011011 @r_p_2 +pas_dhx 1000000 .... 1 .... 1110 .... 00011011 @r_p_2 +psa_dhx 1000010 .... 1 .... 1110 .... 00011011 @r_p_2 +psas_dhx 1001000 .... 1 .... 1110 .... 00011011 @r_p_2 +pssa_dhx 1001010 .... 1 .... 1110 .... 00011011 @r_p_2 +paas_dhx 1001100 .... 1 .... 1110 .... 00011011 @r_p_2 +pasa_dhx 1001110 .... 1 .... 1110 .... 00011011 @r_p_2 +pabd_dh 1100100 .... 0 .... 0110 .... 00011011 @r_p_2 +pabdu_dh 1110100 .... 0 .... 0110 .... 00011011 @r_p_2 +psabs_dh 0110000 00111 .... 0110 .... 00011011 @r2_p +padd_dw 1000001 .... 0 .... 0110 .... 00011011 @r_p_2 +psub_dw 1100001 .... 0 .... 0110 .... 00011011 @r_p_2 +psadd_dw 1001001 .... 0 .... 0110 .... 00011011 @r_p_2 +psaddu_dw 1011001 .... 0 .... 0110 .... 00011011 @r_p_2 +pssub_dw 1101001 .... 0 .... 0110 .... 00011011 @r_p_2 +pssubu_dw 1111001 .... 0 .... 0110 .... 00011011 @r_p_2 +paadd_dw 1001101 .... 0 .... 0110 .... 00011011 @r_p_2 +paaddu_dw 1011101 .... 0 .... 0110 .... 00011011 @r_p_2 +pasub_dw 1101101 .... 0 .... 0110 .... 00011011 @r_p_2 +pasubu_dw 1111101 .... 0 .... 0110 .... 00011011 @r_p_2 +psh1add_dw 1010001 .... 1 .... 0110 .... 00011011 @r_p_2 +pssh1sadd_dw 1011001 .... 1 .... 0110 .... 00011011 @r_p_2 +addd_p 1000011 .... 0 .... 0110 .... 00011011 @r_p_2 +subd_p 1100011 .... 0 .... 0110 .... 00011011 @r_p_2 + +# register-pair first source only +predsum_dbs 0001110 ..... .... 0100 ..... 0011011 @r_p_4 +predsumu_dbs 0011110 ..... .... 0100 ..... 0011011 @r_p_4 +predsum_dhs 0001100 ..... .... 0100 ..... 0011011 @r_p_4 +predsumu_dhs 0011100 ..... .... 0100 ..... 0011011 @r_p_4 + +# register-pair operands +pslli_db 00000 0001... .... 0110 .... 00011011 @p_ui8_p +psrli_db 00000 0001... .... 1110 .... 00011011 @p_ui8_p +psrai_db 01000 0001... .... 1110 .... 00011011 @p_ui8_p +pmin_db 1110010 .... 1 .... 1110 .... 00011011 @r_p_2 +pminu_db 1110110 .... 1 .... 1110 .... 00011011 @r_p_2 +pmax_db 1111010 .... 1 .... 1110 .... 00011011 @r_p_2 +pmaxu_db 1111110 .... 1 .... 1110 .... 00011011 @r_p_2 +pmseq_db 1100010 .... 1 .... 1110 .... 00011011 @r_p_2 +pmslt_db 1101010 .... 1 .... 1110 .... 00011011 @r_p_2 +pmsltu_db 1101110 .... 1 .... 1110 .... 00011011 @r_p_2 +psext_dh_b 0110000 00100 .... 0110 .... 00011011 @r2_p +psati_dh 01100 001.... .... 1110 .... 00011011 @p_ui16_p_2 +pusati_dh 00100 001.... .... 1110 .... 00011011 @p_ui16_p_2 +pslli_dh 00000 001.... .... 0110 .... 00011011 @p_ui16_p_2 +psrli_dh 00000 001.... .... 1110 .... 00011011 @p_ui16_p_2 +psrai_dh 01000 001.... .... 1110 .... 00011011 @p_ui16_p_2 +psslai_dh 01010 001.... .... 0110 .... 00011011 @p_ui16_p_2 +psrari_dh 01010 001.... .... 1110 .... 00011011 @p_ui16_p_2 +pmin_dh 1110000 .... 1 .... 1110 .... 00011011 @r_p_2 +pminu_dh 1110100 .... 1 .... 1110 .... 00011011 @r_p_2 +pmax_dh 1111000 .... 1 .... 1110 .... 00011011 @r_p_2 +pmaxu_dh 1111100 .... 1 .... 1110 .... 00011011 @r_p_2 +pmseq_dh 1100000 .... 1 .... 1110 .... 00011011 @r_p_2 +pmslt_dh 1101000 .... 1 .... 1110 .... 00011011 @r_p_2 +pmsltu_dh 1101100 .... 1 .... 1110 .... 00011011 @r_p_2 +psext_dw_b 0110001 00100 .... 0110 .... 00011011 @r2_p +psext_dw_h 0110001 00101 .... 0110 .... 00011011 @r2_p +psati_dw 01100 01..... .... 1110 .... 00011011 @p_ui32_p_2 +pusati_dw 00100 01..... .... 1110 .... 00011011 @p_ui32_p_2 +pslli_dw 00000 01..... .... 0110 .... 00011011 @p_ui32_p_2 +psrli_dw 00000 01..... .... 1110 .... 00011011 @p_ui32_p_2 +psrai_dw 01000 01..... .... 1110 .... 00011011 @p_ui32_p_2 +psslai_dw 01010 01..... .... 0110 .... 00011011 @p_ui32_p_2 +psrari_dw 01010 01..... .... 1110 .... 00011011 @p_ui32_p_2 +pmin_dw 1110001 .... 1 .... 1110 .... 00011011 @r_p_2 +pminu_dw 1110101 .... 1 .... 1110 .... 00011011 @r_p_2 +pmax_dw 1111001 .... 1 .... 1110 .... 00011011 @r_p_2 +pmaxu_dw 1111101 .... 1 .... 1110 .... 00011011 @r_p_2 +pmseq_dw 1100001 .... 1 .... 1110 .... 00011011 @r_p_2 +pmslt_dw 1101001 .... 1 .... 1110 .... 00011011 @r_p_2 +pmsltu_dw 1101101 .... 1 .... 1110 .... 00011011 @r_p_2 + +# register-pair first source and dest +padd_dbs 0001110 ..... .... 0110 .... 00011011 @r_p_3 +psll_dbs 0000110 ..... .... 0110 .... 00011011 @r_p_3 +psrl_dbs 0000110 ..... .... 1110 .... 00011011 @r_p_3 +psra_dbs 0100110 ..... .... 1110 .... 00011011 @r_p_3 +padd_dhs 0001100 ..... .... 0110 .... 00011011 @r_p_3 +psll_dhs 0000100 ..... .... 0110 .... 00011011 @r_p_3 +psrl_dhs 0000100 ..... .... 1110 .... 00011011 @r_p_3 +psra_dhs 0100100 ..... .... 1110 .... 00011011 @r_p_3 +pssha_dhs 0110100 ..... .... 0110 .... 00011011 @r_p_3 +psshar_dhs 0111100 ..... .... 0110 .... 00011011 @r_p_3 +psshl_dhs 0010100 ..... .... 0110 .... 00011011 @r_p_3 +psshlr_dhs 0011100 ..... .... 0110 .... 00011011 @r_p_3 +padd_dws 0001101 ..... .... 0110 .... 00011011 @r_p_3 +psll_dws 0000101 ..... .... 0110 .... 00011011 @r_p_3 +psrl_dws 0000101 ..... .... 1110 .... 00011011 @r_p_3 +psra_dws 0100101 ..... .... 1110 .... 00011011 @r_p_3 +pssha_dws 0110101 ..... .... 0110 .... 00011011 @r_p_3 +psshar_dws 0111101 ..... .... 0110 .... 00011011 @r_p_3 +psshl_dws 0010101 ..... .... 0110 .... 00011011 @r_p_3 +psshlr_dws 0011101 ..... .... 0110 .... 00011011 @r_p_3 + +# register-pair operands +ppaire_db 1000000 .... 0 .... 1110 .... 00011011 @r_p_2 +ppaireo_db 1001000 .... 0 .... 1110 .... 00011011 @r_p_2 +ppairoe_db 1010000 .... 0 .... 1110 .... 00011011 @r_p_2 +ppairo_db 1011000 .... 0 .... 1110 .... 00011011 @r_p_2 +ppaire_dh 1000001 .... 0 .... 1110 .... 00011011 @r_p_2 +ppaireo_dh 1001001 .... 0 .... 1110 .... 00011011 @r_p_2 +ppairoe_dh 1010001 .... 0 .... 1110 .... 00011011 @r_p_2 +ppairo_dh 1011001 .... 0 .... 1110 .... 00011011 @r_p_2 + +#register-pair first source only +pnsrli_b 00000 001.... .... 1100 ..... 0011011 @p_ui16_p_3 +pnsrai_b 01000 001.... .... 1100 ..... 0011011 @p_ui16_p_3 +pnsrari_b 01010 001.... .... 1100 ..... 0011011 @p_ui16_p_3 +pnclipi_b 01100 001.... .... 1100 ..... 0011011 @p_ui16_p_3 +pnclipri_b 01110 001.... .... 1100 ..... 0011011 @p_ui16_p_3 +pnclipiu_b 00100 001.... .... 1100 ..... 0011011 @p_ui16_p_3 +pnclipriu_b 00110 001.... .... 1100 ..... 0011011 @p_ui16_p_3 +pnsrl_bs 00001 00 ..... .... 1100 ..... 0011011 @r_p_4 +pnsra_bs 01001 00 ..... .... 1100 ..... 0011011 @r_p_4 +pnsrar_bs 01011 00 ..... .... 1100 ..... 0011011 @r_p_4 +pnclip_bs 01101 00 ..... .... 1100 ..... 0011011 @r_p_4 +pnclipr_bs 01111 00 ..... .... 1100 ..... 0011011 @r_p_4 +pnclipu_bs 00101 00 ..... .... 1100 ..... 0011011 @r_p_4 +pnclipru_bs 00111 00 ..... .... 1100 ..... 0011011 @r_p_4 + +pnsrli_h 00000 01..... .... 1100 ..... 0011011 @p_ui32_p_3 +pnsrai_h 01000 01..... .... 1100 ..... 0011011 @p_ui32_p_3 +pnsrari_h 01010 01..... .... 1100 ..... 0011011 @p_ui32_p_3 +pnclipi_h 01100 01..... .... 1100 ..... 0011011 @p_ui32_p_3 +pnclipri_h 01110 01..... .... 1100 ..... 0011011 @p_ui32_p_3 +pnclipiu_h 00100 01..... .... 1100 ..... 0011011 @p_ui32_p_3 +pnclipriu_h 00110 01..... .... 1100 ..... 0011011 @p_ui32_p_3 +pnsrl_hs 00001 01 ..... .... 1100 ..... 0011011 @r_p_4 +pnsra_hs 01001 01 ..... .... 1100 ..... 0011011 @r_p_4 +pnsrar_hs 01011 01 ..... .... 1100 ..... 0011011 @r_p_4 +pnclip_hs 01101 01 ..... .... 1100 ..... 0011011 @r_p_4 +pnclipr_hs 01111 01 ..... .... 1100 ..... 0011011 @r_p_4 +pnclipu_hs 00101 01 ..... .... 1100 ..... 0011011 @r_p_4 +pnclipru_hs 00111 01 ..... .... 1100 ..... 0011011 @r_p_4 + +nsrli 00000 1...... .... 1100 ..... 0011011 @p_ui64_p_2 +nsrai 01000 1...... .... 1100 ..... 0011011 @p_ui64_p_2 +nsrari 01010 1...... .... 1100 ..... 0011011 @p_ui64_p_2 +nclipi 01100 1...... .... 1100 ..... 0011011 @p_ui64_p_2 +nclipri 01110 1...... .... 1100 ..... 0011011 @p_ui64_p_2 +nclipiu 00100 1...... .... 1100 ..... 0011011 @p_ui64_p_2 +nclipriu 00110 1...... .... 1100 ..... 0011011 @p_ui64_p_2 +nsrl 00001 11 ..... .... 1100 ..... 0011011 @r_p_4 +nsra 01001 11 ..... .... 1100 ..... 0011011 @r_p_4 +nsrar 01011 11 ..... .... 1100 ..... 0011011 @r_p_4 +nclip 01101 11 ..... .... 1100 ..... 0011011 @r_p_4 +nclipr 01111 11 ..... .... 1100 ..... 0011011 @r_p_4 +nclipu 00101 11 ..... .... 1100 ..... 0011011 @r_p_4 +nclipru 00111 11 ..... .... 1100 ..... 0011011 @r_p_4 + +# register-pair multiply +pmqwacc_h 01111 00 ..... ..... 010 .... 10011011 @r_p_1 +pmqrwacc_h 01111 10 ..... ..... 010 .... 10011011 @r_p_1 +mqwacc 01111 01 ..... ..... 010 .... 10011011 @r_p_1 +mqrwacc 01111 11 ..... ..... 010 .... 10011011 @r_p_1 + +pwmul_b 00100 10 ..... ..... 010 .... 10011011 @r_p_1 +pwmulsu_b 01100 10 ..... ..... 010 .... 10011011 @r_p_1 +pwmulu_b 00110 10 ..... ..... 010 .... 10011011 @r_p_1 + +pwmul_h 00100 00 ..... ..... 010 .... 10011011 @r_p_1 +pwmulsu_h 01100 00 ..... ..... 010 .... 10011011 @r_p_1 +pwmulu_h 00110 00 ..... ..... 010 .... 10011011 @r_p_1 +pwmacc_h 00101 00 ..... ..... 010 .... 10011011 @r_p_1 +pwmaccsu_h 01101 00 ..... ..... 010 .... 10011011 @r_p_1 +pwmaccu_h 00111 00 ..... ..... 010 .... 10011011 @r_p_1 + +wmul 00100 01 ..... ..... 010 .... 10011011 @r_p_1 +wmulsu 01100 01 ..... ..... 010 .... 10011011 @r_p_1 +wmulu 00110 01 ..... ..... 010 .... 10011011 @r_p_1 +wmacc 00101 01 ..... ..... 010 .... 10011011 @r_p_1 +wmaccsu 01101 01 ..... ..... 010 .... 10011011 @r_p_1 +wmaccu 00111 01 ..... ..... 010 .... 10011011 @r_p_1 + +pm2wadd_h 00000 11 ..... ..... 010 .... 10011011 @r_p_1 +pm2waddsu_h 01100 11 ..... ..... 010 .... 10011011 @r_p_1 +pm2waddu_h 00100 11 ..... ..... 010 .... 10011011 @r_p_1 +pm2wadd_hx 00010 11 ..... ..... 010 .... 10011011 @r_p_1 + +pm2wadda_h 00001 11 ..... ..... 010 .... 10011011 @r_p_1 +pm2waddasu_h 01101 11 ..... ..... 010 .... 10011011 @r_p_1 +pm2waddau_h 00101 11 ..... ..... 010 .... 10011011 @r_p_1 +pm2wadda_hx 00011 11 ..... ..... 010 .... 10011011 @r_p_1 + +pm2wsub_h 01000 11 ..... ..... 010 .... 10011011 @r_p_1 +pm2wsub_hx 01010 11 ..... ..... 010 .... 10011011 @r_p_1 +pm2wsuba_h 01001 11 ..... ..... 010 .... 10011011 @r_p_1 +pm2wsuba_hx 01011 11 ..... ..... 010 .... 10011011 @r_p_1 diff --git a/target/riscv/tcg/insn_trans/trans_rvp.c.inc b/target/riscv/tcg= /insn_trans/trans_rvp.c.inc index c172c8e4e0a..bec44e98f7c 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -2,6 +2,50 @@ /* RISC-V translation routines for the P Standard Extensions. */ /* Copyright (c) 2026 ISRC ISCAS. */ =20 +/* + * A zero register-pair selector denotes { x0, x0 }, rather than { x1, x0 = }. + */ +static int pair_reg(int pair, bool high) +{ + return pair =3D=3D 0 ? 0 : pair * 2 + high; +} + +/* Save a 64 bit value in the register pair selected by pair. */ +static void set_pair_regs(DisasContext *ctx, int pair, TCGv_i64 src) +{ +#if defined(TARGET_RISCV32) + if (pair =3D=3D 0) { + return; + } + + TCGv_i64 tl_64 =3D tcg_temp_new_i64(); + TCGv_i64 th_64 =3D tcg_temp_new_i64(); + TCGv_i32 tl_32 =3D tcg_temp_new_i32(); + TCGv_i32 th_32 =3D tcg_temp_new_i32(); + tcg_gen_extract_i64(tl_64, src, 0, 32); + tcg_gen_extract_i64(th_64, src, 32, 32); + tcg_gen_trunc_i64_tl(tl_32, tl_64); + tcg_gen_trunc_i64_tl(th_32, th_64); + gen_set_gpr(ctx, pair_reg(pair, false), tl_32); + gen_set_gpr(ctx, pair_reg(pair, true), th_32); +# else + gen_set_gpr(ctx, pair_reg(pair, false), src); +#endif +} + +/* Concatenate the two registers selected by pair into dst. */ +static void get_pair_regs(DisasContext *ctx, TCGv_i64 dst, int pair) +{ +#if defined(TARGET_RISCV32) + TCGv t1 =3D get_gpr(ctx, pair_reg(pair, false), EXT_NONE); + TCGv t2 =3D get_gpr(ctx, pair_reg(pair, true), EXT_NONE); + tcg_gen_concat_i32_i64(dst, t1, t2); +#else + TCGv t1 =3D get_gpr(ctx, pair_reg(pair, false), EXT_NONE); + tcg_gen_mov_tl(dst, t1); +#endif +} + static bool require_rvp(DisasContext *ctx) { uint32_t opcode =3D ctx->opcode & 0x7f; @@ -925,6 +969,241 @@ GEN_SIMD_TRANS_ACC_64(pm4adda_h) GEN_SIMD_TRANS_ACC_64(pm4addasu_h) GEN_SIMD_TRANS_ACC_64(pm4addau_h) =20 +/* Packed SIMD - Double-Width Operations (RV32 only, register pairs) */ +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pwadd_b) +GEN_SIMD_TRANS_REG_PAIR_ACC(pwadda_b) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pwaddu_b) +GEN_SIMD_TRANS_REG_PAIR_ACC(pwaddau_b) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pwsub_b) +GEN_SIMD_TRANS_REG_PAIR_ACC(pwsuba_b) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pwsubu_b) +GEN_SIMD_TRANS_REG_PAIR_ACC(pwsubau_b) +GEN_SIMD_TRANS_REG_PAIR_SCALAR_IMM(pwslli_b) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pwsll_bs) +GEN_SIMD_TRANS_REG_PAIR_SCALAR_IMM(pwslai_b) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pwsla_bs) + +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pwadd_h) +GEN_SIMD_TRANS_REG_PAIR_ACC(pwadda_h) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pwaddu_h) +GEN_SIMD_TRANS_REG_PAIR_ACC(pwaddau_h) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pwsub_h) +GEN_SIMD_TRANS_REG_PAIR_ACC(pwsuba_h) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pwsubu_h) +GEN_SIMD_TRANS_REG_PAIR_ACC(pwsubau_h) +GEN_SIMD_TRANS_REG_PAIR_SCALAR_IMM(pwslli_h) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pwsll_hs) +GEN_SIMD_TRANS_REG_PAIR_SCALAR_IMM(pwslai_h) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pwsla_hs) + +GEN_SIMD_TRANS_REG_PAIR_SCALAR(wadd) +GEN_SIMD_TRANS_REG_PAIR_ACC(wadda) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(waddu) +GEN_SIMD_TRANS_REG_PAIR_ACC(waddau) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(wsub) +GEN_SIMD_TRANS_REG_PAIR_ACC(wsuba) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(wsubu) +GEN_SIMD_TRANS_REG_PAIR_ACC(wsubau) + +GEN_SIMD_TRANS_REG_PAIR_SCALAR_IMM(wslli) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(wsll) +GEN_SIMD_TRANS_REG_PAIR_SCALAR_IMM(wslai) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(wsla) + +GEN_SIMD_TRANS_REG_PAIR_LANE(padd_db, padd_b) +GEN_SIMD_TRANS_REG_PAIR_LANE(psub_db, psub_b) +GEN_SIMD_TRANS_REG_PAIR_LANE_VXSAT(psadd_db, psadd_b) +GEN_SIMD_TRANS_REG_PAIR_LANE_VXSAT(psaddu_db, psaddu_b) +GEN_SIMD_TRANS_REG_PAIR_LANE_VXSAT(pssub_db, pssub_b) +GEN_SIMD_TRANS_REG_PAIR_LANE_VXSAT(pssubu_db, pssubu_b) +GEN_SIMD_TRANS_REG_PAIR_LANE(paadd_db, paadd_b) +GEN_SIMD_TRANS_REG_PAIR_LANE(paaddu_db, paaddu_b) +GEN_SIMD_TRANS_REG_PAIR_LANE(pasub_db, pasub_b) +GEN_SIMD_TRANS_REG_PAIR_LANE(pasubu_db, pasubu_b) +GEN_SIMD_TRANS_REG_PAIR_LANE(pabd_db, pabd_b) +GEN_SIMD_TRANS_REG_PAIR_LANE(pabdu_db, pabdu_b) +GEN_SIMD_TRANS_REG_PAIR_LANE_UNARY_VXSAT(psabs_db, psabs_b) +GEN_SIMD_TRANS_REG_PAIR_LANE(padd_dh, padd_h) +GEN_SIMD_TRANS_REG_PAIR_LANE(psub_dh, psub_h) +GEN_SIMD_TRANS_REG_PAIR_LANE_VXSAT(psadd_dh, psadd_h) +GEN_SIMD_TRANS_REG_PAIR_LANE_VXSAT(psaddu_dh, psaddu_h) +GEN_SIMD_TRANS_REG_PAIR_LANE_VXSAT(pssub_dh, pssub_h) +GEN_SIMD_TRANS_REG_PAIR_LANE_VXSAT(pssubu_dh, pssubu_h) +GEN_SIMD_TRANS_REG_PAIR_LANE(paadd_dh, paadd_h) +GEN_SIMD_TRANS_REG_PAIR_LANE(paaddu_dh, paaddu_h) +GEN_SIMD_TRANS_REG_PAIR_LANE(pasub_dh, pasub_h) +GEN_SIMD_TRANS_REG_PAIR_LANE(pasubu_dh, pasubu_h) +GEN_SIMD_TRANS_REG_PAIR_LANE(psh1add_dh, psh1add_h) +GEN_SIMD_TRANS_REG_PAIR_LANE_VXSAT(pssh1sadd_dh, pssh1sadd_h) +GEN_SIMD_TRANS_REG_PAIR_LANE(pas_dhx, pas_hx) +GEN_SIMD_TRANS_REG_PAIR_LANE(psa_dhx, psa_hx) +GEN_SIMD_TRANS_REG_PAIR_LANE_VXSAT(psas_dhx, psas_hx) +GEN_SIMD_TRANS_REG_PAIR_LANE_VXSAT(pssa_dhx, pssa_hx) +GEN_SIMD_TRANS_REG_PAIR_LANE(paas_dhx, paas_hx) +GEN_SIMD_TRANS_REG_PAIR_LANE(pasa_dhx, pasa_hx) +GEN_SIMD_TRANS_REG_PAIR_LANE(pabd_dh, pabd_h) +GEN_SIMD_TRANS_REG_PAIR_LANE(pabdu_dh, pabdu_h) +GEN_SIMD_TRANS_REG_PAIR_LANE_UNARY_VXSAT(psabs_dh, psabs_h) +GEN_SIMD_TRANS_REG_PAIR_LANE_VXSAT(psadd_dw, sadd) +GEN_SIMD_TRANS_REG_PAIR_LANE_VXSAT(psaddu_dw, saddu) +GEN_SIMD_TRANS_REG_PAIR_LANE_VXSAT(pssub_dw, ssub) +GEN_SIMD_TRANS_REG_PAIR_LANE_VXSAT(pssubu_dw, ssubu) +GEN_SIMD_TRANS_REG_PAIR_LANE(paadd_dw, aadd) +GEN_SIMD_TRANS_REG_PAIR_LANE(paaddu_dw, aaddu) +GEN_SIMD_TRANS_REG_PAIR_LANE(pasub_dw, asub) +GEN_SIMD_TRANS_REG_PAIR_LANE(pasubu_dw, asubu) +GEN_SIMD_TRANS_REG_PAIR_LANE_VXSAT(pssh1sadd_dw, ssh1sadd) + +GEN_SIMD_TRANS_REG_PAIR_LANE_IMM(pslli_db, pslli_b) +GEN_SIMD_TRANS_REG_PAIR_LANE_IMM(psrli_db, psrli_b) +GEN_SIMD_TRANS_REG_PAIR_LANE_IMM(psrai_db, psrai_b) +GEN_SIMD_TRANS_REG_PAIR_LANE(pmin_db, pmin_b) +GEN_SIMD_TRANS_REG_PAIR_LANE(pminu_db, pminu_b) +GEN_SIMD_TRANS_REG_PAIR_LANE(pmax_db, pmax_b) +GEN_SIMD_TRANS_REG_PAIR_LANE(pmaxu_db, pmaxu_b) +GEN_SIMD_TRANS_REG_PAIR_LANE(pmseq_db, pmseq_b) +GEN_SIMD_TRANS_REG_PAIR_LANE(pmslt_db, pmslt_b) +GEN_SIMD_TRANS_REG_PAIR_LANE(pmsltu_db, pmsltu_b) +GEN_SIMD_TRANS_REG_PAIR_LANE_UNARY(psext_dh_b, psext_h_b) +GEN_SIMD_TRANS_REG_PAIR_LANE_IMM_VXSAT(psati_dh, psati_h) +GEN_SIMD_TRANS_REG_PAIR_LANE_IMM_VXSAT(pusati_dh, pusati_h) +GEN_SIMD_TRANS_REG_PAIR_LANE_IMM(pslli_dh, pslli_h) +GEN_SIMD_TRANS_REG_PAIR_LANE_IMM(psrli_dh, psrli_h) +GEN_SIMD_TRANS_REG_PAIR_LANE_IMM(psrai_dh, psrai_h) +GEN_SIMD_TRANS_REG_PAIR_LANE_IMM_VXSAT(psslai_dh, psslai_h) +GEN_SIMD_TRANS_REG_PAIR_LANE_IMM(psrari_dh, psrari_h) +GEN_SIMD_TRANS_REG_PAIR_LANE(pmin_dh, pmin_h) +GEN_SIMD_TRANS_REG_PAIR_LANE(pminu_dh, pminu_h) +GEN_SIMD_TRANS_REG_PAIR_LANE(pmax_dh, pmax_h) +GEN_SIMD_TRANS_REG_PAIR_LANE(pmaxu_dh, pmaxu_h) +GEN_SIMD_TRANS_REG_PAIR_LANE(pmseq_dh, pmseq_h) +GEN_SIMD_TRANS_REG_PAIR_LANE(pmslt_dh, pmslt_h) +GEN_SIMD_TRANS_REG_PAIR_LANE(pmsltu_dh, pmsltu_h) +GEN_SIMD_TRANS_REG_PAIR_LANE_IMM_VXSAT(psati_dw, sati_32) +GEN_SIMD_TRANS_REG_PAIR_LANE_IMM_VXSAT(pusati_dw, usati_32) +GEN_SIMD_TRANS_REG_PAIR_LANE_IMM_VXSAT(psslai_dw, sslai) +GEN_SIMD_TRANS_REG_PAIR_LANE_IMM(psrari_dw, srari_32) +GEN_SIMD_TRANS_REG_PAIR_LANE(pmseq_dw, mseq) +GEN_SIMD_TRANS_REG_PAIR_LANE(pmslt_dw, mslt) +GEN_SIMD_TRANS_REG_PAIR_LANE(pmsltu_dw, msltu) + +GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR(padd_dbs, padd_bs) +GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR(psll_dbs, psll_bs) +GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR(psrl_dbs, psrl_bs) +GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR(psra_dbs, psra_bs) +GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR(padd_dhs, padd_hs) +GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR(psll_dhs, psll_hs) +GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR(psrl_dhs, psrl_hs) +GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR(psra_dhs, psra_hs) +GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR_VXSAT(pssha_dhs, pssha_hs) +GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR_VXSAT(psshar_dhs, psshar_hs) +GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR_VXSAT(psshl_dhs, psshl_hs) +GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR_VXSAT(psshlr_dhs, psshlr_hs) +GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR_VXSAT(pssha_dws, ssha) +GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR_VXSAT(psshar_dws, sshar) +GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR_VXSAT(psshl_dws, sshl) +GEN_SIMD_TRANS_REG_PAIR_LANE_SCALAR_VXSAT(psshlr_dws, sshlr) + +GEN_SIMD_TRANS_REG_PAIR_LANE(ppairo_db, ppairo_b) +GEN_SIMD_TRANS_REG_PAIR_LANE(ppairo_dh, ppairo_h) +GEN_SIMD_TRANS_REG_PAIR_LANE(ppaire_db, ppaire_b) +GEN_SIMD_TRANS_REG_PAIR_LANE(ppaireo_db, ppaireo_b) +GEN_SIMD_TRANS_REG_PAIR_LANE(ppaireo_dh, ppaireo_h) +GEN_SIMD_TRANS_REG_PAIR_LANE(ppairoe_dh, ppairoe_h) +GEN_SIMD_TRANS_REG_PAIR_LANE(ppairoe_db, ppairoe_b) + +GEN_SIMD_TRANS_REG_PAIR_PREDSUM(predsum_dbs) +GEN_SIMD_TRANS_REG_PAIR_PREDSUM(predsumu_dbs) +GEN_SIMD_TRANS_REG_PAIR_PREDSUM(predsum_dhs) +GEN_SIMD_TRANS_REG_PAIR_PREDSUM(predsumu_dhs) + +GEN_SIMD_TRANS_PN_OP_IMM(pnsrli_b) +GEN_SIMD_TRANS_PN_OP_IMM(pnsrai_b) +GEN_SIMD_TRANS_PN_OP_IMM(pnsrari_b) +GEN_SIMD_TRANS_PN_OP_IMM_VXSAT(pnclipi_b) +GEN_SIMD_TRANS_PN_OP_IMM_VXSAT(pnclipri_b) +GEN_SIMD_TRANS_PN_OP_IMM_VXSAT(pnclipiu_b) +GEN_SIMD_TRANS_PN_OP_IMM_VXSAT(pnclipriu_b) + +GEN_SIMD_TRANS_PN_OP_IMM(pnsrli_h) +GEN_SIMD_TRANS_PN_OP_IMM(pnsrai_h) +GEN_SIMD_TRANS_PN_OP_IMM(pnsrari_h) +GEN_SIMD_TRANS_PN_OP_IMM_VXSAT(pnclipi_h) +GEN_SIMD_TRANS_PN_OP_IMM_VXSAT(pnclipri_h) +GEN_SIMD_TRANS_PN_OP_IMM_VXSAT(pnclipiu_h) +GEN_SIMD_TRANS_PN_OP_IMM_VXSAT(pnclipriu_h) + +GEN_SIMD_TRANS_PN_OP_IMM(nsrli) +GEN_SIMD_TRANS_PN_OP_IMM(nsrai) +GEN_SIMD_TRANS_PN_OP_IMM(nsrari) +GEN_SIMD_TRANS_PN_OP_IMM_VXSAT(nclipi) +GEN_SIMD_TRANS_PN_OP_IMM_VXSAT(nclipri) +GEN_SIMD_TRANS_PN_OP_IMM_VXSAT(nclipiu) +GEN_SIMD_TRANS_PN_OP_IMM_VXSAT(nclipriu) + +GEN_SIMD_TRANS_PN_OP_REG(pnsrl_bs) +GEN_SIMD_TRANS_PN_OP_REG(pnsra_bs) +GEN_SIMD_TRANS_PN_OP_REG(pnsrar_bs) +GEN_SIMD_TRANS_PN_OP_REG_VXSAT(pnclip_bs) +GEN_SIMD_TRANS_PN_OP_REG_VXSAT(pnclipr_bs) +GEN_SIMD_TRANS_PN_OP_REG_VXSAT(pnclipu_bs) +GEN_SIMD_TRANS_PN_OP_REG_VXSAT(pnclipru_bs) + +GEN_SIMD_TRANS_PN_OP_REG(pnsrl_hs) +GEN_SIMD_TRANS_PN_OP_REG(pnsra_hs) +GEN_SIMD_TRANS_PN_OP_REG(pnsrar_hs) +GEN_SIMD_TRANS_PN_OP_REG_VXSAT(pnclip_hs) +GEN_SIMD_TRANS_PN_OP_REG_VXSAT(pnclipr_hs) +GEN_SIMD_TRANS_PN_OP_REG_VXSAT(pnclipu_hs) +GEN_SIMD_TRANS_PN_OP_REG_VXSAT(pnclipru_hs) + +GEN_SIMD_TRANS_PN_OP_REG(nsrl) +GEN_SIMD_TRANS_PN_OP_REG(nsra) +GEN_SIMD_TRANS_PN_OP_REG(nsrar) +GEN_SIMD_TRANS_PN_OP_REG_VXSAT(nclip) +GEN_SIMD_TRANS_PN_OP_REG_VXSAT(nclipr) +GEN_SIMD_TRANS_PN_OP_REG_VXSAT(nclipu) +GEN_SIMD_TRANS_PN_OP_REG_VXSAT(nclipru) + +GEN_SIMD_TRANS_REG_PAIR_ACC(pmqwacc_h) +GEN_SIMD_TRANS_REG_PAIR_ACC(pmqrwacc_h) +GEN_SIMD_TRANS_REG_PAIR_ACC(mqwacc) +GEN_SIMD_TRANS_REG_PAIR_ACC(mqrwacc) + +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pwmul_b) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pwmulsu_b) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pwmulu_b) + +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pwmul_h) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pwmulsu_h) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pwmulu_h) +GEN_SIMD_TRANS_REG_PAIR_ACC(pwmacc_h) +GEN_SIMD_TRANS_REG_PAIR_ACC(pwmaccsu_h) +GEN_SIMD_TRANS_REG_PAIR_ACC(pwmaccu_h) + +GEN_SIMD_TRANS_REG_PAIR_SCALAR(wmul) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(wmulsu) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(wmulu) + +GEN_SIMD_TRANS_REG_PAIR_ACC(wmacc) +GEN_SIMD_TRANS_REG_PAIR_ACC(wmaccsu) +GEN_SIMD_TRANS_REG_PAIR_ACC(wmaccu) + +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pm2wadd_h) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pm2waddsu_h) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pm2waddu_h) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pm2wadd_hx) + +GEN_SIMD_TRANS_REG_PAIR_ACC(pm2wadda_h) +GEN_SIMD_TRANS_REG_PAIR_ACC(pm2waddasu_h) +GEN_SIMD_TRANS_REG_PAIR_ACC(pm2waddau_h) +GEN_SIMD_TRANS_REG_PAIR_ACC(pm2wadda_hx) + +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pm2wsub_h) +GEN_SIMD_TRANS_REG_PAIR_SCALAR(pm2wsub_hx) +GEN_SIMD_TRANS_REG_PAIR_ACC(pm2wsuba_h) +GEN_SIMD_TRANS_REG_PAIR_ACC(pm2wsuba_hx) + #define GEN_PLI(NAME, PRE_REQ, IMM_TYPE, LIMIT, SHIFT, ADDEND) \ static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ { \ @@ -940,6 +1219,21 @@ static bool trans_##NAME(DisasContext *ctx, arg_##NAM= E * a) \ return true; \ } =20 +#define GEN_PLI_D(NAME, IMM_TYPE, LIMIT, SHIFT, ADDEND) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_RVP(ctx); \ + int i =3D 1; \ + IMM_TYPE imm =3D a->imm; \ + while (i < (LIMIT)) { \ + imm =3D (imm << (SHIFT)) + (ADDEND); \ + i++; \ + } \ + gen_set_gpri(ctx, pair_reg(a->rd, false), imm); \ + gen_set_gpri(ctx, pair_reg(a->rd, true), imm); \ + return true; \ +} + GEN_PLI(pli_b, , target_long, TARGET_LONG_SIZE, 8, a->imm) GEN_PLI(pli_h, , target_long, TARGET_LONG_SIZE / 2, 16, a->imm & 0xFFFF) @@ -949,3 +1243,197 @@ GEN_PLI(pli_w, REQUIRE_64BIT(ctx); , int64_t, TARGET= _LONG_SIZE / 4, 32, a->imm & 0xFFFFFFFF) GEN_PLI(plui_w, REQUIRE_64BIT(ctx); , int64_t, TARGET_LONG_SIZE / 4, 32, a->imm & 0xFFFFFFFF) +GEN_PLI_D(pli_db, target_long, TARGET_LONG_SIZE, 8, a->imm) +GEN_PLI_D(pli_dh, target_long, TARGET_LONG_SIZE / 2, 16, + a->imm & 0xFFFF) +GEN_PLI_D(plui_dh, target_long, TARGET_LONG_SIZE / 2, 16, + a->imm & 0xFFFF) + +#define GEN_DW_LANE_BINOP(NAME, OP) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + REQUIRE_RVP(ctx); \ + TCGv src1_0 =3D get_gpr(ctx, pair_reg(a->rs1, false), EXT_NONE); \ + TCGv src2_0 =3D get_gpr(ctx, pair_reg(a->rs2, false), EXT_NONE); \ + TCGv dest_0 =3D dest_gpr(ctx, pair_reg(a->rd, false)); \ + TCGv src1_1 =3D get_gpr(ctx, pair_reg(a->rs1, true), EXT_NONE); \ + TCGv src2_1 =3D get_gpr(ctx, pair_reg(a->rs2, true), EXT_NONE); \ + TCGv dest_1 =3D dest_gpr(ctx, pair_reg(a->rd, true)); \ + OP(dest_0, src1_0, src2_0); \ + OP(dest_1, src1_1, src2_1); \ + gen_set_gpr(ctx, pair_reg(a->rd, false), dest_0); \ + gen_set_gpr(ctx, pair_reg(a->rd, true), dest_1); \ + return true; \ +} + +GEN_DW_LANE_BINOP(padd_dw, tcg_gen_add_tl) +GEN_DW_LANE_BINOP(psub_dw, tcg_gen_sub_tl) +GEN_DW_LANE_BINOP(psh1add_dw, gen_sh1add) + +/* Verify rd is not zero register for wzip8p and wzip16p. */ +#if defined(TARGET_RISCV32) +#define GEN_WZIP_P(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + REQUIRE_RVP(ctx); \ + TCGv_i32 src1 =3D get_gpr(ctx, a->rs1, EXT_NONE); \ + TCGv_i32 src2 =3D get_gpr(ctx, a->rs2, EXT_NONE); \ + TCGv_i64 t =3D tcg_temp_new_i64(); \ + if (a->rd =3D=3D 0) { \ + return true; \ + } else { \ + get_pair_regs(ctx, t, a->rd); \ + } \ + gen_helper_##NAME(t, tcg_env, src1, src2); \ + set_pair_regs(ctx, a->rd, t); \ + return true; \ +} +#else +#define GEN_WZIP_P(NAME) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + return true; \ +} +#endif + +GEN_WZIP_P(wzip8p) +GEN_WZIP_P(wzip16p) + +#define GEN_PAIR_I64_BINOP(NAME, OP) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + REQUIRE_RVP(ctx); \ + TCGv_i64 src1 =3D tcg_temp_new_i64(); \ + TCGv_i64 src2 =3D tcg_temp_new_i64(); \ + TCGv_i64 dest =3D tcg_temp_new_i64(); \ + get_pair_regs(ctx, src1, a->rs1); \ + get_pair_regs(ctx, src2, a->rs2); \ + get_pair_regs(ctx, dest, a->rd); \ + OP(dest, src1, src2); \ + set_pair_regs(ctx, a->rd, dest); \ + return true; \ +} + +GEN_PAIR_I64_BINOP(addd_p, tcg_gen_add_i64) +GEN_PAIR_I64_BINOP(subd_p, tcg_gen_sub_i64) + +#define GEN_DW_EXT(NAME, OP) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + REQUIRE_RVP(ctx); \ + TCGv dest_0 =3D dest_gpr(ctx, pair_reg(a->rd, false)); \ + TCGv src1_0 =3D get_gpr(ctx, pair_reg(a->rs1, false), EXT_NONE); \ + TCGv dest_1 =3D dest_gpr(ctx, pair_reg(a->rd, true)); \ + TCGv src1_1 =3D get_gpr(ctx, pair_reg(a->rs1, true), EXT_NONE); \ + OP(dest_0, src1_0); \ + gen_set_gpr(ctx, pair_reg(a->rd, false), dest_0); \ + OP(dest_1, src1_1); \ + gen_set_gpr(ctx, pair_reg(a->rd, true), dest_1); \ + return true; \ +} + +GEN_DW_EXT(psext_dw_b, tcg_gen_ext8s_tl) +GEN_DW_EXT(psext_dw_h, tcg_gen_ext16s_tl) + +#define GEN_DW_SHIFT_IMM(NAME, OP) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + REQUIRE_RVP(ctx); \ + arg_shift a0, a1; \ + a0.rd =3D pair_reg(a->rd, false); \ + a0.rs1 =3D pair_reg(a->rs1, false); \ + a0.shamt =3D a->imm; \ + a1.rd =3D pair_reg(a->rd, true); \ + a1.rs1 =3D pair_reg(a->rs1, true); \ + a1.shamt =3D a->imm; \ + gen_shift_imm_fn(ctx, &a0, EXT_NONE, OP, NULL); \ + gen_shift_imm_fn(ctx, &a1, EXT_NONE, OP, NULL); \ + return true; \ +} + +#define GEN_DW_SHIFT_IMM_PER_OL(NAME, OP, OP_OL) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + REQUIRE_RVP(ctx); \ + arg_shift a0, a1; \ + a0.rd =3D pair_reg(a->rd, false); \ + a0.rs1 =3D pair_reg(a->rs1, false); \ + a0.shamt =3D a->imm; \ + a1.rd =3D pair_reg(a->rd, true); \ + a1.rs1 =3D pair_reg(a->rs1, true); \ + a1.shamt =3D a->imm; \ + gen_shift_imm_fn_per_ol(ctx, &a0, EXT_NONE, OP, OP_OL, NULL); \ + gen_shift_imm_fn_per_ol(ctx, &a1, EXT_NONE, OP, OP_OL, NULL); \ + return true; \ +} + +GEN_DW_SHIFT_IMM(pslli_dw, tcg_gen_shli_tl) +GEN_DW_SHIFT_IMM_PER_OL(psrli_dw, tcg_gen_shri_tl, gen_srliw) +GEN_DW_SHIFT_IMM_PER_OL(psrai_dw, tcg_gen_sari_tl, gen_sraiw) + +#define GEN_DW_PAIR_ARITH(NAME, EXTRA_REQ, EXT, OP) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + REQUIRE_RVP(ctx); \ + EXTRA_REQ \ + arg_r a0, a1; \ + a0.rd =3D pair_reg(a->rd, false); \ + a0.rs1 =3D pair_reg(a->rs1, false); \ + a0.rs2 =3D pair_reg(a->rs2, false); \ + a1.rd =3D pair_reg(a->rd, true); \ + a1.rs1 =3D pair_reg(a->rs1, true); \ + a1.rs2 =3D pair_reg(a->rs2, true); \ + gen_arith(ctx, &a0, EXT, OP, NULL); \ + gen_arith(ctx, &a1, EXT, OP, NULL); \ + return true; \ +} + +GEN_DW_PAIR_ARITH(pmin_dw, REQUIRE_ZBB(ctx); , EXT_SIGN, tcg_gen_smin_tl) +GEN_DW_PAIR_ARITH(pminu_dw, REQUIRE_ZBB(ctx); , EXT_SIGN, tcg_gen_umin_tl) +GEN_DW_PAIR_ARITH(pmax_dw, REQUIRE_ZBB(ctx); , EXT_SIGN, tcg_gen_smax_tl) +GEN_DW_PAIR_ARITH(pmaxu_dw, REQUIRE_ZBB(ctx); , EXT_SIGN, tcg_gen_umax_tl) + +#define GEN_DWS_REG_OP(NAME, EXT, MASK_SHIFT, OP) \ +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ +{ \ + REQUIRE_32BIT(ctx); \ + REQUIRE_RVP(ctx); \ + TCGv src1_0; \ + TCGv src1_1; \ + if (a->rs1 =3D=3D 0) { \ + src1_0 =3D tcg_constant_tl(0); \ + src1_1 =3D tcg_constant_tl(0); \ + } else { \ + src1_0 =3D get_gpr(ctx, pair_reg(a->rs1, false), EXT); \ + src1_1 =3D get_gpr(ctx, pair_reg(a->rs1, true), EXT); \ + } \ + TCGv src2 =3D tcg_temp_new(); \ + tcg_gen_mov_tl(src2, get_gpr(ctx, a->rs2, EXT_NONE)); \ + if (MASK_SHIFT) { \ + tcg_gen_andi_tl(src2, src2, 31); \ + } \ + TCGv dest_0 =3D tcg_temp_new(); \ + TCGv dest_1 =3D tcg_temp_new(); \ + OP(dest_0, src1_0, src2); \ + OP(dest_1, src1_1, src2); \ + if (a->rd !=3D 0) { \ + gen_set_gpr(ctx, pair_reg(a->rd, false), dest_0); \ + gen_set_gpr(ctx, pair_reg(a->rd, true), dest_1); \ + } \ + return true; \ +} + +GEN_DWS_REG_OP(padd_dws, EXT_NONE, false, tcg_gen_add_tl) +GEN_DWS_REG_OP(psll_dws, EXT_NONE, true, tcg_gen_shl_tl) +GEN_DWS_REG_OP(psrl_dws, EXT_ZERO, true, tcg_gen_shr_tl) +GEN_DWS_REG_OP(psra_dws, EXT_SIGN, true, tcg_gen_sar_tl) + +GEN_DW_PAIR_ARITH(ppaire_dh, REQUIRE_ZBKB(ctx); , EXT_NONE, gen_pack) diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helpe= r.c index 94eb68776aa..5e6ee7926a0 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -3261,3 +3261,276 @@ GEN_PSIMD_4WAY_MUL_ACC(pm4addasu_h, uint64_t, int16= _t, uint16_t, GEN_PSIMD_4WAY_MUL_ACC(pm4addau_h, uint64_t, uint16_t, uint16_t, uint64_t, uint64_t, uint64_t, EXTRACT16, EXTRACT64, INSERT64, ELEMS_D, 0, PSIMD_MUL_U64) + +/* Double-Width Operations (RV32 only, register pairs) */ + +GEN_PSIMD_WIDEN_BINOP(pwadd_b, int8_t, int16_t, uint16_t, + 4, 8, 16, 0xFF, PSIMD_COMB_ADD) +GEN_PSIMD_WIDEN_BINOP_ACC(pwadda_b, int8_t, int16_t, uint16_t, + 4, 8, 16, 0xFF, 0xFFFF, PSIMD_COMB_ADD) +GEN_PSIMD_WIDEN_BINOP(pwaddu_b, uint8_t, uint16_t, uint16_t, + 4, 8, 16, 0xFF, PSIMD_COMB_ADD) +GEN_PSIMD_WIDEN_BINOP_ACC(pwaddau_b, uint8_t, uint16_t, uint16_t, + 4, 8, 16, 0xFF, 0xFFFF, PSIMD_COMB_ADD) +GEN_PSIMD_WIDEN_BINOP(pwsub_b, int8_t, int16_t, uint16_t, + 4, 8, 16, 0xFF, PSIMD_COMB_SUB) +GEN_PSIMD_WIDEN_BINOP_ACC(pwsuba_b, int8_t, int16_t, uint16_t, + 4, 8, 16, 0xFF, 0xFFFF, PSIMD_COMB_SUB) +GEN_PSIMD_WIDEN_BINOP(pwsubu_b, uint8_t, uint16_t, uint16_t, + 4, 8, 16, 0xFF, PSIMD_COMB_SUB) +GEN_PSIMD_WIDEN_BINOP_ACC(pwsubau_b, uint8_t, uint16_t, uint16_t, + 4, 8, 16, 0xFF, 0xFFFF, PSIMD_COMB_SUB) + +GEN_PSIMD_WIDEN_SHIFT(pwslli_b, uint8_t, uint16_t, uint16_t, + 4, 8, 16, 0xFF, 0x0F) +GEN_PSIMD_WIDEN_SHIFT(pwsll_bs, uint8_t, uint16_t, uint16_t, + 4, 8, 16, 0xFF, 0x1F) +GEN_PSIMD_WIDEN_SHIFT(pwslai_b, int8_t, int16_t, uint16_t, + 4, 8, 16, 0xFF, 0x0F) +GEN_PSIMD_WIDEN_SHIFT(pwsla_bs, int8_t, int16_t, uint16_t, + 4, 8, 16, 0xFF, 0x1F) + +GEN_PSIMD_WIDEN_BINOP(pwadd_h, int16_t, int32_t, uint32_t, + 2, 16, 32, 0xFFFF, PSIMD_COMB_ADD) +GEN_PSIMD_WIDEN_BINOP_ACC(pwadda_h, int16_t, int32_t, uint32_t, + 2, 16, 32, 0xFFFF, 0xFFFFFFFFULL, + PSIMD_COMB_ADD) +GEN_PSIMD_WIDEN_BINOP(pwaddu_h, uint16_t, uint32_t, uint32_t, + 2, 16, 32, 0xFFFF, PSIMD_COMB_ADD) +GEN_PSIMD_WIDEN_BINOP_ACC(pwaddau_h, uint16_t, uint32_t, uint32_t, + 2, 16, 32, 0xFFFF, 0xFFFFFFFFULL, + PSIMD_COMB_ADD) +GEN_PSIMD_WIDEN_BINOP(pwsub_h, int16_t, int32_t, uint32_t, + 2, 16, 32, 0xFFFF, PSIMD_COMB_SUB) +GEN_PSIMD_WIDEN_BINOP_ACC(pwsuba_h, int16_t, int32_t, uint32_t, + 2, 16, 32, 0xFFFF, 0xFFFFFFFFULL, + PSIMD_COMB_SUB) +GEN_PSIMD_WIDEN_BINOP(pwsubu_h, uint16_t, uint32_t, uint32_t, + 2, 16, 32, 0xFFFF, PSIMD_COMB_SUB) +GEN_PSIMD_WIDEN_BINOP_ACC(pwsubau_h, uint16_t, uint32_t, uint32_t, + 2, 16, 32, 0xFFFF, 0xFFFFFFFFULL, + PSIMD_COMB_SUB) + +GEN_PSIMD_WIDEN_SHIFT(pwslli_h, uint16_t, uint32_t, uint32_t, + 2, 16, 32, 0xFFFF, 0x1F) +GEN_PSIMD_WIDEN_SHIFT(pwsll_hs, uint16_t, uint32_t, uint32_t, + 2, 16, 32, 0xFFFF, 0x1F) +GEN_PSIMD_WIDEN_SHIFT(pwslai_h, int16_t, int32_t, uint32_t, + 2, 16, 32, 0xFFFF, 0x1F) +GEN_PSIMD_WIDEN_SHIFT(pwsla_hs, int16_t, int32_t, uint32_t, + 2, 16, 32, 0xFFFF, 0x1F) + +GEN_PSIMD_WIDEN_BINOP(wadd, int32_t, int64_t, uint64_t, + 1, 32, 64, 0xFFFFFFFF, PSIMD_COMB_ADD) +GEN_PSIMD_WIDEN_BINOP_ACC(wadda, int32_t, int64_t, uint64_t, + 1, 32, 64, 0xFFFFFFFF, 0xFFFFFFFFFFFFFFFFULL, + PSIMD_COMB_ADD) +GEN_PSIMD_WIDEN_BINOP(waddu, uint32_t, uint64_t, uint64_t, + 1, 32, 64, 0xFFFFFFFF, PSIMD_COMB_ADD) +GEN_PSIMD_WIDEN_BINOP_ACC(waddau, uint32_t, uint64_t, uint64_t, + 1, 32, 64, 0xFFFFFFFF, 0xFFFFFFFFFFFFFFFFULL, + PSIMD_COMB_ADD) +GEN_PSIMD_WIDEN_BINOP(wsub, int32_t, int64_t, uint64_t, + 1, 32, 64, 0xFFFFFFFF, PSIMD_COMB_SUB) +GEN_PSIMD_WIDEN_BINOP_ACC(wsuba, int32_t, int64_t, uint64_t, + 1, 32, 64, 0xFFFFFFFF, 0xFFFFFFFFFFFFFFFFULL, + PSIMD_COMB_SUB) +GEN_PSIMD_WIDEN_BINOP(wsubu, uint32_t, uint64_t, uint64_t, + 1, 32, 64, 0xFFFFFFFF, PSIMD_COMB_SUB) +GEN_PSIMD_WIDEN_BINOP_ACC(wsubau, uint32_t, uint64_t, uint64_t, + 1, 32, 64, 0xFFFFFFFF, 0xFFFFFFFFFFFFFFFFULL, + PSIMD_COMB_SUB) + +GEN_PSIMD_WIDEN_SHIFT(wslli, uint32_t, uint64_t, uint64_t, + 1, 32, 64, 0xFFFFFFFF, 0x3F) +GEN_PSIMD_WIDEN_SHIFT(wsll, uint32_t, uint64_t, uint64_t, + 1, 32, 64, 0xFFFFFFFF, 0x3F) +GEN_PSIMD_WIDEN_SHIFT(wslai, int32_t, int64_t, uint64_t, + 1, 32, 64, 0xFFFFFFFF, 0x3F) +GEN_PSIMD_WIDEN_SHIFT(wsla, int32_t, int64_t, uint64_t, + 1, 32, 64, 0xFFFFFFFF, 0x3F) + +GEN_PSIMD_DW_ZIP(wzip8p, EXTRACT8, 4, 16, 8) +GEN_PSIMD_DW_ZIP(wzip16p, EXTRACT16, 2, 32, 16) + +GEN_PSIMD_DW_REDSUM(predsum_dbs, int64_t, int32_t, int8_t, EXTRACT8, 8) +GEN_PSIMD_DW_REDSUM(predsumu_dbs, uint64_t, uint32_t, uint8_t, EXTRACT8, 8) +GEN_PSIMD_DW_REDSUM(predsum_dhs, int64_t, int32_t, int16_t, EXTRACT16, 4) +GEN_PSIMD_DW_REDSUM(predsumu_dhs, uint64_t, uint32_t, uint16_t, EXTRACT16,= 4) + + +/* Narrowing Operations (RV32 only, register pair sources) */ + +GEN_PSIMD_NARROW_SRL(pnsrli_b, uint16_t, uint8_t, + 4, 16, 8, 0xFFFF, 0x0F) +GEN_PSIMD_NARROW_SRL(pnsrl_bs, uint16_t, uint8_t, + 4, 16, 8, 0xFFFF, 0x1F) +GEN_PSIMD_NARROW_SRA_PACK(pnsrai_b, int16_t, int32_t, uint8_t, + 4, 16, 8, 0xFFFF, 0x0F) +GEN_PSIMD_NARROW_SRA_PACK(pnsra_bs, int16_t, int32_t, uint8_t, + 4, 16, 8, 0xFFFF, 0x1F) +GEN_PSIMD_NARROW_RNDSRA_PACK(pnsrari_b, int16_t, int32_t, uint8_t, + 4, 16, 8, 0xFFFF, 0x0F, 0x1FF) +GEN_PSIMD_NARROW_RNDSRA_PACK(pnsrar_bs, int16_t, int32_t, uint8_t, + 4, 16, 8, 0xFFFF, 0x1F, 0x1FF) +GEN_PSIMD_NCLIP_SIGNED_PACK(pnclipi_b, int16_t, int32_t, int16_t, + uint8_t, 4, 16, 8, 0xFFFF, 0x0F, + -128, 127, 0x80, 0x7F) +GEN_PSIMD_NCLIPR_SIGNED_PACK(pnclipri_b, int16_t, int32_t, int16_t, + uint8_t, 4, 16, 8, 0xFFFF, 0x0F, 0x1FFFF, + -128, 127, 0x80, 0x7F) +GEN_PSIMD_NCLIP_UNSIGNED_PACK(pnclipiu_b, uint16_t, uint16_t, uint8_t, + 4, 16, 8, 0xFFFF, 0x0F, 0x00FF) +GEN_PSIMD_NCLIPR_UNSIGNED_PACK(pnclipriu_b, uint16_t, uint32_t, uint8_t, + 4, 16, 8, 0xFFFF, 0x0F, 0x00FF) +GEN_PSIMD_NCLIP_SIGNED_PACK(pnclip_bs, int16_t, int32_t, int16_t, + uint8_t, 4, 16, 8, 0xFFFF, 0x1F, + -128, 127, 0x80, 0x7F) +GEN_PSIMD_NCLIPR_SIGNED_PACK(pnclipr_bs, int16_t, int32_t, int16_t, + uint8_t, 4, 16, 8, 0xFFFF, 0x1F, 0x1FFFF, + -128, 127, 0x80, 0x7F) +GEN_PSIMD_NCLIP_UNSIGNED_PACK(pnclipu_bs, uint16_t, uint32_t, uint8_t, + 4, 16, 8, 0xFFFF, 0x1F, 0x00FF) +GEN_PSIMD_NCLIPR_UNSIGNED_PACK(pnclipru_bs, uint16_t, uint64_t, uint8_t, + 4, 16, 8, 0xFFFF, 0x1F, 0x00FF) + +GEN_PSIMD_NARROW_SRL(pnsrli_h, uint32_t, uint16_t, + 2, 32, 16, 0xFFFFFFFFULL, 0x1F) +GEN_PSIMD_NARROW_SRA_PACK(pnsrai_h, int32_t, int64_t, uint16_t, + 2, 32, 16, 0xFFFFFFFFULL, 0x1F) +GEN_PSIMD_NARROW_RNDSRA_PACK(pnsrari_h, int32_t, int64_t, uint16_t, + 2, 32, 16, 0xFFFFFFFFULL, 0x1F, 0x1FFFF) + +GEN_PSIMD_NARROW_SRL(pnsrl_hs, uint32_t, uint16_t, + 2, 32, 16, 0xFFFFFFFFULL, 0x1F) + +GEN_PSIMD_NARROW_ALIAS(pnsra_hs, pnsrai_h) +GEN_PSIMD_NARROW_ALIAS(pnsrar_hs, pnsrari_h) + +GEN_PSIMD_NCLIP_SIGNED_PACK(pnclip_hs, int32_t, int64_t, int32_t, + uint16_t, 2, 32, 16, 0xFFFFFFFFULL, 0x1F, + -32768, 32767, 0x8000, 0x7FFF) +GEN_PSIMD_NCLIPR_SIGNED_PACK(pnclipr_hs, int32_t, int64_t, int32_t, + uint16_t, 2, 32, 16, 0xFFFFFFFFULL, 0x1F, + 0x1FFFFFFFF, -32768, 32767, 0x8000, 0x7FFF) + +GEN_PSIMD_NARROW_ALIAS(pnclipi_h, pnclip_hs) +GEN_PSIMD_NARROW_ALIAS(pnclipri_h, pnclipr_hs) + +GEN_PSIMD_NCLIP_UNSIGNED_PACK(pnclipu_hs, uint32_t, uint32_t, uint16_t, + 2, 32, 16, 0xFFFFFFFFULL, 0x1F, 0xFFFF) +GEN_PSIMD_NCLIPR_UNSIGNED_PACK(pnclipru_hs, uint32_t, uint64_t, uint16_t, + 2, 32, 16, 0xFFFFFFFFULL, 0x1F, 0xFFFF) + +GEN_PSIMD_NARROW_ALIAS(pnclipiu_h, pnclipu_hs) +GEN_PSIMD_NARROW_ALIAS(pnclipriu_h, pnclipru_hs) + +GEN_PSIMD_NARROW_SRL(nsrli, uint64_t, uint32_t, + 1, 64, 32, 0xFFFFFFFFFFFFFFFFULL, 0x3F) + +GEN_PSIMD_NARROW_SRA(nsrai) +GEN_PSIMD_NARROW_RNDSRA(nsrari) + +GEN_PSIMD_NARROW_SRL(nsrl, uint64_t, uint32_t, + 1, 64, 32, 0xFFFFFFFFFFFFFFFFULL, 0x3F) + +GEN_PSIMD_NARROW_SRA(nsra) +GEN_PSIMD_NARROW_RNDSRA(nsrar) + +GEN_PSIMD_NCLIP(nclipi) +GEN_PSIMD_NCLIPR(nclipri) +GEN_PSIMD_NCLIPU(nclipiu) +GEN_PSIMD_NCLIPRU(nclipriu) + +GEN_PSIMD_NCLIP(nclip) +GEN_PSIMD_NCLIPR(nclipr) +GEN_PSIMD_NCLIPU(nclipu) +GEN_PSIMD_NCLIPRU(nclipru) + +/* Multiplication with Even-Odd Register Pairs as Destination (RV32 only) = */ + +GEN_PSIMD_WIDEN_QMUL_ACC(pmqwacc_h, int16_t, int32_t, int64_t, + int32_t, uint32_t, 2, EXTRACT16, EXTRACT32, + 1, 0, 15, 0, 32, PSIMD_MUL_S64) +GEN_PSIMD_WIDEN_QMUL_ACC(pmqrwacc_h, int16_t, int32_t, int64_t, + int32_t, uint32_t, 2, EXTRACT16, EXTRACT32, + 1, 0, 15, 1LL << 14, 32, PSIMD_MUL_S64) + +GEN_PSIMD_WIDEN_MUL(pwmul_b, int8_t, int8_t, int16_t, uint16_t, + 4, EXTRACT8, 16, PSIMD_MUL_S32) +GEN_PSIMD_WIDEN_MUL(pwmulsu_b, int8_t, uint8_t, int16_t, uint16_t, + 4, EXTRACT8, 16, PSIMD_MUL_SU16) +GEN_PSIMD_WIDEN_MUL(pwmulu_b, uint8_t, uint8_t, uint16_t, uint16_t, + 4, EXTRACT8, 16, PSIMD_MUL_U32) +GEN_PSIMD_WIDEN_MUL(pwmul_h, int16_t, int16_t, int32_t, uint32_t, + 2, EXTRACT16, 32, PSIMD_MUL_S32) +GEN_PSIMD_WIDEN_MUL(pwmulsu_h, int16_t, uint16_t, int32_t, uint32_t, + 2, EXTRACT16, 32, PSIMD_MUL_SU32) +GEN_PSIMD_WIDEN_MUL(pwmulu_h, uint16_t, uint16_t, uint32_t, uint32_t, + 2, EXTRACT16, 32, PSIMD_MUL_U32) + +GEN_PSIMD_WIDEN_MUL_ACC(pwmacc_h, int16_t, int16_t, int32_t, + int32_t, uint32_t, 2, EXTRACT16, EXTRACT32, 32, + PSIMD_MUL_S32) +GEN_PSIMD_WIDEN_MUL_ACC(pwmaccsu_h, int16_t, uint16_t, int32_t, + int32_t, uint32_t, 2, EXTRACT16, EXTRACT32, 32, + PSIMD_MUL_SU32) +GEN_PSIMD_WIDEN_MUL_ACC(pwmaccu_h, uint16_t, uint16_t, uint32_t, + uint32_t, uint32_t, 2, EXTRACT16, EXTRACT32, 32, + PSIMD_MUL_U32) + +GEN_PSIMD_WIDEN_QMUL_ACC(mqwacc, int32_t, int64_t, int64_t, + int64_t, uint64_t, 1, EXTRACT32, EXTRACT64, + 0, 0, 31, 0, 64, PSIMD_MUL_S64) +GEN_PSIMD_WIDEN_QMUL_ACC(mqrwacc, int32_t, int64_t, int64_t, + int64_t, uint64_t, 1, EXTRACT32, EXTRACT64, + 0, 0, 31, 1LL << 30, 64, PSIMD_MUL_S64) + +GEN_PSIMD_WIDEN_MUL(wmul, int32_t, int32_t, int64_t, uint64_t, + 1, EXTRACT32, 64, PSIMD_MUL_S64) +GEN_PSIMD_WIDEN_MUL(wmulsu, int32_t, uint32_t, int64_t, uint64_t, + 1, EXTRACT32, 64, PSIMD_MUL_SU64) +GEN_PSIMD_WIDEN_MUL(wmulu, uint32_t, uint32_t, uint64_t, uint64_t, + 1, EXTRACT32, 64, PSIMD_MUL_U64) + +GEN_PSIMD_WIDEN_MUL_ACC(wmacc, int32_t, int32_t, int64_t, + int64_t, uint64_t, 1, EXTRACT32, EXTRACT64, 64, + PSIMD_MUL_S64) +GEN_PSIMD_WIDEN_MUL_ACC(wmaccsu, int32_t, uint32_t, int64_t, + int64_t, uint64_t, 1, EXTRACT32, EXTRACT64, 64, + PSIMD_MUL_SU64) +GEN_PSIMD_WIDEN_MUL_ACC(wmaccu, uint32_t, uint32_t, uint64_t, + uint64_t, uint64_t, 1, EXTRACT32, EXTRACT64, 64, + PSIMD_MUL_U64) + +GEN_PSIMD_DW_2WAY_MUL(pm2wadd_h, int16_t, int16_t, int64_t, + EXTRACT16, 0, 1, 0, 1, PSIMD_MUL_S64, PSIMD_COMB_ADD) +GEN_PSIMD_DW_2WAY_MUL(pm2waddsu_h, int16_t, uint16_t, int64_t, + EXTRACT16, 0, 1, 0, 1, PSIMD_MUL_SU64, + PSIMD_COMB_ADD) +GEN_PSIMD_DW_2WAY_MUL(pm2waddu_h, uint16_t, uint16_t, uint64_t, + EXTRACT16, 0, 1, 0, 1, PSIMD_MUL_U64, PSIMD_COMB_ADD) +GEN_PSIMD_DW_2WAY_MUL_ACC(pm2wadda_h, int16_t, int16_t, int64_t, int64_t, + EXTRACT16, 0, 1, 0, 1, PSIMD_MUL_S64, + PSIMD_COMB_ADD) +GEN_PSIMD_DW_2WAY_MUL_ACC(pm2waddasu_h, int16_t, uint16_t, int64_t, + int64_t, EXTRACT16, 0, 1, 0, 1, PSIMD_MUL_SU64, + PSIMD_COMB_ADD) +GEN_PSIMD_DW_2WAY_MUL_ACC(pm2waddau_h, uint16_t, uint16_t, uint64_t, + uint64_t, EXTRACT16, 0, 1, 0, 1, PSIMD_MUL_U64, + PSIMD_COMB_ADD) +GEN_PSIMD_DW_2WAY_MUL(pm2wadd_hx, int16_t, int16_t, int64_t, + EXTRACT16, 0, 1, 1, 0, PSIMD_MUL_S64, PSIMD_COMB_ADD) +GEN_PSIMD_DW_2WAY_MUL_ACC(pm2wadda_hx, int16_t, int16_t, int64_t, int64_t, + EXTRACT16, 0, 1, 1, 0, PSIMD_MUL_S64, + PSIMD_COMB_ADD) +GEN_PSIMD_DW_2WAY_MUL(pm2wsub_h, int16_t, int16_t, int64_t, + EXTRACT16, 0, 1, 0, 1, PSIMD_MUL_S64, PSIMD_COMB_SUB) +GEN_PSIMD_DW_2WAY_MUL(pm2wsub_hx, int16_t, int16_t, int64_t, + EXTRACT16, 0, 1, 1, 0, PSIMD_MUL_S64, PSIMD_COMB_SUB) +GEN_PSIMD_DW_2WAY_MUL_ACC(pm2wsuba_h, int16_t, int16_t, int64_t, int64_t, + EXTRACT16, 0, 1, 0, 1, PSIMD_MUL_S64, + PSIMD_COMB_SUB) +GEN_PSIMD_DW_2WAY_MUL_ACC(pm2wsuba_hx, int16_t, int16_t, int64_t, int64_t, + EXTRACT16, 0, 1, 1, 0, PSIMD_MUL_S64, + PSIMD_COMB_SUB) --=20 2.34.1 From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 17895429459441007.5285759261558; Wed, 16 Sep 2026 00:15:45 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jrU-0005n6-7L; Wed, 16 Sep 2026 03:15:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jqv-0005ak-6W; Wed, 16 Sep 2026 03:14:45 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jqs-0000zS-04; Wed, 16 Sep 2026 03:14:44 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S20; Wed, 16 Sep 2026 15:08:05 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 18/19] target/riscv: Remove Zbkb dependency from P extension to align with the spec Date: Wed, 16 Sep 2026 07:07:20 +0000 Message-Id: <20260916070721.3279229-19-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S20 X-Coremail-Antispam: 1UD129KBjvJXoW7tw48Wr4xCryDXrWUWF1rZwb_yoW8tr1xpr 48C3yYkrWDXFyrA3yftF4UAF1UWa1Sga1Iga92qwn5uF45ArW3Xr4q9w43KF1UJF1kWw42 9F1vy3s8uFW8Xa7anT9S1TB71UUUUUJqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUQa14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_Ar0_tr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq 3wAaw2AFwI0_Jrv_JF1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I 8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_JF0_Jw1lYx0Ex4A2jsIE14v26F4j6r4UJwAm72CE 4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7M4 IIrI8v6xkF7I0E8cxan2IY04v7MxkF7I0En4kS14v26r1q6r43MxAIw28IcxkI7VAKI48J MxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwV AFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6xIIjxv2 0xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8Jr0_Cr1UMIIF0xvE42xK8V AvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWxJVW8Jr1lIxAIcVC2z280aVCY1x02 67AKxVW8Jr0_Cr1UYxBIdaVFxhVjvjDU0xZFpf9x0JULSdkUUUUU= X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542946088158500 Content-Type: text/plain; charset="utf-8" Signed-off-by: Molly Chen Reviewed-by: Chao Liu --- target/riscv/tcg/insn_trans/trans_rvb.c.inc | 4 +++- target/riscv/tcg/insn_trans/trans_rvp.c.inc | 2 +- target/riscv/tcg/tcg-cpu.c | 6 ++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/target/riscv/tcg/insn_trans/trans_rvb.c.inc b/target/riscv/tcg= /insn_trans/trans_rvb.c.inc index 3e74be223b0..48bc5df0378 100644 --- a/target/riscv/tcg/insn_trans/trans_rvb.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvb.c.inc @@ -527,7 +527,9 @@ static bool trans_brev8(DisasContext *ctx, arg_brev8 *a) =20 static bool trans_pack(DisasContext *ctx, arg_pack *a) { - REQUIRE_ZBKB(ctx); + if (!has_ext(ctx, RVP) && !ctx->cfg_ptr->ext_zbkb) { + return false; + } return gen_arith(ctx, a, EXT_NONE, gen_pack, NULL); } =20 diff --git a/target/riscv/tcg/insn_trans/trans_rvp.c.inc b/target/riscv/tcg= /insn_trans/trans_rvp.c.inc index bec44e98f7c..8c8c6ba3a6f 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -1436,4 +1436,4 @@ GEN_DWS_REG_OP(psll_dws, EXT_NONE, true, tcg_gen_shl_= tl) GEN_DWS_REG_OP(psrl_dws, EXT_ZERO, true, tcg_gen_shr_tl) GEN_DWS_REG_OP(psra_dws, EXT_SIGN, true, tcg_gen_sar_tl) =20 -GEN_DW_PAIR_ARITH(ppaire_dh, REQUIRE_ZBKB(ctx); , EXT_NONE, gen_pack) +GEN_DW_PAIR_ARITH(ppaire_dh, , EXT_NONE, gen_pack) diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c index 3e72e2ffd7f..4d57192d1e1 100644 --- a/target/riscv/tcg/tcg-cpu.c +++ b/target/riscv/tcg/tcg-cpu.c @@ -562,10 +562,8 @@ static void riscv_cpu_validate_p(RISCVCPU *cpu, Error = **errp) return; } =20 - if (!(cpu->cfg.ext_zmmul && cpu->cfg.ext_zba && cpu->cfg.ext_zbb && - cpu->cfg.ext_zbkb)) { - error_setg(errp, "P extension requires zmmul, zba, zbb and zbkb " - "extensions"); + if (!(cpu->cfg.ext_zmmul && cpu->cfg.ext_zba && cpu->cfg.ext_zbb)) { + error_setg(errp, "P extension requires zmmul, zba and zbb extensio= ns"); return; } } --=20 2.34.1 From nobody Sat Sep 26 20:52:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789542683013555.2546043261476; Wed, 16 Sep 2026 00:11:23 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x6jl8-00066j-K5; Wed, 16 Sep 2026 03:08:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x6jky-0005wP-FB; Wed, 16 Sep 2026 03:08:37 -0400 Received: from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn) by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1x6jks-0008KR-3G; Wed, 16 Sep 2026 03:08:36 -0400 Received: from xiaoou-ubuntu-02.home.arpa (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXaOxHQKpq3zYkCA--.4143S21; Wed, 16 Sep 2026 15:08:06 +0800 (CST) From: Molly Chen To: palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com, daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com, Chao Liu Cc: nutty.liu@hotmail.com, max.chou@sifive.com, xiaoou@iscas.ac.cn, qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 19/19] tests/tcg/riscv: Add tests for the P extension Date: Wed, 16 Sep 2026 07:07:21 +0000 Message-Id: <20260916070721.3279229-20-xiaoou@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> References: <20260916070721.3279229-1-xiaoou@iscas.ac.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXaOxHQKpq3zYkCA--.4143S21 X-Coremail-Antispam: 1UD129KBjvAXoWDKw4xJF13GrWUXFyrtw45Awb_yoW3uFy5Ao W8XrW3JFWfKr48Cw1kAr1UX3WkXw1Iq3ZrKFnxJw4UGayUXr4xXFyDAr1rCa4kK34DXr1Y y34ayF95tw45JF1kn29KB7ZKAUJUUUUr529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUY_7AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r126s0DM28Irc Ia0xkI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l 84ACjcxK6xIIjxv20xvE14v26F1j6w1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4UJV WxJr1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE 3s1ln4kS14v26r1Y6r17M2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c 02F40Ex7xfMcIj6xIIjxv20xvE14v26r126r1DMcIj6I8E87Iv67AKxVWxJVW8Jr1lOx8S 6xCaFVCjc4AY6r1j6r4UM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02 F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GF ylIxAIcVC0I7IYx2IY67AKxVW8JVW5JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4U JwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Cr0_Gr1UMIIF0x vEx4A2jsIEc7CjxVAFwI0_Gr1j6F4UJbIYCTnIWIevJa73UjIFyTuYvjfUoBTYUUUUU X-Originating-IP: [36.110.52.2] X-CM-SenderInfo: 50ld003x6l2u1dvotugofq/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn; helo=cstnet.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.74, HK_RANDOM_FROM=0.999, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1789542684857158500 Content-Type: text/plain; charset="utf-8" Add freestanding RV32 and RV64 packed SIMD assembly tests, shared test macros, and TCG Makefile integration. Use PSIMD_CC to select a P-capable Clang with support for the P v0.21 assembler options. Cover arithmetic, shifts, multiplication, narrowing and saturation, register overlap, zero register-pair operands and vxsat side effects. Include regression cases for oversized rounding right shifts, SHLR rounding overflow and zero register-pair narrowing sources. Signed-off-by: Molly Chen --- tests/tcg/riscv/psimd-common.S | 1105 ++++++++++++++++++++++ tests/tcg/riscv/psimd-rv32.S | 1256 +++++++++++++++++++++++++ tests/tcg/riscv/psimd-rv64.S | 578 ++++++++++++ tests/tcg/riscv/psimd-test-macros.inc | 952 +++++++++++++++++++ tests/tcg/riscv32/Makefile.target | 30 + tests/tcg/riscv64/Makefile.target | 25 + 6 files changed, 3946 insertions(+) create mode 100644 tests/tcg/riscv/psimd-common.S create mode 100644 tests/tcg/riscv/psimd-rv32.S create mode 100644 tests/tcg/riscv/psimd-rv64.S create mode 100644 tests/tcg/riscv/psimd-test-macros.inc create mode 100644 tests/tcg/riscv32/Makefile.target diff --git a/tests/tcg/riscv/psimd-common.S b/tests/tcg/riscv/psimd-common.S new file mode 100644 index 00000000000..61c64305e86 --- /dev/null +++ b/tests/tcg/riscv/psimd-common.S @@ -0,0 +1,1105 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Test cases shared by RV32 and RV64. Included from psimd-rv*.S. */ + +#if __riscv_xlen =3D=3D 32 + /* PLI.B: zero, one, high immediate bits, and a mixed-bit pattern. */ + TEST_PSIMD_LI 1, pli.b, 0xa5, 0xa5a5a5a5 + TEST_PSIMD_LI 1, pli.b, 0, 0 + TEST_PSIMD_LI 1, pli.b, 1, 0x01010101 + TEST_PSIMD_LI 1, pli.b, 0xff, 0xffffffff + TEST_PSIMD_LI 279, pli.h, 0, 0 + TEST_PSIMD_LI 279, pli.h, 1, 0x00010001 + TEST_PSIMD_LI 279, pli.h, 511, 0x01ff01ff + TEST_PSIMD_LI 279, pli.h, -512, 0xfe00fe00 + TEST_PSIMD_LI 280, plui.h, 0, 0 + TEST_PSIMD_LI 280, plui.h, 1, 0x00400040 + TEST_PSIMD_LI 280, plui.h, 511, 0x7fc07fc0 + TEST_PSIMD_LI 280, plui.h, -512, 0x80008000 + + /* PADD.B: distinct lanes, zero, wraparound, and both rd aliases. */ + TEST_PSIMD_RR 2, padd.b, 0x7f120003, 0x7f340007, 0xfe46000a + TEST_PSIMD_RR 2, padd.b, 0, 0, 0 + TEST_PSIMD_RR 2, padd.b, 0x7f80ff00, 0x01010101, 0x80810001 + TEST_PSIMD_RR_RD_RS1 2, padd.b, 0x7f120003, 0x7f340007, \ + 0xfe46000a + TEST_PSIMD_RR_RD_RS2 2, padd.b, 0x7f120003, 0x7f340007, \ + 0xfe46000a + + /* PSADD.B: no saturation, exact bounds, both overflows, and sticky. */ + TEST_PSIMD_RR_VXSAT 3, psadd.b, 0x7f120003, 0x7f340007, \ + 0x7f46000a + TEST_PSIMD_RR_VXSAT_STATE 3, psadd.b, 0x0102fefe, 0x01010101, \ + 0x0203ffff, 0, 0 + TEST_PSIMD_RR_VXSAT_STATE 3, psadd.b, 0x7e7e8181, 0x0101ffff, \ + 0x7f7f8080, 0, 0 + TEST_PSIMD_RR_VXSAT_STATE 3, psadd.b, 0x80808080, 0xffffffff, \ + 0x80808080, 0, 1 + TEST_PSIMD_RR_VXSAT_STATE 3, psadd.b, 0, 0, 0, 1, 1 + + /* PSATI.H width=3D5: exact bounds and values outside both bounds. */ + TEST_PSIMD_RI_VXSAT 4, psati.h, 0x7fff8000, 5, 0x000ffff0 + TEST_PSIMD_RI_VXSAT_STATE 4, psati.h, 0x000ffff0, 5, \ + 0x000ffff0, 0, 0 + TEST_PSIMD_RI_VXSAT_STATE 4, psati.h, 0x0010ffef, 5, \ + 0x000ffff0, 0, 1 + TEST_PSIMD_RI_VXSAT_STATE 4, psati.h, 0x7fff8000, 16, \ + 0x7fff8000, 0, 0 + + /* PMHACC.H: nonzero rd, zero products, and signed-negative inputs. */ + TEST_PSIMD_ACC_RR 5, pmhacc.h, 0x00010002, 0x7fff8000, \ + 0x7fff8001, 0x40004001 + TEST_PSIMD_ACC_RR 5, pmhacc.h, 0x12345678, 0, 0, 0x12345678 + TEST_PSIMD_ACC_RR 5, pmhacc.h, 0, -1, -1, 0 + + /* PPAIRE.B uses a unique value in every source lane. */ + TEST_PSIMD_RR 6, ppaire.b, 0xaabbccdd, 0x33445566, 0x44bb66dd + TEST_PSIMD_RR 6, ppaire.b, 0, 0, 0 + TEST_PSIMD_RR_RD_RS1 6, ppaire.b, 0xaabbccdd, 0x33445566, \ + 0x44bb66dd + TEST_PSIMD_RR_RD_RS2 6, ppaire.b, 0xaabbccdd, 0x33445566, \ + 0x44bb66dd + + /* Signed/unsigned byte comparisons deliberately disagree by lane. */ + TEST_PSIMD_RR_SET 30, pmin.b, 0x807f00ff, 0x7f8000ff, 0x808000ff + TEST_PSIMD_RR_SET 31, pminu.b, 0x807f00ff, 0x7f8000ff, 0x7f7f00ff + TEST_PSIMD_RR_SET 32, pmax.b, 0x807f00ff, 0x7f8000ff, 0x7f7f00ff + TEST_PSIMD_RR_SET 33, pmaxu.b, 0x807f00ff, 0x7f8000ff, 0x808000ff + TEST_PSIMD_RR_SET 34, pmseq.b, 0x807f00ff, 0x7f8000ff, 0x0000ffff, -1 + TEST_PSIMD_RR_SET 35, pmslt.b, 0x807f00ff, 0x7f8000ff, 0xff000000 + TEST_PSIMD_RR_SET 36, pmsltu.b, 0x807f00ff, 0x7f8000ff, 0x00ff0000 + + /* Halfword extrema exercise signed and unsigned ordering. */ + TEST_PSIMD_RR_SET 37, pmin.h, 0x80007fff, 0x7fff8000, 0x80008000 + TEST_PSIMD_RR_SET 38, pminu.h, 0x80007fff, 0x7fff8000, 0x7fff7fff + TEST_PSIMD_RR_SET 39, pmax.h, 0x80007fff, 0x7fff8000, 0x7fff7fff + TEST_PSIMD_RR_SET 40, pmaxu.h, 0x80007fff, 0x7fff8000, 0x80008000 + TEST_PSIMD_RR_SET 41, pmseq.h, 0x80007fff, 0x7fff8000, 0, -1 + TEST_PSIMD_RR_SET 42, pmslt.h, 0x80007fff, 0x7fff8000, 0xffff0000 + TEST_PSIMD_RR_SET 43, pmsltu.h, 0x80007fff, 0x7fff8000, 0x0000ffff + + /* Wrapping subtraction and halfword addition/subtraction. */ + TEST_PSIMD_RR_SET 72, psub.b, 0x0304fefd, 0x0101ff01, 0x0203fffc + TEST_PSIMD_RR_SET 73, padd.h, 0x7fff8000, 0x00018000, 0x80000000 + TEST_PSIMD_RR_SET 74, psub.h, 0x7fff8000, 0x00018000, 0x7ffe0000 + + /* Signed byte saturation: positive and negative overflow. */ + TEST_PSIMD_SAT_RR_SET 75, pssub.b, 0x0304fefd, 0x0101ff01, \ + 0x0203fffc, 0x7f7f7f7f, -1, 0x7f7f7f7f, \ + 0x80808080, 0x01010101, 0x80808080 + + /* Unsigned byte add overflow and subtract underflow. */ + TEST_PSIMD_SAT_RR_SET 76, psaddu.b, 0x0102fefe, 0x01010101, \ + 0x0203ffff, -1, 0x01010101, -1, \ + 0xf0f0f0f0, 0x20202020, -1 + TEST_PSIMD_SAT_RR_SET 77, pssubu.b, 0x0304fefd, 0x01010101, \ + 0x0203fdfc, 0, 0x01010101, 0, \ + 0x000100ff, 0x01020001, 0x000000fe + + /* Halfword signed/unsigned saturated add and subtract. */ + TEST_PSIMD_SAT_RR_SET 78, psadd.h, 0x00010002, 0x00030004, \ + 0x00040006, 0x7fff7fff, 0x00010001, \ + 0x7fff7fff, 0x80008000, -1, 0x80008000 + TEST_PSIMD_SAT_RR_SET 79, psaddu.h, 0x00010002, 0x00030004, \ + 0x00040006, -1, 0x00010001, -1, \ + 0xf000f000, 0x20002000, -1 + TEST_PSIMD_SAT_RR_SET 80, pssub.h, 0x00040006, 0x00010004, \ + 0x00030002, 0x7fff7fff, -1, 0x7fff7fff, \ + 0x80008000, 0x00010001, 0x80008000 + TEST_PSIMD_SAT_RR_SET 81, pssubu.h, 0x00040006, 0x00010004, \ + 0x00030002, 0, 0x00010001, 0, \ + 0x000100ff, 0x00020001, 0x000000fe + + /* Signed/unsigned average add/subtract with distinct byte lanes. */ + TEST_PSIMD_RR_SET 109, paadd.b, 0x7f120003, 0x7f340007, 0x7f230005 + TEST_PSIMD_RR_SET 110, paaddu.b, 0x7f120003, 0x7f340007, 0x7f230005 + TEST_PSIMD_RR_SET 111, pasub.b, 0xffff0000, 0x11110001, 0xf7f700ff + TEST_PSIMD_RR_SET 112, pasubu.b, 0xffff0000, 0x11110001, 0x777700ff + TEST_PSIMD_RR 109, paadd.b, 0x7f7f7f7f, 0x80808080, -1 + TEST_PSIMD_RR 110, paaddu.b, -1, 0x01010101, 0x80808080 + TEST_PSIMD_RR 111, pasub.b, 0x80808080, 0x7f7f7f7f, 0x80808080 + TEST_PSIMD_RR 112, pasubu.b, -1, 0, 0x7f7f7f7f + + /* Halfword average operations exercise signed/unsigned divergence. */ + TEST_PSIMD_RR_SET 113, paadd.h, 0x7f120003, 0x7f340007, 0x7f230005 + TEST_PSIMD_RR_SET 114, paaddu.h, 0x7f120003, 0x7f340007, 0x7f230005 + TEST_PSIMD_RR_SET 115, pasub.h, 0xffff0000, 0x11110001, 0xf777ffff + TEST_PSIMD_RR_SET 116, pasubu.h, 0xffff0000, 0x11110001, 0x7777ffff + TEST_PSIMD_RR 113, paadd.h, 0x7fff7fff, 0x80008000, -1 + TEST_PSIMD_RR 114, paaddu.h, -1, 0x00010001, 0x80008000 + TEST_PSIMD_RR 115, pasub.h, 0x80008000, 0x7fff7fff, 0x80008000 + TEST_PSIMD_RR 116, pasubu.h, -1, 0, 0x7fff7fff + + /* Shift-one add wraps; the signed form saturates and sets vxsat. */ + TEST_PSIMD_RR_SET 117, psh1add.h, 0x07ffffff, 0x80007fff, 0x8ffe7ffd + TEST_PSIMD_SAT_RR_SET 118, pssh1sadd.h, 1, 2, 4, \ + 0x40004000, 0, 0x7fff7fff, \ + 0xc000c000, -1, 0x80008000 + /* Absolute difference: signed and unsigned ordering deliberately diff= er. */ + TEST_PSIMD_RR_SET 146, pabd.b, 0x7f7f01ff, 0x7f70ff7e, \ + 0x000f027f + TEST_PSIMD_RR_SET 147, pabdu.b, 0x807f01ff, 0x7f01fffe, \ + 0x017efe01 + TEST_PSIMD_RR_SET 148, pabd.h, 0x00017fff, 0x00020001, \ + 0x00017ffe + TEST_PSIMD_RR_SET 149, pabdu.h, 0xfffe7fff, 0x00010001, \ + 0xfffd7ffe + + /* Sum of unsigned byte differences, with and without old-rd input. */ + TEST_PSIMD_RR_SET 150, pabdsumu.b, 0x807fffff, 0x7f0101fe, \ + 0x0000017e + TEST_PSIMD_ACC_RR_SET 151, pabdsumau.b, 1, 0x807fffff, \ + 0x7f0101fe, 0x0000017f, 0x8080017d, 0x7f01037c + TEST_PSIMD_ACC_RR 151, pabdsumau.b, 0x12345678, 0, 0, \ + 0x12345678 + + /* Saturating absolute value covers ordinary/minimum lanes and sticky.= */ + TEST_PSIMD_SAT_R_SET 152, psabs.b, 0x7fff0181, 0x7f01017f, \ + 0x80008000, 0x7f007f00 + TEST_PSIMD_SAT_R_SET 153, psabs.h, 0x7fffffff, 0x7fff0001, \ + 0x80000001, 0x7fff0001 + + /* Reduction lanes are unique; signed and unsigned results diverge. */ + TEST_PSIMD_RR_SET 154, predsum.bs, 0x7eff0180, 1, -1 + TEST_PSIMD_RR_SET 155, predsumu.bs, 0x7eff0180, 1, 0x1ff + TEST_PSIMD_RR_SET 156, predsum.hs, 0x00030004, 0xa, 0x11 + TEST_PSIMD_RR_SET 157, predsumu.hs, 0x10008000, 0x1000, 0xa000 + + /* Packed shifts: amount zero/one/maximum, truncation, and signed fill= . */ + TEST_PSIMD_SHIFT_RR_SET 172, psll.bs, 0x807f1201, 0x00fe2402, \ + 7, 0x00800080 + TEST_PSIMD_SHIFT_RR_SET 173, psrl.bs, 0x807f1201, 0x403f0900, \ + 7, 0x01000000 + TEST_PSIMD_SHIFT_RR_SET 174, psra.bs, 0x807f1201, 0xc03f0900, \ + 7, 0xff000000 + TEST_PSIMD_SHIFT_RI_SET 175, pslli.b, 0x807f1201, 0x00fe2402, \ + 7, 0x00800080 + TEST_PSIMD_SHIFT_RI_SET 176, psrli.b, 0x807f1201, 0x403f0900, \ + 7, 0x01000000 + TEST_PSIMD_SHIFT_RI_SET 177, psrai.b, 0x807f1201, 0xc03f0900, \ + 7, 0xff000000 + + TEST_PSIMD_SHIFT_RR_SET 178, psll.hs, 0x80017fff, 0x0002fffe, \ + 15, 0x80008000 + TEST_PSIMD_SHIFT_RR_SET 179, psrl.hs, 0x80017fff, 0x40003fff, \ + 15, 0x00010000 + TEST_PSIMD_SHIFT_RR_SET 180, psra.hs, 0x80017fff, 0xc0003fff, \ + 15, 0xffff0000 + TEST_PSIMD_SHIFT_RI_SET 181, pslli.h, 0x80017fff, 0x0002fffe, \ + 15, 0x80008000 + TEST_PSIMD_SHIFT_RI_SET 182, psrli.h, 0x80017fff, 0x40003fff, \ + 15, 0x00010000 + TEST_PSIMD_SHIFT_RI_SET 183, psrai.h, 0x80017fff, 0xc0003fff, \ + 15, 0xffff0000 + + /* Rounded shifts: odd/even lanes give guard bits one/zero. */ + TEST_PSIMD_SHIFT_RI_SET 208, psrari.h, 0xfffd0002, \ + 0xffff0001, 15, 0 + TEST_PSIMD_RI 208, psrari.h, 0x0003fffc, 1, 0x0002fffe + TEST_PSIMD_SHIFT_RI_SET 209, srari, 0x80000001, \ + 0xc0000001, 31, -1 + TEST_PSIMD_RI 209, srari, 3, 1, 2 + + /* Pair/merge operations use unique bytes to expose every source choic= e. */ + TEST_PSIMD_RR_SET 261, ppaireo.b, 0x11223344, 0xaabbccdd, \ + 0xaa22cc44 + TEST_PSIMD_RR_SET 262, ppairoe.b, 0x11223344, 0xaabbccdd, \ + 0xbb11dd33 + TEST_PSIMD_RR_SET 263, ppairo.b, 0x11223344, 0xaabbccdd, \ + 0xaa11cc33 + TEST_PSIMD_RR_SET 264, ppaireo.h, 0x11223344, 0xaabbccdd, \ + 0xaabb3344 + TEST_PSIMD_RR_SET 265, ppairoe.h, 0x11223344, 0xaabbccdd, \ + 0xccdd1122 + TEST_PSIMD_RR_SET 266, ppairo.h, 0x11223344, 0xaabbccdd, \ + 0xaabb1122 + + TEST_PSIMD_R_SET 283, psext.h.b, 0x007f0080, 0x007fff80 + + /* Mask merge instructions prove that old rd participates bit-for-bit.= */ + TEST_PSIMD_ACC_RR_SET 292, mvm, 0xaaaaaaaa, 0x55555555, \ + 0x0f0ff0f0, 0xa5a55a5a, 0x55555555, 0x05055050 + TEST_PSIMD_ACC_RR 292, mvm, 0xaaaaaaaa, 0x55555555, 0, \ + 0xaaaaaaaa + TEST_PSIMD_ACC_RR_SET 293, mvmn, 0xaaaaaaaa, 0x55555555, \ + 0x0f0ff0f0, 0x5a5aa5a5, 0x55555555, 0x5f5ff5f5 + TEST_PSIMD_ACC_RR 293, mvmn, 0xaaaaaaaa, 0x55555555, -1, \ + 0xaaaaaaaa + TEST_PSIMD_ACC_RR_SET 294, merge, 0xaaaaaaaa, 0x55555555, \ + 0x0f0ff0f0, 0x5f5ff5f5, 0x05055050, 0x5f5ff5f5 + TEST_PSIMD_RR_SET 295, pack, 0x11223344, 0xaabbccdd, \ + 0xccdd3344 + + TEST_PSIMD_R 297, cls, 1, 30 + TEST_PSIMD_R_RD_RS1 297, cls, 1, 30 + TEST_PSIMD_R 297, cls, 0, 31 + TEST_PSIMD_R 297, cls, -1, 31 + TEST_PSIMD_R 297, cls, 0x40000000, 0 + + TEST_PSIMD_RR_SET 298, mseq, 0x80000000, 0x80000000, -1, -1 + TEST_PSIMD_RR_SET 299, mslt, 0x80000000, 0x7fffffff, -1 + TEST_PSIMD_RR_SET 300, msltu, 0x80000000, 0x7fffffff, 0 + + TEST_PSIMD_SAT_RI_SET 313, sati, 5, 15, 15, 16, 15, -17, -16 + TEST_PSIMD_RI_VXSAT_STATE 313, sati, 0x7fffffff, 32, \ + 0x7fffffff, 0, 0 + TEST_PSIMD_SAT_RI_SET 314, pusati.h, 4, 0x000f0000, \ + 0x000f0000, 0x00100010, 0x000f000f, -1, 0 + TEST_PSIMD_RI_VXSAT_STATE 314, pusati.h, 0x7fff0000, 15, \ + 0x7fff0000, 0, 0 + TEST_PSIMD_SAT_RI_SET 315, usati, 4, 15, 15, 16, 15, -1, 0 + TEST_PSIMD_RI_VXSAT_STATE 315, usati, 0x7fffffff, 31, \ + 0x7fffffff, 0, 0 + + TEST_PSIMD_SAT_RI_SET 323, psslai.h, 1, 0x0001ffff, \ + 0x0002fffe, 0x40004000, 0x7fff7fff, \ + 0xbfffbfff, 0x80008000 + TEST_PSIMD_RI_VXSAT_STATE 323, psslai.h, 0, 15, 0, 0, 0 + TEST_PSIMD_SAT_RI_SET 324, sslai, 1, 1, 2, \ + 0x40000000, 0x7fffffff, \ + 0xbfffffff, 0x80000000 + TEST_PSIMD_RI_VXSAT_STATE 324, sslai, 0, 31, 0, 0, 0 + + /* Signed variable shifts: positive means saturating left, negative ri= ght. */ + TEST_PSIMD_SAT_RR_SET 328, pssha.hs, 0x0001ffff, 1, \ + 0x0002fffe, 0x40004000, 1, 0x7fff7fff, \ + 0xbfffbfff, 1, 0x80008000 + TEST_PSIMD_RR_VXSAT_STATE 328, pssha.hs, 0x0003fffc, -1, \ + 0x0001fffe, 0, 0 + TEST_PSIMD_SAT_RR_SET 329, psshar.hs, 0x0001ffff, 1, \ + 0x0002fffe, 0x40004000, 1, 0x7fff7fff, \ + 0xbfffbfff, 1, 0x80008000 + TEST_PSIMD_RR_VXSAT_STATE 329, psshar.hs, 0x0003fffc, -1, \ + 0x0002fffe, 0, 0 + + /* Unsigned variable shifts: saturating left and logical rounded right= . */ + TEST_PSIMD_SAT_RR_SET 600, psshl.hs, \ + 0x7ffe4000, 1, 0xfffc8000, \ + 0x80004001, 1, 0xffff8002, \ + 0xffff0001, 1, 0xffff0002 + TEST_PSIMD_RR_VXSAT_STATE 600, psshl.hs, \ + 0x80017fff, -1, 0x40003fff, 0, 0 + TEST_PSIMD_SAT_RR_SET 601, psshlr.hs, \ + 0x7ffe4000, 1, 0xfffc8000, \ + 0x80004001, 1, 0xffff8002, \ + 0xffff0001, 1, 0xffff0002 + TEST_PSIMD_RR_VXSAT_STATE 601, psshlr.hs, \ + 0x80030002, -1, 0x40020001, 0, 0 + TEST_PSIMD_RR_VXSAT_STATE 601, psshlr.hs, \ + 0x80017fff, -17, 0x00010000, 0, 0 + + TEST_PSIMD_SAT_RR_SET 332, ssha, 1, 1, 2, \ + 0x40000000, 1, 0x7fffffff, \ + 0xbfffffff, 1, 0x80000000 + TEST_PSIMD_RR_VXSAT_STATE 332, ssha, -4, -1, -2, 0, 0 + TEST_PSIMD_SAT_RR_SET 333, sshar, 1, 1, 2, \ + 0x40000000, 1, 0x7fffffff, \ + 0xbfffffff, 1, 0x80000000 + TEST_PSIMD_RR_VXSAT_STATE 333, sshar, 3, -1, 2, 0, 0 + + /* Byte-selection multiply: signed and unsigned high-bit inputs diverg= e. */ + TEST_PSIMD_RR_SET 344, pmul.h.b00, 0x7f80017f, 0x7f018001, \ + 0xff80007f + TEST_PSIMD_RR_SET 345, pmul.h.b01, 0x7f80017f, 0x017f0180, \ + 0xff80007f + TEST_PSIMD_RR_SET 346, pmul.h.b11, 0x80667f88, 0x017f0180, \ + 0xff80007f + TEST_PSIMD_RR_SET 347, pmulsu.h.b00, 0x7f80017f, 0x7f018001, \ + 0xff80007f + TEST_PSIMD_RR_SET 348, pmulsu.h.b11, 0x807f7f04, 0x017f0108, \ + 0xff80007f + TEST_PSIMD_RR_SET 349, pmulu.h.b00, 0x7f80017f, 0x7f018001, \ + 0x0080007f + TEST_PSIMD_RR_SET 350, pmulu.h.b01, 0x7f80017f, 0x017f0180, \ + 0x0080007f + TEST_PSIMD_RR_SET 351, pmulu.h.b11, 0x80807f7f, 0x017f0180, \ + 0x0080007f + + /* High-half multiply distinguishes truncating and rounded variants. */ + TEST_PSIMD_RR_SET 368, pmulh.h, 0x7fff0002, 0x7fff0003, \ + 0x3fff0000 + TEST_PSIMD_RR_SET 369, pmulhr.h, 0x7fff8000, 0x7fff8001, \ + 0x3fff4000 + TEST_PSIMD_RR_SET 370, pmulhsu.h, 0x7fff8000, 0xffff0001, \ + 0x7ffeffff + TEST_PSIMD_RR_SET 371, pmulhrsu.h, 0x7fff8000, 0xffff0001, \ + 0x7fff0000 + TEST_PSIMD_RR_SET 372, pmulhu.h, 0x8000ffff, 0x7fff0001, \ + 0x3fff0000 + TEST_PSIMD_RR_SET 373, pmulhru.h, 0x8000ffff, 0x7fff0001, \ + 0x40000001 + + /* Q15 multiply: rounding carry plus the unique min*min saturation. */ + TEST_PSIMD_SAT_RR_SET 383, pmulq.h, \ + 0x00017fff, 0x40007fff, 0x00007ffe, \ + 0x80008000, 0x80008000, 0x7fff7fff, \ + 0x80008000, 0x80008000, 0x7fff7fff + TEST_PSIMD_SAT_RR_SET 384, pmulqr.h, \ + 0x00017fff, 0x40007fff, 0x00017ffe, \ + 0x80008000, 0x80008000, 0x7fff7fff, \ + 0x80008000, 0x80008000, 0x7fff7fff + + TEST_PSIMD_RR_SET 389, pmulh.h.b0, 0x7fff8000, 0x01017f7f, \ + 0x007fc080 + TEST_PSIMD_RR_SET 390, pmulh.h.b1, 0x7fff8000, 0x01017f7f, \ + 0x007fc080 + TEST_PSIMD_RR_SET 391, pmulhsu.h.b0, 0x0010ffff, 0x01800001, \ + 0x0008ffff + TEST_PSIMD_RR_SET 392, pmulhsu.h.b1, 0x0010ffff, 0x8001017f, \ + 0x0008ffff + + /* Scalar ABS wraps at INT_MIN, exactly as the SPEC bit-vector formula= . */ + TEST_PSIMD_R_SET 158, abs, -1, 1 + TEST_PSIMD_R 158, abs, 0x80000000, 0x80000000 + +#elif __riscv_xlen =3D=3D 64 + /* PLI.B: zero, one, high immediate bits, and a mixed-bit pattern. */ + TEST_PSIMD_LI 1, pli.b, 0xa5, 0xa5a5a5a5a5a5a5a5 + TEST_PSIMD_LI 1, pli.b, 0, 0 + TEST_PSIMD_LI 1, pli.b, 1, 0x0101010101010101 + TEST_PSIMD_LI 1, pli.b, 0xff, 0xffffffffffffffff + TEST_PSIMD_LI 279, pli.h, 0, 0 + TEST_PSIMD_LI 279, pli.h, 1, 0x0001000100010001 + TEST_PSIMD_LI 279, pli.h, 511, 0x01ff01ff01ff01ff + TEST_PSIMD_LI 279, pli.h, -512, 0xfe00fe00fe00fe00 + TEST_PSIMD_LI 280, plui.h, 0, 0 + TEST_PSIMD_LI 280, plui.h, 1, 0x0040004000400040 + TEST_PSIMD_LI 280, plui.h, 511, 0x7fc07fc07fc07fc0 + TEST_PSIMD_LI 280, plui.h, -512, 0x8000800080008000 + TEST_PSIMD_LI 281, pli.w, 0, 0 + TEST_PSIMD_LI 281, pli.w, 1, 0x0000000100000001 + TEST_PSIMD_LI 281, pli.w, 511, 0x000001ff000001ff + TEST_PSIMD_LI 281, pli.w, -512, 0xfffffe00fffffe00 + TEST_PSIMD_LI 282, plui.w, 0, 0 + TEST_PSIMD_LI 282, plui.w, 1, 0x0040000000400000 + TEST_PSIMD_LI 282, plui.w, 511, 0x7fc000007fc00000 + TEST_PSIMD_LI 282, plui.w, -512, 0x8000000080000000 + + /* PADD.B keeps all high 32 bits active and tests both rd aliases. */ + TEST_PSIMD_RR 2, padd.b, 0x7f120003ff780001, 0x7f340007ff9a0005, \ + 0xfe46000afe120006 + TEST_PSIMD_RR 2, padd.b, 0, 0, 0 + TEST_PSIMD_RR 2, padd.b, 0x7f80ff007f80ff00, \ + 0x0101010101010101, 0x8081000180810001 + TEST_PSIMD_RR_RD_RS1 2, padd.b, 0x7f120003ff780001, \ + 0x7f340007ff9a0005, 0xfe46000afe120006 + TEST_PSIMD_RR_RD_RS2 2, padd.b, 0x7f120003ff780001, \ + 0x7f340007ff9a0005, 0xfe46000afe120006 + + /* PSADD.B: no saturation, exact bounds, both overflows, and sticky. */ + TEST_PSIMD_RR_VXSAT 3, psadd.b, 0x7f120003ff788001, \ + 0x7f340007ff9a8005, 0x7f46000afe128006 + TEST_PSIMD_RR_VXSAT_STATE 3, psadd.b, 0x0102fefe0102fefe, \ + 0x0101010101010101, \ + 0x0203ffff0203ffff, 0, 0 + TEST_PSIMD_RR_VXSAT_STATE 3, psadd.b, 0x7e7e81817e7e8181, \ + 0x0101ffff0101ffff, \ + 0x7f7f80807f7f8080, 0, 0 + TEST_PSIMD_RR_VXSAT_STATE 3, psadd.b, 0x8080808080808080, -1, \ + 0x8080808080808080, 0, 1 + TEST_PSIMD_RR_VXSAT_STATE 3, psadd.b, 0, 0, 0, 1, 1 + + /* PSATI.H width=3D5: exact bounds and values outside both bounds. */ + TEST_PSIMD_RI_VXSAT 4, psati.h, 0x000ffff07fff8000, 5, \ + 0x000ffff0000ffff0 + TEST_PSIMD_RI_VXSAT_STATE 4, psati.h, 0x000ffff0000ffff0, 5, \ + 0x000ffff0000ffff0, 0, 0 + TEST_PSIMD_RI_VXSAT_STATE 4, psati.h, 0x0010ffef0010ffef, 5, \ + 0x000ffff0000ffff0, 0, 1 + TEST_PSIMD_RI_VXSAT_STATE 4, psati.h, \ + 0x7fff80007fff8000, 16, \ + 0x7fff80007fff8000, 0, 0 + + /* PMHACC.H: nonzero rd, zero products, and signed-negative inputs. */ + TEST_PSIMD_ACC_RR 5, pmhacc.h, 0x0001000200030004, \ + 0x7fff800000020002, 0x7fff80010003fffe, \ + 0x4000400100030003 + TEST_PSIMD_ACC_RR 5, pmhacc.h, 0x123456789abcdef0, 0, 0, \ + 0x123456789abcdef0 + TEST_PSIMD_ACC_RR 5, pmhacc.h, 0, -1, -1, 0 + + /* PPAIRE.B uses a unique value in every source lane. */ + TEST_PSIMD_RR 6, ppaire.b, 0xaabbccddeeff1122, \ + 0x3344556677889900, 0x44bb66dd88ff0022 + TEST_PSIMD_RR 6, ppaire.b, 0, 0, 0 + TEST_PSIMD_RR_RD_RS1 6, ppaire.b, 0xaabbccddeeff1122, \ + 0x3344556677889900, 0x44bb66dd88ff0022 + TEST_PSIMD_RR_RD_RS2 6, ppaire.b, 0xaabbccddeeff1122, \ + 0x3344556677889900, 0x44bb66dd88ff0022 + + /* Signed/unsigned byte comparisons disagree in both XLEN halves. */ + TEST_PSIMD_RR_SET 30, pmin.b, 0x807f00ff807f00ff, \ + 0x7f8000ff7f8000ff, 0x808000ff808000ff + TEST_PSIMD_RR_SET 31, pminu.b, 0x807f00ff807f00ff, \ + 0x7f8000ff7f8000ff, 0x7f7f00ff7f7f00ff + TEST_PSIMD_RR_SET 32, pmax.b, 0x807f00ff807f00ff, \ + 0x7f8000ff7f8000ff, 0x7f7f00ff7f7f00ff + TEST_PSIMD_RR_SET 33, pmaxu.b, 0x807f00ff807f00ff, \ + 0x7f8000ff7f8000ff, 0x808000ff808000ff + TEST_PSIMD_RR_SET 34, pmseq.b, 0x807f00ff807f00ff, \ + 0x7f8000ff7f8000ff, 0x0000ffff0000ffff, -1 + TEST_PSIMD_RR_SET 35, pmslt.b, 0x807f00ff807f00ff, \ + 0x7f8000ff7f8000ff, 0xff000000ff000000 + TEST_PSIMD_RR_SET 36, pmsltu.b, 0x807f00ff807f00ff, \ + 0x7f8000ff7f8000ff, 0x00ff000000ff0000 + + /* Halfword extrema exercise signed and unsigned ordering. */ + TEST_PSIMD_RR_SET 37, pmin.h, 0x80007fff80007fff, \ + 0x7fff80007fff8000, 0x8000800080008000 + TEST_PSIMD_RR_SET 38, pminu.h, 0x80007fff80007fff, \ + 0x7fff80007fff8000, 0x7fff7fff7fff7fff + TEST_PSIMD_RR_SET 39, pmax.h, 0x80007fff80007fff, \ + 0x7fff80007fff8000, 0x7fff7fff7fff7fff + TEST_PSIMD_RR_SET 40, pmaxu.h, 0x80007fff80007fff, \ + 0x7fff80007fff8000, 0x8000800080008000 + TEST_PSIMD_RR_SET 41, pmseq.h, 0x80007fff80007fff, \ + 0x7fff80007fff8000, 0, -1 + TEST_PSIMD_RR_SET 42, pmslt.h, 0x80007fff80007fff, \ + 0x7fff80007fff8000, 0xffff0000ffff0000 + TEST_PSIMD_RR_SET 43, pmsltu.h, 0x80007fff80007fff, \ + 0x7fff80007fff8000, 0x0000ffff0000ffff + + /* RV64 word lanes keep the high 32-bit lane nonzero. */ + TEST_PSIMD_RR_SET 44, pmin.w, 0x800000007fffffff, \ + 0x7fffffff80000000, 0x8000000080000000 + TEST_PSIMD_RR_SET 45, pminu.w, 0x800000007fffffff, \ + 0x7fffffff80000000, 0x7fffffff7fffffff + TEST_PSIMD_RR_SET 46, pmax.w, 0x800000007fffffff, \ + 0x7fffffff80000000, 0x7fffffff7fffffff + TEST_PSIMD_RR_SET 47, pmaxu.w, 0x800000007fffffff, \ + 0x7fffffff80000000, 0x8000000080000000 + TEST_PSIMD_RR_SET 48, pmseq.w, 0x800000007fffffff, \ + 0x7fffffff80000000, 0, -1 + TEST_PSIMD_RR_SET 49, pmslt.w, 0x800000007fffffff, \ + 0x7fffffff80000000, 0xffffffff00000000 + TEST_PSIMD_RR_SET 50, pmsltu.w, 0x800000007fffffff, \ + 0x7fffffff80000000, 0x00000000ffffffff + + /* Wrapping subtraction and wider lane add/subtract operations. */ + TEST_PSIMD_RR_SET 72, psub.b, 0x0304fefd0304fefd, \ + 0x0101ff010101ff01, 0x0203fffc0203fffc + TEST_PSIMD_RR_SET 73, padd.h, 0x7fff80007fff8000, \ + 0x0001800000018000, 0x8000000080000000 + TEST_PSIMD_RR_SET 74, psub.h, 0x7fff80007fff8000, \ + 0x0001800000018000, 0x7ffe00007ffe0000 + TEST_PSIMD_RR_SET 82, padd.w, 0x7fffffff80000000, \ + 0x0000000180000000, 0x8000000000000000 + TEST_PSIMD_RR_SET 83, psub.w, 0x7fffffff80000000, \ + 0x0000000180000000, 0x7ffffffe00000000 + + /* Signed byte saturation: positive and negative overflow. */ + TEST_PSIMD_SAT_RR_SET 75, pssub.b, 0x0304fefd0304fefd, \ + 0x0101ff010101ff01, 0x0203fffc0203fffc, \ + 0x7f7f7f7f7f7f7f7f, -1, \ + 0x7f7f7f7f7f7f7f7f, \ + 0x8080808080808080, 0x0101010101010101, \ + 0x8080808080808080 + + /* Unsigned byte add overflow and subtract underflow. */ + TEST_PSIMD_SAT_RR_SET 76, psaddu.b, 0x0102fefe0102fefe, \ + 0x0101010101010101, 0x0203ffff0203ffff, -1, \ + 0x0101010101010101, -1, \ + 0xf0f0f0f0f0f0f0f0, 0x2020202020202020, -1 + TEST_PSIMD_SAT_RR_SET 77, pssubu.b, 0x0304fefd0304fefd, \ + 0x0101010101010101, 0x0203fdfc0203fdfc, 0, \ + 0x0101010101010101, 0, \ + 0x000100ff000100ff, 0x0102000101020001, \ + 0x000000fe000000fe + + /* Halfword signed/unsigned saturated add and subtract. */ + TEST_PSIMD_SAT_RR_SET 78, psadd.h, 0x0001000200010002, \ + 0x0003000400030004, 0x0004000600040006, \ + 0x7fff7fff7fff7fff, 0x0001000100010001, \ + 0x7fff7fff7fff7fff, 0x8000800080008000, -1, \ + 0x8000800080008000 + TEST_PSIMD_SAT_RR_SET 79, psaddu.h, 0x0001000200010002, \ + 0x0003000400030004, 0x0004000600040006, -1, \ + 0x0001000100010001, -1, \ + 0xf000f000f000f000, 0x2000200020002000, -1 + TEST_PSIMD_SAT_RR_SET 80, pssub.h, 0x0004000600040006, \ + 0x0001000400010004, 0x0003000200030002, \ + 0x7fff7fff7fff7fff, -1, 0x7fff7fff7fff7fff, \ + 0x8000800080008000, 0x0001000100010001, \ + 0x8000800080008000 + TEST_PSIMD_SAT_RR_SET 81, pssubu.h, 0x0004000600040006, \ + 0x0001000400010004, 0x0003000200030002, 0, \ + 0x0001000100010001, 0, \ + 0x000100ff000100ff, 0x0002000100020001, \ + 0x000000fe000000fe + + /* RV64 word saturation keeps both 32-bit lanes active. */ + TEST_PSIMD_SAT_RR_SET 84, psadd.w, 0x0000000100000002, \ + 0x0000000300000004, 0x0000000400000006, \ + 0x7fffffff7fffffff, 0x0000000100000001, \ + 0x7fffffff7fffffff, 0x8000000080000000, -1, \ + 0x8000000080000000 + TEST_PSIMD_SAT_RR_SET 85, psaddu.w, 0x0000000100000002, \ + 0x0000000300000004, 0x0000000400000006, -1, \ + 0x0000000100000001, -1, \ + 0xf0000000f0000000, 0x2000000020000000, -1 + TEST_PSIMD_SAT_RR_SET 86, pssub.w, 0x0000000400000006, \ + 0x0000000100000004, 0x0000000300000002, \ + 0x7fffffff7fffffff, -1, 0x7fffffff7fffffff, \ + 0x8000000080000000, 0x0000000100000001, \ + 0x8000000080000000 + TEST_PSIMD_SAT_RR_SET 87, pssubu.w, 0x0000000400000006, \ + 0x0000000100000004, 0x0000000300000002, 0, \ + 0x0000000100000001, 0, \ + 0x00000001000000ff, 0x0000000200000001, \ + 0x00000000000000fe + + /* Signed/unsigned average byte add/subtract with active high lanes. */ + TEST_PSIMD_RR_SET 109, paadd.b, 0x7f120003ff780001, \ + 0x7f340007ff9a0005, 0x7f230005ff090003 + TEST_PSIMD_RR_SET 110, paaddu.b, 0x7f120003ff780001, \ + 0x7f340007ff9a0005, 0x7f230005ff890003 + TEST_PSIMD_RR_SET 111, pasub.b, 0xffff000000000001, \ + 0x111100010000ffff, 0xf7f700ff00000001 + TEST_PSIMD_RR_SET 112, pasubu.b, 0xffff000000000001, \ + 0x111100010000ffff, 0x777700ff00008081 + TEST_PSIMD_RR 109, paadd.b, 0x7f7f7f7f7f7f7f7f, \ + 0x8080808080808080, -1 + TEST_PSIMD_RR 110, paaddu.b, -1, 0x0101010101010101, \ + 0x8080808080808080 + TEST_PSIMD_RR 111, pasub.b, 0x8080808080808080, \ + 0x7f7f7f7f7f7f7f7f, 0x8080808080808080 + TEST_PSIMD_RR 112, pasubu.b, -1, 0, 0x7f7f7f7f7f7f7f7f + + /* Halfword average operations exercise signed/unsigned divergence. */ + TEST_PSIMD_RR_SET 113, paadd.h, 0x7f120003ff780001, \ + 0x7f340007ff9a0005, 0x7f230005ff890003 + TEST_PSIMD_RR_SET 114, paaddu.h, 0x7f120003ff780001, \ + 0x7f340007ff9a0005, 0x7f230005ff890003 + TEST_PSIMD_RR_SET 115, pasub.h, 0xffff000000000001, \ + 0x111100010000ffff, 0xf777ffff00000001 + TEST_PSIMD_RR_SET 116, pasubu.h, 0xffff000000000001, \ + 0x111100010000ffff, 0x7777ffff00008001 + TEST_PSIMD_RR 113, paadd.h, 0x7fff7fff7fff7fff, \ + 0x8000800080008000, -1 + TEST_PSIMD_RR 114, paaddu.h, -1, 0x0001000100010001, \ + 0x8000800080008000 + TEST_PSIMD_RR 115, pasub.h, 0x8000800080008000, \ + 0x7fff7fff7fff7fff, 0x8000800080008000 + TEST_PSIMD_RR 116, pasubu.h, -1, 0, 0x7fff7fff7fff7fff + + /* RV64 word averages keep both word lanes nonzero. */ + TEST_PSIMD_RR_SET 119, paadd.w, 0xffffff12ffffff78, \ + 0xffffff34ffffff9a, 0xffffff23ffffff89 + TEST_PSIMD_RR_SET 120, paaddu.w, 0xffffff12ffffff78, \ + 0xffffff34ffffff9a, 0xffffff23ffffff89 + TEST_PSIMD_RR_SET 121, pasub.w, 1, 0x00000001ffffffff, \ + 0xffffffff00000001 + TEST_PSIMD_RR_SET 122, pasubu.w, 1, 0x00000001ffffffff, \ + 0xffffffff80000001 + TEST_PSIMD_RR 119, paadd.w, 0x7fffffff7fffffff, \ + 0x8000000080000000, -1 + TEST_PSIMD_RR 120, paaddu.w, -1, 0x0000000100000001, \ + 0x8000000080000000 + TEST_PSIMD_RR 121, pasub.w, 0x8000000080000000, \ + 0x7fffffff7fffffff, 0x8000000080000000 + TEST_PSIMD_RR 122, pasubu.w, -1, 0, 0x7fffffff7fffffff + + /* Shift-one add wraps; signed variants saturate and set vxsat. */ + TEST_PSIMD_RR_SET 117, psh1add.h, 0x7fff8000000afffb, \ + 0x0001fffe00050005, 0xfffffffe0019fffb + TEST_PSIMD_SAT_RR_SET 118, pssh1sadd.h, 1, 2, 4, \ + 0x4000400040004000, 0, \ + 0x7fff7fff7fff7fff, \ + 0xc000c000c000c000, -1, \ + 0x8000800080008000 + TEST_PSIMD_RR_SET 123, psh1add.w, 0x0000000a2000000f, \ + 0x0000000500000003, 0x0000001940000021 + TEST_PSIMD_SAT_RR_SET 124, pssh1sadd.w, \ + 0x0000000200000001, 0x0000000300000004, \ + 0x0000000700000006, \ + 0x4000000040000000, 0, \ + 0x7fffffff7fffffff, \ + 0xc0000000c0000000, -1, \ + 0x8000000080000000 + /* Absolute difference with every high-half lane active. */ + TEST_PSIMD_RR_SET 146, pabd.b, 0x807f0201807f0201, \ + 0x018001ff7f80027f, 0x81ff0102ffff007e + TEST_PSIMD_RR_SET 147, pabdu.b, 0x807f0201807f0201, \ + 0x018001ff7f80027f, 0x7f0101fe0101007e + TEST_PSIMD_RR_SET 148, pabd.h, 0x00010002fffe7fff, \ + 0x0002000100010001, 0x0001000100037ffe + TEST_PSIMD_RR_SET 149, pabdu.h, 0x00010002fffe7fff, \ + 0x0002000100010001, 0x00010001fffd7ffe + + TEST_PSIMD_RR_SET 150, pabdsumu.b, 0x807fffff807fffff, \ + 0x7f0101fe7f0101fe, 0x2fc + TEST_PSIMD_ACC_RR_SET 151, pabdsumau.b, 1, \ + 0x807fffff807fffff, 0x7f0101fe7f0101fe, 0x2fd, \ + 0x807fffff808002fb, 0x7f0101fe7f0104fa + TEST_PSIMD_ACC_RR 151, pabdsumau.b, 0x123456789abcdef0, 0, 0, \ + 0x123456789abcdef0 + + TEST_PSIMD_SAT_R_SET 152, psabs.b, 0x00007fffffff8101, \ + 0x00007f0101017f01, \ + 0x8000000080000000, 0x7f0000007f000000 + TEST_PSIMD_SAT_R_SET 153, psabs.h, 0x00007fffffff8001, \ + 0x00007fff00017fff, \ + 0x8000000080000000, 0x7fff00007fff0000 + + TEST_PSIMD_RR_SET 154, predsum.bs, 0x807f02fe01807f02, \ + 0x64, 0x65 + TEST_PSIMD_RR_SET 155, predsumu.bs, 0x807f02ff01807f02, \ + 0x64, 0x366 + TEST_PSIMD_RR_SET 156, predsum.hs, 0x0003000400010002, 0xa, 0x14 + TEST_PSIMD_RR_SET 157, predsumu.hs, 0x1000200030004000, \ + 0x1000, 0xb000 + TEST_PSIMD_RR_SET 159, predsum.ws, 0x7fffffff00000005, \ + 0x1000, 0x0000000080001004 + TEST_PSIMD_RR_SET 160, predsumu.ws, 0xffffffff0000000a, \ + 0x1000, 0x0000000100001009 + + /* Packed shifts keep distinct data in both halves of the RV64 registe= r. */ + TEST_PSIMD_SHIFT_RR_SET 172, psll.bs, 0x807f1201807f1201, \ + 0x00fe240200fe2402, 7, \ + 0x0080008000800080 + TEST_PSIMD_SHIFT_RR_SET 173, psrl.bs, 0x807f1201807f1201, \ + 0x403f0900403f0900, 7, \ + 0x0100000001000000 + TEST_PSIMD_SHIFT_RR_SET 174, psra.bs, 0x807f1201807f1201, \ + 0xc03f0900c03f0900, 7, \ + 0xff000000ff000000 + TEST_PSIMD_SHIFT_RI_SET 175, pslli.b, 0x807f1201807f1201, \ + 0x00fe240200fe2402, 7, \ + 0x0080008000800080 + TEST_PSIMD_SHIFT_RI_SET 176, psrli.b, 0x807f1201807f1201, \ + 0x403f0900403f0900, 7, \ + 0x0100000001000000 + TEST_PSIMD_SHIFT_RI_SET 177, psrai.b, 0x807f1201807f1201, \ + 0xc03f0900c03f0900, 7, \ + 0xff000000ff000000 + + TEST_PSIMD_SHIFT_RR_SET 178, psll.hs, 0x80017fff80017fff, \ + 0x0002fffe0002fffe, 15, \ + 0x8000800080008000 + TEST_PSIMD_SHIFT_RR_SET 179, psrl.hs, 0x80017fff80017fff, \ + 0x40003fff40003fff, 15, \ + 0x0001000000010000 + TEST_PSIMD_SHIFT_RR_SET 180, psra.hs, 0x80017fff80017fff, \ + 0xc0003fffc0003fff, 15, \ + 0xffff0000ffff0000 + TEST_PSIMD_SHIFT_RI_SET 181, pslli.h, 0x80017fff80017fff, \ + 0x0002fffe0002fffe, 15, \ + 0x8000800080008000 + TEST_PSIMD_SHIFT_RI_SET 182, psrli.h, 0x80017fff80017fff, \ + 0x40003fff40003fff, 15, \ + 0x0001000000010000 + TEST_PSIMD_SHIFT_RI_SET 183, psrai.h, 0x80017fff80017fff, \ + 0xc0003fffc0003fff, 15, \ + 0xffff0000ffff0000 + + TEST_PSIMD_SHIFT_RR_SET 184, psll.ws, 0x800000017fffffff, \ + 0x00000002fffffffe, 31, \ + 0x8000000080000000 + TEST_PSIMD_SHIFT_RR_SET 185, psrl.ws, 0x800000017fffffff, \ + 0x400000003fffffff, 31, \ + 0x0000000100000000 + TEST_PSIMD_SHIFT_RR_SET 186, psra.ws, 0x800000017fffffff, \ + 0xc00000003fffffff, 31, \ + 0xffffffff00000000 + TEST_PSIMD_SHIFT_RI_SET 187, pslli.w, 0x800000017fffffff, \ + 0x00000002fffffffe, 31, \ + 0x8000000080000000 + TEST_PSIMD_SHIFT_RI_SET 188, psrli.w, 0x800000017fffffff, \ + 0x400000003fffffff, 31, \ + 0x0000000100000000 + TEST_PSIMD_SHIFT_RI_SET 189, psrai.w, 0x800000017fffffff, \ + 0xc00000003fffffff, 31, \ + 0xffffffff00000000 + + /* Rounded shifts cover both guard values and negative arithmetic fill= . */ + TEST_PSIMD_SHIFT_RI_SET 208, psrari.h, \ + 0x80017ffffffd0002, \ + 0xc0014000ffff0001, 15, \ + 0xffff000100000000 + TEST_PSIMD_RI 208, psrari.h, 0x0003fffc00050004, 1, \ + 0x0002fffe00030002 + TEST_PSIMD_SHIFT_RI_SET 210, psrari.w, \ + 0x800000017fffffff, \ + 0xc000000140000000, 31, \ + 0xffffffff00000001 + TEST_PSIMD_RI 210, psrari.w, 0x00000003fffffffc, 1, \ + 0x00000002fffffffe + TEST_PSIMD_SHIFT_RI_SET 209, srari, 0x8000000000000001, \ + 0xc000000000000001, 63, -1 + TEST_PSIMD_RI 209, srari, 3, 1, 2 + + /* Pair/merge operations make every RV64 source field visible. */ + TEST_PSIMD_RR_SET 261, ppaireo.b, 0x1122334455667788, \ + 0x99aabbccddeeff00, 0x9922bb44dd66ff88 + TEST_PSIMD_RR_SET 262, ppairoe.b, 0x1122334455667788, \ + 0x99aabbccddeeff00, 0xaa11cc33ee550077 + TEST_PSIMD_RR_SET 263, ppairo.b, 0x1122334455667788, \ + 0x99aabbccddeeff00, 0x9911bb33dd55ff77 + TEST_PSIMD_RR_SET 267, ppaire.h, 0x1122334455667788, \ + 0x99aabbccddeeff00, 0xbbcc3344ff007788 + TEST_PSIMD_RR_SET 264, ppaireo.h, 0x1122334455667788, \ + 0x99aabbccddeeff00, 0x99aa3344ddee7788 + TEST_PSIMD_RR_SET 265, ppairoe.h, 0x1122334455667788, \ + 0x99aabbccddeeff00, 0xbbcc1122ff005566 + TEST_PSIMD_RR_SET 266, ppairo.h, 0x1122334455667788, \ + 0x99aabbccddeeff00, 0x99aa1122ddee5566 + TEST_PSIMD_RR_SET 268, ppaireo.w, 0x1122334455667788, \ + 0x99aabbccddeeff00, 0x99aabbcc55667788 + TEST_PSIMD_RR_SET 269, ppairoe.w, 0x1122334455667788, \ + 0x99aabbccddeeff00, 0xddeeff0011223344 + TEST_PSIMD_RR_SET 270, ppairo.w, 0x1122334455667788, \ + 0x99aabbccddeeff00, 0x99aabbcc11223344 + + TEST_PSIMD_R_SET 283, psext.h.b, 0x000100ff007f0080, \ + 0x0001ffff007fff80 + TEST_PSIMD_R_SET 284, psext.w.b, 0x000000800000007f, \ + 0xffffff800000007f + TEST_PSIMD_R_SET 285, psext.w.h, 0x0000800100007fff, \ + 0xffff800100007fff + + TEST_PSIMD_ACC_RR_SET 292, mvm, 0xaaaaaaaaaaaaaaaa, \ + 0x5555555555555555, 0x0f0ff0f00f0ff0f0, \ + 0xa5a55a5aa5a55a5a, 0x5555555555555555, \ + 0x0505505005055050 + TEST_PSIMD_ACC_RR 292, mvm, 0xaaaaaaaaaaaaaaaa, \ + 0x5555555555555555, 0, 0xaaaaaaaaaaaaaaaa + TEST_PSIMD_ACC_RR_SET 293, mvmn, 0xaaaaaaaaaaaaaaaa, \ + 0x5555555555555555, 0x0f0ff0f00f0ff0f0, \ + 0x5a5aa5a55a5aa5a5, 0x5555555555555555, \ + 0x5f5ff5f55f5ff5f5 + TEST_PSIMD_ACC_RR 293, mvmn, 0xaaaaaaaaaaaaaaaa, \ + 0x5555555555555555, -1, 0xaaaaaaaaaaaaaaaa + TEST_PSIMD_ACC_RR_SET 294, merge, 0xaaaaaaaaaaaaaaaa, \ + 0x5555555555555555, 0x0f0ff0f00f0ff0f0, \ + 0x5f5ff5f55f5ff5f5, 0x0505505005055050, \ + 0x5f5ff5f55f5ff5f5 + TEST_PSIMD_RR_SET 295, pack, 0x1122334455667788, \ + 0x99aabbccddeeff00, 0xddeeff0055667788 + + TEST_PSIMD_R 297, cls, 1, 62 + TEST_PSIMD_R_RD_RS1 297, cls, 1, 62 + TEST_PSIMD_R 297, cls, 0, 63 + TEST_PSIMD_R 297, cls, -1, 63 + TEST_PSIMD_R 297, cls, 0x4000000000000000, 0 + TEST_PSIMD_R 301, clsw, 1, 30 + TEST_PSIMD_R_RD_RS1 301, clsw, 1, 30 + TEST_PSIMD_R 301, clsw, 0, 31 + TEST_PSIMD_R 301, clsw, 0xffffffff, 31 + + TEST_PSIMD_SAT_RI_SET 313, sati, 5, 15, 15, 16, 15, -17, -16 + TEST_PSIMD_RI_VXSAT_STATE 313, sati, 0x7fffffffffffffff, 64, \ + 0x7fffffffffffffff, 0, 0 + TEST_PSIMD_SAT_RI_SET 316, psati.w, 5, \ + 0x0000000ffffffff0, \ + 0x0000000ffffffff0, \ + 0x0000001000000010, \ + 0x0000000f0000000f, \ + 0xffffffefffffffef, \ + 0xfffffff0fffffff0 + TEST_PSIMD_RI_VXSAT_STATE 316, psati.w, \ + 0x7fffffff80000000, 32, \ + 0x7fffffff80000000, 0, 0 + TEST_PSIMD_SAT_RI_SET 314, pusati.h, 4, \ + 0x000f0000000f0000, \ + 0x000f0000000f0000, \ + 0x0010001000100010, \ + 0x000f000f000f000f, -1, 0 + TEST_PSIMD_RI_VXSAT_STATE 314, pusati.h, \ + 0x7fff00007fff0000, 15, \ + 0x7fff00007fff0000, 0, 0 + TEST_PSIMD_SAT_RI_SET 317, pusati.w, 4, \ + 0x0000000f00000000, \ + 0x0000000f00000000, \ + 0x0000001000000010, \ + 0x0000000f0000000f, -1, 0 + TEST_PSIMD_RI_VXSAT_STATE 317, pusati.w, \ + 0x7fffffff00000000, 31, \ + 0x7fffffff00000000, 0, 0 + TEST_PSIMD_SAT_RI_SET 315, usati, 4, 15, 15, 16, 15, -1, 0 + TEST_PSIMD_RI_VXSAT_STATE 315, usati, \ + 0x7fffffffffffffff, 63, \ + 0x7fffffffffffffff, 0, 0 + + TEST_PSIMD_SAT_RI_SET 323, psslai.h, 1, \ + 0x0001ffff0001ffff, \ + 0x0002fffe0002fffe, \ + 0x4000400040004000, \ + 0x7fff7fff7fff7fff, \ + 0xbfffbfffbfffbfff, \ + 0x8000800080008000 + TEST_PSIMD_RI_VXSAT_STATE 323, psslai.h, 0, 15, 0, 0, 0 + TEST_PSIMD_SAT_RI_SET 325, psslai.w, 1, \ + 0x00000001ffffffff, \ + 0x00000002fffffffe, \ + 0x4000000040000000, \ + 0x7fffffff7fffffff, \ + 0xbfffffffbfffffff, \ + 0x8000000080000000 + TEST_PSIMD_RI_VXSAT_STATE 325, psslai.w, 0, 31, 0, 0, 0 + + TEST_PSIMD_SAT_RR_SET 328, pssha.hs, \ + 0x0001ffff0001ffff, 1, \ + 0x0002fffe0002fffe, \ + 0x4000400040004000, 1, \ + 0x7fff7fff7fff7fff, \ + 0xbfffbfffbfffbfff, 1, \ + 0x8000800080008000 + TEST_PSIMD_RR_VXSAT_STATE 328, pssha.hs, \ + 0x0003fffc0003fffc, -1, \ + 0x0001fffe0001fffe, 0, 0 + TEST_PSIMD_SAT_RR_SET 329, psshar.hs, \ + 0x0001ffff0001ffff, 1, \ + 0x0002fffe0002fffe, \ + 0x4000400040004000, 1, \ + 0x7fff7fff7fff7fff, \ + 0xbfffbfffbfffbfff, 1, \ + 0x8000800080008000 + TEST_PSIMD_RR_VXSAT_STATE 329, psshar.hs, \ + 0x0003fffc0003fffc, -1, \ + 0x0002fffe0002fffe, 0, 0 + + /* Unsigned variable shifts: saturating left and logical rounded right= . */ + TEST_PSIMD_SAT_RR_SET 600, psshl.hs, \ + 0x000100027ffe4000, 1, \ + 0x00020004fffc8000, \ + 0x8000400180004001, 1, \ + 0xffff8002ffff8002, \ + 0xffff0001ffff0001, 1, \ + 0xffff0002ffff0002 + TEST_PSIMD_RR_VXSAT_STATE 600, psshl.hs, \ + 0x80017fff00030002, -1, \ + 0x40003fff00010001, 0, 0 + TEST_PSIMD_SAT_RR_SET 601, psshlr.hs, \ + 0x0003000420001000, 1, \ + 0x0006000840002000, \ + 0x8000400180004001, 1, \ + 0xffff8002ffff8002, \ + 0xffff0001ffff0001, 1, \ + 0xffff0002ffff0002 + TEST_PSIMD_RR_VXSAT_STATE 601, psshlr.hs, \ + 0x8003000200030002, -1, \ + 0x4002000100020001, 0, 0 + TEST_PSIMD_RR_VXSAT_STATE 601, psshlr.hs, \ + 0x80017fff80000001, -17, \ + 0x0001000000010000, 0, 0 + + TEST_PSIMD_SAT_RR_SET 336, pssha.ws, \ + 0x00000001ffffffff, 1, \ + 0x00000002fffffffe, \ + 0x4000000040000000, 1, \ + 0x7fffffff7fffffff, \ + 0xbfffffffbfffffff, 1, \ + 0x8000000080000000 + TEST_PSIMD_RR_VXSAT_STATE 336, pssha.ws, \ + 0x00000003fffffffc, -1, \ + 0x00000001fffffffe, 0, 0 + TEST_PSIMD_SAT_RR_SET 337, psshar.ws, \ + 0x00000001ffffffff, 1, \ + 0x00000002fffffffe, \ + 0x4000000040000000, 1, \ + 0x7fffffff7fffffff, \ + 0xbfffffffbfffffff, 1, \ + 0x8000000080000000 + TEST_PSIMD_RR_VXSAT_STATE 337, psshar.ws, \ + 0x00000003fffffffc, -1, \ + 0x00000002fffffffe, 0, 0 + + TEST_PSIMD_RR_SET 344, pmul.h.b00, \ + 0x7f80017f05027e01, \ + 0x7f0180015e80007f, \ + 0xff80007fff00007f + TEST_PSIMD_RR_SET 345, pmul.h.b01, \ + 0x7f80017f05027e01, \ + 0x017f0180805e7f80, \ + 0xff80007fff00007f + TEST_PSIMD_RR_SET 346, pmul.h.b11, \ + 0x80667f8802500101, \ + 0x017f0180805e7f80, \ + 0xff80007fff00007f + TEST_PSIMD_RR_SET 347, pmulsu.h.b00, \ + 0x7f80017f05027e01, \ + 0x7f0180015e80007f, \ + 0xff80007f0100007f + TEST_PSIMD_RR_SET 348, pmulsu.h.b11, \ + 0x807f7f04027f017e, \ + 0x017f010880807f55, \ + 0xff80007f0100007f + TEST_PSIMD_RR_SET 349, pmulu.h.b00, \ + 0x7f80017f05027e01, \ + 0x7f0180015e80007f, \ + 0x0080007f0100007f + TEST_PSIMD_RR_SET 350, pmulu.h.b01, \ + 0x7f80017f05027e01, \ + 0x017f018080807f7f, \ + 0x0080007f0100007f + TEST_PSIMD_RR_SET 351, pmulu.h.b11, \ + 0x80807f7f02020101, \ + 0x017f018080807f7f, \ + 0x0080007f0100007f + + /* Halfword-selection multiply produces two distinct 32-bit lanes. */ + TEST_PSIMD_RR_SET 352, pmul.w.h00, \ + 0xffff7fffffff0001, \ + 0xffff7fff0000ffff, \ + 0x3fff0001ffffffff + TEST_PSIMD_RR_SET 353, pmul.w.h01, \ + 0xffff7fffffff0001, \ + 0x7fffffffffff0000, \ + 0x3fff0001ffffffff + TEST_PSIMD_RR_SET 354, pmul.w.h11, \ + 0x7fffffff0001ffff, \ + 0x7fffffffffff0000, \ + 0x3fff0001ffffffff + TEST_PSIMD_RR_SET 355, pmulsu.w.h00, \ + 0xffff7fffffff0001, \ + 0xffff7fff0000ffff, \ + 0x3fff00010000ffff + TEST_PSIMD_RR_SET 356, pmulsu.w.h11, \ + 0x7fffffff0001ffff, \ + 0x7fffffffffff0000, \ + 0x3fff00010000ffff + TEST_PSIMD_RR_SET 357, pmulu.w.h00, \ + 0xffff7fffffffffff, \ + 0xffff7fff00000001, \ + 0x3fff00010000ffff + TEST_PSIMD_RR_SET 358, pmulu.w.h01, \ + 0xffff7fffffffffff, \ + 0x7fffffff000107ff, \ + 0x3fff00010000ffff + TEST_PSIMD_RR_SET 359, pmulu.w.h11, \ + 0x7fffffffffffffff, \ + 0x7fffffff000107ff, \ + 0x3fff00010000ffff + + TEST_PSIMD_RR_SET 368, pmulh.h, \ + 0x7fff00028000fffe, \ + 0x7fff00037fff0001, \ + 0x3fff0000c000ffff + TEST_PSIMD_RR_SET 369, pmulhr.h, \ + 0x7fff800000028000, \ + 0x7fff800100037fff, \ + 0x3fff40000000c001 + TEST_PSIMD_RR_SET 370, pmulhsu.h, \ + 0x7fff80000002fffe, \ + 0xffff000100030004, \ + 0x7ffeffff0000ffff + TEST_PSIMD_RR_SET 371, pmulhrsu.h, \ + 0x7fff80000002fffe, \ + 0xffff000100030004, \ + 0x7fff000000000000 + TEST_PSIMD_RR_SET 372, pmulhu.h, \ + 0x8000ffff0002fffe, \ + 0x7fff000180017fff, \ + 0x3fff000000017ffe + TEST_PSIMD_RR_SET 373, pmulhru.h, \ + 0x8000ffff0002fffe, \ + 0x7fff000180017fff, \ + 0x4000000100017ffe + + TEST_PSIMD_RR_SET 374, pmulh.w, \ + 0x000000017fffffff, \ + 0xffffffff7fffffff, \ + 0xffffffff3fffffff + TEST_PSIMD_RR_SET 375, pmulhr.w, \ + 0x000000017fffffff, \ + 0xffffffff7fffffff, \ + 0x000000003fffffff + TEST_PSIMD_RR_SET 376, pmulhsu.w, \ + 0x7fff80000002fffe, \ + 0xffff000100030004, \ + 0x7fff000000000009 + TEST_PSIMD_RR_SET 377, pmulhrsu.w, \ + 0x7fff80000002fffe, \ + 0xffff000100030004, \ + 0x7fff000100000009 + TEST_PSIMD_RR_SET 378, pmulhu.w, \ + 0x8000ffff0002fffe, \ + 0x7fff000180017fff, \ + 0x3fffffff00018003 + TEST_PSIMD_RR_SET 379, pmulhru.w, \ + 0x8000ffff0002fffe, \ + 0x7fffffff80017fff, \ + 0x40007fff00018003 + + TEST_PSIMD_SAT_RR_SET 383, pmulq.h, \ + 0x00017fff0002ffff, \ + 0x40007fff20000001, \ + 0x00007ffe0000ffff, \ + 0x8000800080008000, \ + 0x8000800080008000, \ + 0x7fff7fff7fff7fff, \ + 0x8000800080008000, \ + 0x8000800080008000, \ + 0x7fff7fff7fff7fff + TEST_PSIMD_SAT_RR_SET 384, pmulqr.h, \ + 0x00017fff0002ffff, \ + 0x40007fff20000001, \ + 0x00017ffe00010000, \ + 0x8000800080008000, \ + 0x8000800080008000, \ + 0x7fff7fff7fff7fff, \ + 0x8000800080008000, \ + 0x8000800080008000, \ + 0x7fff7fff7fff7fff + TEST_PSIMD_SAT_RR_SET 385, pmulq.w, \ + 0x000000017fffffff, \ + 0x400000007fffffff, \ + 0x000000007ffffffe, \ + 0x8000000080000000, \ + 0x8000000080000000, \ + 0x7fffffff7fffffff, \ + 0x8000000080000000, \ + 0x8000000080000000, \ + 0x7fffffff7fffffff + TEST_PSIMD_SAT_RR_SET 386, pmulqr.w, \ + 0x000000017fffffff, \ + 0x400000007fffffff, \ + 0x000000017ffffffe, \ + 0x8000000080000000, \ + 0x8000000080000000, \ + 0x7fffffff7fffffff, \ + 0x8000000080000000, \ + 0x8000000080000000, \ + 0x7fffffff7fffffff + + TEST_PSIMD_RR_SET 389, pmulh.h.b0, \ + 0x7fff80000001ffff, \ + 0x01017f7f80010001, \ + 0x007fc0800000ffff + TEST_PSIMD_RR_SET 390, pmulh.h.b1, \ + 0x7fff80000001ffff, \ + 0x01017f7f01800100, \ + 0x007fc0800000ffff + TEST_PSIMD_RR_SET 391, pmulhsu.h.b0, \ + 0x7fff80000010ffff, \ + 0x01017f7f01800001, \ + 0x007fc0800008ffff + TEST_PSIMD_RR_SET 392, pmulhsu.h.b1, \ + 0x7fff80000010ffff, \ + 0x01017f7f8001017f, \ + 0x007fc0800008ffff + TEST_PSIMD_RR_SET 393, pmulh.w.h0, \ + 0x000000017fffffff, \ + 0x0000ffff00007fff, \ + 0xffffffff3fff7fff + TEST_PSIMD_RR_SET 394, pmulh.w.h1, \ + 0x000000017fffffff, \ + 0xffff00007fff0000, \ + 0xffffffff3fff7fff + TEST_PSIMD_RR_SET 395, pmulhsu.w.h0, \ + 0x000000017fffffff, \ + 0x0000ffff00007fff, \ + 0x000000003fff7fff + TEST_PSIMD_RR_SET 396, pmulhsu.w.h1, \ + 0x000000017fffffff, \ + 0xffff00007fff0000, \ + 0x000000003fff7fff + + TEST_PSIMD_R_SET 158, abs, -1, 1 + TEST_PSIMD_R 158, abs, 0x8000000000000000, 0x8000000000000000 + TEST_PSIMD_R_SET 161, absw, 0x12345678ffffffff, 1 + TEST_PSIMD_R 161, absw, 0x1234567880000000, \ + 0xffffffff80000000 + +#else +#error unsupported RISC-V XLEN +#endif diff --git a/tests/tcg/riscv/psimd-rv32.S b/tests/tcg/riscv/psimd-rv32.S new file mode 100644 index 00000000000..9a20142e98b --- /dev/null +++ b/tests/tcg/riscv/psimd-rv32.S @@ -0,0 +1,1256 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Basic RV32 P extension execution tests. */ + +#include "psimd-test-macros.inc" + + .text + .balign 4 + .globl _start + .type _start, @function +_start: +#include "psimd-common.S" + + TEST_PSIMD_PAIR_RR 7, padd.db, 0x7f120003, 0xff780001, \ + 0x7f340007, 0xff9a0005, 0xfe46000a, 0xfe120006 + TEST_PSIMD_PAIR_RR 7, padd.db, 0, 0, 0, 0, 0, 0 + TEST_PSIMD_PAIR_RR 7, padd.db, 0x7f80ff00, 0x008001ff, \ + 0x01010101, 0xff017f01, 0x80810001, 0xff818000 + TEST_PSIMD_PAIR_RR_RD_RS1 7, padd.db, 0x7f120003, 0xff780001, \ + 0x7f340007, 0xff9a0005, 0xfe46000a, \ + 0xfe120006 + TEST_PSIMD_PAIR_RR_RD_RS2 7, padd.db, 0x7f120003, 0xff780001, \ + 0x7f340007, 0xff9a0005, 0xfe46000a, \ + 0xfe120006 + + /* Double-wide byte comparisons, including pair source overlap. */ + TEST_PSIMD_PAIR_RR_SET 51, pmin.db, 0x807f00ff, 0x807f00ff, \ + 0x7f8000ff, 0x7f8000ff, 0x808000ff, \ + 0x808000ff, 0 + TEST_PSIMD_PAIR_RR_SET 52, pminu.db, 0x807f00ff, 0x807f00ff, \ + 0x7f8000ff, 0x7f8000ff, 0x7f7f00ff, \ + 0x7f7f00ff, 0 + TEST_PSIMD_PAIR_RR_SET 53, pmax.db, 0x807f00ff, 0x807f00ff, \ + 0x7f8000ff, 0x7f8000ff, 0x7f7f00ff, \ + 0x7f7f00ff, 0 + TEST_PSIMD_PAIR_RR_SET 54, pmaxu.db, 0x807f00ff, 0x807f00ff, \ + 0x7f8000ff, 0x7f8000ff, 0x808000ff, \ + 0x808000ff, 0 + TEST_PSIMD_PAIR_RR_SET 55, pmseq.db, 0x807f00ff, 0x807f00ff, \ + 0x7f8000ff, 0x7f8000ff, 0x0000ffff, \ + 0x0000ffff + TEST_PSIMD_PAIR_RR_SET 56, pmslt.db, 0x807f00ff, 0x807f00ff, \ + 0x7f8000ff, 0x7f8000ff, 0xff000000, \ + 0xff000000, 0 + TEST_PSIMD_PAIR_RR_SET 57, pmsltu.db, 0x807f00ff, 0x807f00ff, \ + 0x7f8000ff, 0x7f8000ff, 0x00ff0000, \ + 0x00ff0000, 0 + + /* Double-wide halfword comparisons. */ + TEST_PSIMD_PAIR_RR_SET 58, pmin.dh, 0x80007fff, 0x80007fff, \ + 0x7fff8000, 0x7fff8000, 0x80008000, \ + 0x80008000, 0 + TEST_PSIMD_PAIR_RR_SET 59, pminu.dh, 0x80007fff, 0x80007fff, \ + 0x7fff8000, 0x7fff8000, 0x7fff7fff, \ + 0x7fff7fff, 0 + TEST_PSIMD_PAIR_RR_SET 60, pmax.dh, 0x80007fff, 0x80007fff, \ + 0x7fff8000, 0x7fff8000, 0x7fff7fff, \ + 0x7fff7fff, 0 + TEST_PSIMD_PAIR_RR_SET 61, pmaxu.dh, 0x80007fff, 0x80007fff, \ + 0x7fff8000, 0x7fff8000, 0x80008000, \ + 0x80008000, 0 + TEST_PSIMD_PAIR_RR_SET 62, pmseq.dh, 0x80007fff, 0x80007fff, \ + 0x7fff8000, 0x7fff8000, 0, 0 + TEST_PSIMD_PAIR_RR_SET 63, pmslt.dh, 0x80007fff, 0x80007fff, \ + 0x7fff8000, 0x7fff8000, 0xffff0000, \ + 0xffff0000, 0 + TEST_PSIMD_PAIR_RR_SET 64, pmsltu.dh, 0x80007fff, 0x80007fff, \ + 0x7fff8000, 0x7fff8000, 0x0000ffff, \ + 0x0000ffff, 0 + + /* Double-wide word lanes verify low/high register ordering. */ + TEST_PSIMD_PAIR_RR_SET 65, pmin.dw, 0x7fffffff, 0x80000000, \ + 0x80000000, 0x7fffffff, 0x80000000, \ + 0x80000000, 0 + TEST_PSIMD_PAIR_RR_SET 66, pminu.dw, 0x7fffffff, 0x80000000, \ + 0x80000000, 0x7fffffff, 0x7fffffff, \ + 0x7fffffff, 0 + TEST_PSIMD_PAIR_RR_SET 67, pmax.dw, 0x7fffffff, 0x80000000, \ + 0x80000000, 0x7fffffff, 0x7fffffff, \ + 0x7fffffff, 0 + TEST_PSIMD_PAIR_RR_SET 68, pmaxu.dw, 0x7fffffff, 0x80000000, \ + 0x80000000, 0x7fffffff, 0x80000000, \ + 0x80000000, 0 + TEST_PSIMD_PAIR_RR_SET 69, pmseq.dw, 0x7fffffff, 0x80000000, \ + 0x80000000, 0x7fffffff, 0, 0 + TEST_PSIMD_PAIR_RR_SET 70, pmslt.dw, 0x7fffffff, 0x80000000, \ + 0x80000000, 0x7fffffff, 0, -1, 0 + TEST_PSIMD_PAIR_RR_SET 71, pmsltu.dw, 0x7fffffff, 0x80000000, \ + 0x80000000, 0x7fffffff, -1, 0, 0 + + /* Remaining wrapping double-wide add/sub lane widths. */ + TEST_PSIMD_PAIR_RR_SET 88, psub.db, 0x0304fefd, 0x0304fefd, \ + 0x0101ff01, 0x0101ff01, 0x0203fffc, \ + 0x0203fffc, 0 + TEST_PSIMD_PAIR_RR_SET 89, padd.dh, 0x7fff8000, 0x7fff8000, \ + 0x00018000, 0x00018000, 0x80000000, \ + 0x80000000, 0 + TEST_PSIMD_PAIR_RR_SET 90, psub.dh, 0x7fff8000, 0x7fff8000, \ + 0x00018000, 0x00018000, 0x7ffe0000, \ + 0x7ffe0000, 0 + TEST_PSIMD_PAIR_RR_SET 91, padd.dw, 0x7fffffff, 0x80000000, \ + 0x00000001, 0x80000000, 0x80000000, 0, 0 + TEST_PSIMD_PAIR_RR_SET 92, psub.dw, 0x7fffffff, 0x80000000, \ + 0x00000001, 0x80000000, 0x7ffffffe, 0, 0 + + /* Saturated byte register-pair operations. */ + TEST_PSIMD_PAIR_SAT_RR_SET 93, psadd.db, \ + 0x0102fefe, 0x0102fefe, 0x01010101, 0x01010101, \ + 0x0203ffff, 0x0203ffff, \ + 0x7f7f7f7f, 0x7f7f7f7f, 0x01010101, 0x01010101, \ + 0x7f7f7f7f, 0x7f7f7f7f, \ + 0x80808080, 0x80808080, -1, -1, 0x80808080, 0x80808080 + TEST_PSIMD_PAIR_SAT_RR_SET 94, psaddu.db, \ + 0x0102fefe, 0x0102fefe, 0x01010101, 0x01010101, \ + 0x0203ffff, 0x0203ffff, \ + -1, -1, 0x01010101, 0x01010101, -1, -1, \ + 0xf0f0f0f0, 0xf0f0f0f0, 0x20202020, 0x20202020, -1, -1 + TEST_PSIMD_PAIR_SAT_RR_SET 95, pssub.db, \ + 0x0304fefd, 0x0304fefd, 0x0101ff01, 0x0101ff01, \ + 0x0203fffc, 0x0203fffc, \ + 0x7f7f7f7f, 0x7f7f7f7f, -1, -1, 0x7f7f7f7f, 0x7f7f7f7f, \ + 0x80808080, 0x80808080, 0x01010101, 0x01010101, \ + 0x80808080, 0x80808080 + TEST_PSIMD_PAIR_SAT_RR_SET 96, pssubu.db, \ + 0x0304fefd, 0x0304fefd, 0x01010101, 0x01010101, \ + 0x0203fdfc, 0x0203fdfc, \ + 0, 0, 0x01010101, 0x01010101, 0, 0, \ + 0x000100ff, 0x000100ff, 0x01020001, 0x01020001, \ + 0x000000fe, 0x000000fe + + /* Saturated halfword register-pair operations. */ + TEST_PSIMD_PAIR_SAT_RR_SET 97, psadd.dh, \ + 0x00010002, 0x00010002, 0x00030004, 0x00030004, \ + 0x00040006, 0x00040006, \ + 0x7fff7fff, 0x7fff7fff, 0x00010001, 0x00010001, \ + 0x7fff7fff, 0x7fff7fff, \ + 0x80008000, 0x80008000, -1, -1, 0x80008000, 0x80008000 + TEST_PSIMD_PAIR_SAT_RR_SET 98, psaddu.dh, \ + 0x00010002, 0x00010002, 0x00030004, 0x00030004, \ + 0x00040006, 0x00040006, \ + -1, -1, 0x00010001, 0x00010001, -1, -1, \ + 0xf000f000, 0xf000f000, 0x20002000, 0x20002000, -1, -1 + TEST_PSIMD_PAIR_SAT_RR_SET 99, pssub.dh, \ + 0x00040006, 0x00040006, 0x00010004, 0x00010004, \ + 0x00030002, 0x00030002, \ + 0x7fff7fff, 0x7fff7fff, -1, -1, 0x7fff7fff, 0x7fff7fff, \ + 0x80008000, 0x80008000, 0x00010001, 0x00010001, \ + 0x80008000, 0x80008000 + TEST_PSIMD_PAIR_SAT_RR_SET 100, pssubu.dh, \ + 0x00040006, 0x00040006, 0x00010004, 0x00010004, \ + 0x00030002, 0x00030002, \ + 0, 0, 0x00010001, 0x00010001, 0, 0, \ + 0x000100ff, 0x000100ff, 0x00020001, 0x00020001, \ + 0x000000fe, 0x000000fe + + /* Saturated word register-pair operations. */ + TEST_PSIMD_PAIR_SAT_RR_SET 101, psadd.dw, \ + 1, 2, 3, 4, 4, 6, \ + 0x7fffffff, 0x7fffffff, 1, 1, 0x7fffffff, 0x7fffffff, \ + 0x80000000, 0x80000000, -1, -1, 0x80000000, 0x80000000 + TEST_PSIMD_PAIR_SAT_RR_SET 102, psaddu.dw, \ + 1, 2, 3, 4, 4, 6, \ + -1, -1, 1, 1, -1, -1, \ + 0xf0000000, 0xf0000000, 0x20000000, 0x20000000, -1, -1 + TEST_PSIMD_PAIR_SAT_RR_SET 103, pssub.dw, \ + 4, 6, 1, 4, 3, 2, \ + 0x7fffffff, 0x7fffffff, -1, -1, 0x7fffffff, 0x7fffffff, \ + 0x80000000, 0x80000000, 1, 1, 0x80000000, 0x80000000 + TEST_PSIMD_PAIR_SAT_RR_SET 104, pssubu.dw, \ + 4, 6, 1, 4, 3, 2, \ + 0, 0, 1, 1, 0, 0, \ + 1, 0xff, 2, 1, 0, 0xfe + + /* RV32 scalar saturation covers XLEN-wide signed/unsigned bounds. */ + TEST_PSIMD_SAT_RR_SET 105, sadd, 1, 2, 3, \ + 0x7fffffff, 1, 0x7fffffff, \ + 0x80000000, -1, 0x80000000 + TEST_PSIMD_SAT_RR_SET 106, saddu, 1, 2, 3, \ + -1, 1, -1, 0xf0000000, 0x20000000, -1 + TEST_PSIMD_SAT_RR_SET 107, ssub, 4, 1, 3, \ + 0x7fffffff, -1, 0x7fffffff, \ + 0x80000000, 1, 0x80000000 + TEST_PSIMD_SAT_RR_SET 108, ssubu, 4, 1, 3, \ + 0, 1, 0, 1, 2, 0 + + /* RV32 XLEN-wide signed/unsigned averaging and saturated shift-add. */ + TEST_PSIMD_RR_SET 125, aadd, 0x40000000, 0x80000000, 0xe0000000 + TEST_PSIMD_RR_SET 126, aaddu, 0x40000000, 0x80000000, 0x60000000 + TEST_PSIMD_RR_SET 127, asub, 0x80000000, 0x40000000, 0xa0000000 + TEST_PSIMD_RR_SET 128, asubu, 0x80000000, 0x40000000, 0x20000000 + TEST_PSIMD_SAT_RR_SET 129, ssh1sadd, 1, 2, 4, \ + 0x40000000, 0, 0x7fffffff, \ + 0xc0000000, -1, 0x80000000 + + /* Byte double-wide signed/unsigned average operations. */ + TEST_PSIMD_PAIR_RR_SET 130, paadd.db, \ + 0x7f120003, 0x7f120003, \ + 0x7f340007, 0x7f340007, \ + 0x7f230005, 0x7f230005, 0 + TEST_PSIMD_PAIR_RR 130, paadd.db, 0x7f7f7f7f, 0x7f7f7f7f, \ + 0x80808080, 0x80808080, -1, -1 + TEST_PSIMD_PAIR_RR_SET 131, paaddu.db, \ + 0x7f120003, 0x7f120003, \ + 0x7f340007, 0x7f340007, \ + 0x7f230005, 0x7f230005, 0 + TEST_PSIMD_PAIR_RR 131, paaddu.db, -1, -1, \ + 0x01010101, 0x01010101, \ + 0x80808080, 0x80808080 + TEST_PSIMD_PAIR_RR_SET 132, pasub.db, \ + 0xffff0000, 0xffff0000, \ + 0x11110001, 0x11110001, \ + 0xf7f700ff, 0xf7f700ff, 0 + TEST_PSIMD_PAIR_RR 132, pasub.db, 0x80808080, 0x80808080, \ + 0x7f7f7f7f, 0x7f7f7f7f, \ + 0x80808080, 0x80808080 + TEST_PSIMD_PAIR_RR_SET 133, pasubu.db, \ + 0xffff0000, 0xffff0000, \ + 0x11110001, 0x11110001, \ + 0x777700ff, 0x777700ff, 0 + TEST_PSIMD_PAIR_RR 133, pasubu.db, -1, -1, 0, 0, \ + 0x7f7f7f7f, 0x7f7f7f7f + + /* Halfword double-wide signed/unsigned average operations. */ + TEST_PSIMD_PAIR_RR_SET 134, paadd.dh, \ + 0x7f120003, 0x7f120003, \ + 0x7f340007, 0x7f340007, \ + 0x7f230005, 0x7f230005, 0 + TEST_PSIMD_PAIR_RR 134, paadd.dh, 0x7fff7fff, 0x7fff7fff, \ + 0x80008000, 0x80008000, -1, -1 + TEST_PSIMD_PAIR_RR_SET 135, paaddu.dh, \ + 0x7f120003, 0x7f120003, \ + 0x7f340007, 0x7f340007, \ + 0x7f230005, 0x7f230005, 0 + TEST_PSIMD_PAIR_RR 135, paaddu.dh, -1, -1, \ + 0x00010001, 0x00010001, \ + 0x80008000, 0x80008000 + TEST_PSIMD_PAIR_RR_SET 136, pasub.dh, \ + 0xffff0000, 0xffff0000, \ + 0x11110001, 0x11110001, \ + 0xf777ffff, 0xf777ffff, 0 + TEST_PSIMD_PAIR_RR 136, pasub.dh, 0x80008000, 0x80008000, \ + 0x7fff7fff, 0x7fff7fff, \ + 0x80008000, 0x80008000 + TEST_PSIMD_PAIR_RR_SET 137, pasubu.dh, \ + 0xffff0000, 0xffff0000, \ + 0x11110001, 0x11110001, \ + 0x7777ffff, 0x7777ffff, 0 + TEST_PSIMD_PAIR_RR 137, pasubu.dh, -1, -1, 0, 0, \ + 0x7fff7fff, 0x7fff7fff + + /* Word double-wide averages use distinct low/high source registers. */ + TEST_PSIMD_PAIR_RR_SET 138, paadd.dw, \ + 0xffffff78, 0xffffff12, \ + 0xffffff9a, 0xffffff34, \ + 0xffffff89, 0xffffff23, 0 + TEST_PSIMD_PAIR_RR 138, paadd.dw, 0x7fffffff, 0x7fffffff, \ + 0x80000000, 0x80000000, -1, -1 + TEST_PSIMD_PAIR_RR_SET 139, paaddu.dw, \ + 0xffffff78, 0xffffff12, \ + 0xffffff9a, 0xffffff34, \ + 0xffffff89, 0xffffff23, 0 + TEST_PSIMD_PAIR_RR 139, paaddu.dw, -1, -1, 1, 1, \ + 0x80000000, 0x80000000 + TEST_PSIMD_PAIR_RR_SET 140, pasub.dw, \ + 1, 0, -1, 1, 1, -1, 0 + TEST_PSIMD_PAIR_RR 140, pasub.dw, 0x80000000, 0x80000000, \ + 0x7fffffff, 0x7fffffff, \ + 0x80000000, 0x80000000 + TEST_PSIMD_PAIR_RR_SET 141, pasubu.dw, \ + 1, 0, -1, 1, 0x80000001, -1, 0 + TEST_PSIMD_PAIR_RR 141, pasubu.dw, -1, -1, 0, 0, \ + 0x7fffffff, 0x7fffffff + + /* Double-wide shift-one add, wrapping and saturating. */ + TEST_PSIMD_PAIR_RR_SET 142, psh1add.dh, \ + 0x01010101, 0x02020202, \ + 0x01010101, 0x03030303, \ + 0x03030303, 0x07070707, 0 + TEST_PSIMD_PAIR_RR_SET 143, psh1add.dw, \ + 1, 2, 3, 4, 5, 8, 0 + TEST_PSIMD_PAIR_SAT_RR_SET 144, pssh1sadd.dh, \ + 0x00010001, 0x00020002, 0x00020002, 0x00030003, \ + 0x00040004, 0x00070007, \ + 0x40004000, 0x40004000, 0, 0, 0x7fff7fff, 0x7fff7fff, \ + 0xc000c000, 0xc000c000, -1, -1, 0x80008000, 0x80008000 + TEST_PSIMD_PAIR_SAT_RR_SET 145, pssh1sadd.dw, \ + 1, 2, 2, 3, 4, 7, \ + 0x40000000, 0x40000000, 0, 0, 0x7fffffff, 0x7fffffff, \ + 0xc0000000, 0xc0000000, -1, -1, 0x80000000, 0x80000000 + + /* Pair shifts use distinct low/high registers and overlap rd with rs1= . */ + TEST_PSIMD_PAIR_SHIFT_RR_SET 190, psll.dbs, \ + 0x807f1201, 0xff400a05, 0x00fe2402, 0xfe80140a, \ + 7, 0x00800080, 0x80000080 + TEST_PSIMD_PAIR_SHIFT_RR_SET 191, psrl.dbs, \ + 0x807f1201, 0xff400a05, 0x403f0900, 0x7f200502, \ + 7, 0x01000000, 0x01000000 + TEST_PSIMD_PAIR_SHIFT_RR_SET 192, psra.dbs, \ + 0x807f1201, 0xff400a05, 0xc03f0900, 0xff200502, \ + 7, 0xff000000, 0xff000000 + TEST_PSIMD_PAIR_SHIFT_RI_SET 193, pslli.db, \ + 0x807f1201, 0xff400a05, 0x00fe2402, 0xfe80140a, \ + 7, 0x00800080, 0x80000080 + TEST_PSIMD_PAIR_SHIFT_RI_SET 194, psrli.db, \ + 0x807f1201, 0xff400a05, 0x403f0900, 0x7f200502, \ + 7, 0x01000000, 0x01000000 + TEST_PSIMD_PAIR_SHIFT_RI_SET 195, psrai.db, \ + 0x807f1201, 0xff400a05, 0xc03f0900, 0xff200502, \ + 7, 0xff000000, 0xff000000 + + TEST_PSIMD_PAIR_SHIFT_RR_SET 196, psll.dhs, \ + 0x80017fff, 0x0003fffe, 0x0002fffe, 0x0006fffc, \ + 15, 0x80008000, 0x80000000 + TEST_PSIMD_PAIR_SHIFT_RR_SET 197, psrl.dhs, \ + 0x80017fff, 0x0003fffe, 0x40003fff, 0x00017fff, \ + 15, 0x00010000, 0x00000001 + TEST_PSIMD_PAIR_SHIFT_RR_SET 198, psra.dhs, \ + 0x80017fff, 0x0003fffe, 0xc0003fff, 0x0001ffff, \ + 15, 0xffff0000, 0x0000ffff + TEST_PSIMD_PAIR_SHIFT_RI_SET 199, pslli.dh, \ + 0x80017fff, 0x0003fffe, 0x0002fffe, 0x0006fffc, \ + 15, 0x80008000, 0x80000000 + TEST_PSIMD_PAIR_SHIFT_RI_SET 200, psrli.dh, \ + 0x80017fff, 0x0003fffe, 0x40003fff, 0x00017fff, \ + 15, 0x00010000, 0x00000001 + TEST_PSIMD_PAIR_SHIFT_RI_SET 201, psrai.dh, \ + 0x80017fff, 0x0003fffe, 0xc0003fff, 0x0001ffff, \ + 15, 0xffff0000, 0x0000ffff + + TEST_PSIMD_PAIR_SHIFT_RR_SET 202, psll.dws, \ + 0x80000001, 0x7fffffff, 0x00000002, 0xfffffffe, \ + 31, 0x80000000, 0x80000000 + TEST_PSIMD_PAIR_SHIFT_RR_SET 203, psrl.dws, \ + 0x80000001, 0x7fffffff, 0x40000000, 0x3fffffff, \ + 31, 1, 0 + TEST_PSIMD_PAIR_SHIFT_RR_SET 204, psra.dws, \ + 0x80000001, 0x7fffffff, 0xc0000000, 0x3fffffff, \ + 31, -1, 0 + TEST_PSIMD_PAIR_SHIFT_RI_SET 205, pslli.dw, \ + 0x80000001, 0x7fffffff, 0x00000002, 0xfffffffe, \ + 31, 0x80000000, 0x80000000 + TEST_PSIMD_PAIR_SHIFT_RI_SET 206, psrli.dw, \ + 0x80000001, 0x7fffffff, 0x40000000, 0x3fffffff, \ + 31, 1, 0 + TEST_PSIMD_PAIR_SHIFT_RI_SET 207, psrai.dw, \ + 0x80000001, 0x7fffffff, 0xc0000000, 0x3fffffff, \ + 31, -1, 0 + + /* Scalar halfword-selection multiply validates all source selectors. = */ + TEST_PSIMD_RR_SET 360, mul.h00, 0xffff7fff, 0xffff7fff, \ + 0x3fff0001 + TEST_PSIMD_RR_SET 361, mul.h01, 0xffff7fff, 0x7fffffff, \ + 0x3fff0001 + TEST_PSIMD_RR_SET 362, mul.h11, 0x7fffffff, 0x7fffffff, \ + 0x3fff0001 + TEST_PSIMD_RR_SET 363, mulsu.h00, 0x8000ffff, 0x7fff8000, \ + 0xffff8000 + TEST_PSIMD_RR_SET 364, mulsu.h11, 0x8000ffff, 0x7fff8000, \ + 0xc0008000 + TEST_PSIMD_RR_SET 365, mulu.h00, 0x8000ffff, 0x7fff8000, \ + 0x7fff8000 + TEST_PSIMD_RR_SET 366, mulu.h01, 0x8000ffff, 0x7fff8000, \ + 0x7ffe8001 + TEST_PSIMD_RR_SET 367, mulu.h11, 0x8000ffff, 0x7fff8000, \ + 0x3fff8000 + TEST_PSIMD_RR_SET 380, mulhr, 1, -1, 0 + TEST_PSIMD_RR_SET 381, mulhrsu, 1, -1, 1 + TEST_PSIMD_RR_SET 382, mulhru, -1, -1, -2 + TEST_PSIMD_SAT_RR_SET 387, mulq, 1, 0x40000000, 0, \ + 0x80000000, 0x80000000, 0x7fffffff, \ + 0x80000000, 0x80000000, 0x7fffffff + TEST_PSIMD_SAT_RR_SET 388, mulqr, 1, 0x40000000, 1, \ + 0x80000000, 0x80000000, 0x7fffffff, \ + 0x80000000, 0x80000000, 0x7fffffff + TEST_PSIMD_RR_SET 397, mulh.h0, 1, 0x0000ffff, -1 + TEST_PSIMD_RR_SET 398, mulh.h1, 1, 0xffff0000, -1 + TEST_PSIMD_RR_SET 399, mulhsu.h0, 0x7fffffff, 0x0000ffff, \ + 0x7fff7fff + TEST_PSIMD_RR_SET 400, mulhsu.h1, 0x80000000, 0xffff0000, \ + 0x80008000 + + /* Pair signed variable shifts cover saturating left and rounded right= . */ + TEST_PSIMD_PAIR_VAR_SAT_SET 340, pssha.dhs, \ + 0x0001ffff, 0x0002fffe, 0x0002fffe, 0x0004fffc, \ + 0x40004000, 0x40004000, 0x7fff7fff, 0x7fff7fff, \ + 0xbfffbfff, 0xbfffbfff, 0x80008000, 0x80008000 + TEST_PSIMD_PAIR_SHIFT_RR_VXSAT_STATE 340, pssha.dhs, \ + 0x0003fffc, 0x00050004, -1, \ + 0x0001fffe, 0x00020002, 0, 0 + TEST_PSIMD_PAIR_VAR_SAT_SET 341, psshar.dhs, \ + 0x0001ffff, 0x0002fffe, 0x0002fffe, 0x0004fffc, \ + 0x40004000, 0x40004000, 0x7fff7fff, 0x7fff7fff, \ + 0xbfffbfff, 0xbfffbfff, 0x80008000, 0x80008000 + TEST_PSIMD_PAIR_SHIFT_RR_VXSAT_STATE 341, psshar.dhs, \ + 0x0003fffc, 0x00050004, -1, \ + 0x0002fffe, 0x00030002, 0, 0 + TEST_PSIMD_PAIR_VAR_SAT_SET 342, pssha.dws, \ + 1, -1, 2, -2, \ + 0x40000000, 0x40000000, 0x7fffffff, 0x7fffffff, \ + 0xbfffffff, 0xbfffffff, 0x80000000, 0x80000000 + TEST_PSIMD_PAIR_SHIFT_RR_VXSAT_STATE 342, pssha.dws, \ + 3, -4, -1, 1, -2, 0, 0 + TEST_PSIMD_PAIR_VAR_SAT_SET 343, psshar.dws, \ + 1, -1, 2, -2, \ + 0x40000000, 0x40000000, 0x7fffffff, 0x7fffffff, \ + 0xbfffffff, 0xbfffffff, 0x80000000, 0x80000000 + TEST_PSIMD_PAIR_SHIFT_RR_VXSAT_STATE 343, psshar.dws, \ + 3, -4, -1, 2, -2, 0, 0 + + /* Pair signed/unsigned saturation checks all lanes and sticky vxsat. = */ + /* Signed operands specify width; the encoded immediate is width - 1. = */ + TEST_PSIMD_PAIR_SAT_RI_SET 319, psati.dh, 5, \ + 0x000ffff0, 0xfff0000f, 0x000ffff0, 0xfff0000f, \ + 0x00100010, 0x00100010, 0x000f000f, 0x000f000f, \ + 0xffefffef, 0xffefffef, 0xfff0fff0, 0xfff0fff0 + TEST_PSIMD_PAIR_SAT_RI_SET 320, psati.dw, 5, \ + 15, -16, 15, -16, 16, 16, 15, 15, -17, -17, -16, -16 + TEST_PSIMD_PAIR_SAT_RI_SET 321, pusati.dh, 4, \ + 0x000f0000, 0x0000000f, 0x000f0000, 0x0000000f, \ + 0x00100010, 0x00100010, 0x000f000f, 0x000f000f, \ + -1, -1, 0, 0 + TEST_PSIMD_PAIR_SAT_RI_SET 322, pusati.dw, 4, \ + 15, 0, 15, 0, 16, 16, 15, 15, -1, -1, 0, 0 + TEST_PSIMD_PAIR_RI_VXSAT_STATE 319, psati.dh, \ + 0x7fff8000, 0x0001ffff, 16, \ + 0x7fff8000, 0x0001ffff, 0, 0 + TEST_PSIMD_PAIR_RI_VXSAT_STATE 320, psati.dw, \ + 0x7fffffff, 0x80000000, 32, \ + 0x7fffffff, 0x80000000, 0, 0 + TEST_PSIMD_PAIR_RI_VXSAT_STATE 321, pusati.dh, \ + 0x7fff0000, 0x00010001, 15, \ + 0x7fff0000, 0x00010001, 0, 0 + TEST_PSIMD_PAIR_RI_VXSAT_STATE 322, pusati.dw, \ + 0x7fffffff, 0, 31, 0x7fffffff, 0, 0, 0 + TEST_PSIMD_PAIR_SAT_RI_SET 326, psslai.dh, 1, \ + 0x0001ffff, 0x0002fffe, 0x0002fffe, 0x0004fffc, \ + 0x40004000, 0x40004000, 0x7fff7fff, 0x7fff7fff, \ + 0xbfffbfff, 0xbfffbfff, 0x80008000, 0x80008000 + TEST_PSIMD_PAIR_SAT_RI_SET 327, psslai.dw, 1, \ + 1, -1, 2, -2, \ + 0x40000000, 0x40000000, 0x7fffffff, 0x7fffffff, \ + 0xbfffffff, 0xbfffffff, 0x80000000, 0x80000000 + TEST_PSIMD_PAIR_RI_VXSAT_STATE 326, psslai.dh, \ + 0, 0, 15, 0, 0, 0, 0 + TEST_PSIMD_PAIR_RI_VXSAT_STATE 327, psslai.dw, \ + 0, 0, 31, 0, 0, 0, 0 + + /* Full register-pair arithmetic checks carry, borrow, and pair aliase= s. */ + TEST_PSIMD_PAIR_RR_SET 303, addd, -1, 0, 1, 0, 0, 1, 0 + TEST_PSIMD_PAIR_RR_SET 304, subd, 0, 1, 1, 0, -1, 0, 0 + + /* Signed/unsigned widen results deliberately differ in the high word.= */ + TEST_PSIMD_WIDE_RR_SET 305, wadd, -1, -1, -2, -1 + TEST_PSIMD_WIDE_RR_SET 306, waddu, -1, -1, -2, 1 + TEST_PSIMD_WIDE_RR_SET 307, wsub, -1, 1, -2, -1 + TEST_PSIMD_WIDE_RR_SET 308, wsubu, -1, 1, -2, 0 + + /* Accumulating forms start from the nonzero 64-bit value five. */ + TEST_PSIMD_WIDE_ACC_RR_SET 309, wadda, 5, 0, -1, -1, 3, 0, \ + 0xfffffffd, 0, 0xfffffffd, 0 + TEST_PSIMD_WIDE_ACC_RR 309, wadda, -1, -1, 0, 0, -1, -1 + TEST_PSIMD_WIDE_ACC_RR_SET 310, waddau, 5, 0, -1, -1, 3, 2, \ + 0xfffffffd, 2, 0xfffffffd, 2 + TEST_PSIMD_WIDE_ACC_RR_SET 311, wsuba, 5, 0, -1, 1, 3, 0, \ + 0xfffffffd, 0, 0xffffffff, 0xffffffff + TEST_PSIMD_WIDE_ACC_RR_SET 312, wsubau, 5, 0, -1, 1, 3, 1, \ + 0xfffffffd, 1, 0xffffffff, 0 + + /* Pair immediates cover zero, one, signed extrema, and encoding high = bits. */ + TEST_PSIMD_PAIR_LI_SET 286, pli.db, 0x01010101, 255, -1, 0, 0 + TEST_PSIMD_PAIR_LI_SET 287, pli.dh, 0x00010001, 511, \ + 0x01ff01ff, -512, 0xfe00fe00 + TEST_PSIMD_PAIR_LI_SET 288, plui.dh, 0x00400040, 511, \ + 0x7fc07fc0, -512, 0x80008000 + + /* Pair sign extension verifies each extracted element and output orde= r. */ + TEST_PSIMD_PAIR_R_SET 289, psext.dh.b, 0x007f0080, 0x000100ff, \ + 0x007fff80, 0x0001ffff + TEST_PSIMD_PAIR_R_SET 290, psext.dw.b, 0x00000080, 0x0000007f, \ + 0xffffff80, 0x0000007f + TEST_PSIMD_PAIR_R_SET 291, psext.dw.h, 0x0000ffff, 0x00008000, \ + -1, 0xffff8000 + + /* Double-wide pair/merge verifies both register halves and overlap. */ + TEST_PSIMD_PAIR_RR_SET 271, ppaire.db, \ + 0x11223344, 0x55667788, 0xaabbccdd, 0xddeeff00, \ + 0xbb22dd44, 0xee660088, 0 + TEST_PSIMD_PAIR_RR_SET 272, ppaireo.db, \ + 0x11223344, 0x55667788, 0xaabbccdd, 0xddeeff00, \ + 0xaa22cc44, 0xdd66ff88, 0 + TEST_PSIMD_PAIR_RR_SET 273, ppairoe.db, \ + 0x11223344, 0x55667788, 0xaabbccdd, 0xddeeff00, \ + 0xbb11dd33, 0xee550077, 0 + TEST_PSIMD_PAIR_RR_SET 274, ppairo.db, \ + 0x11223344, 0x55667788, 0xaabbccdd, 0xddeeff00, \ + 0xaa11cc33, 0xdd55ff77, 0 + TEST_PSIMD_PAIR_RR_SET 275, ppaire.dh, \ + 0x11223344, 0x55667788, 0xaabbccdd, 0xddeeff00, \ + 0xccdd3344, 0xff007788, 0 + TEST_PSIMD_PAIR_RR_SET 276, ppaireo.dh, \ + 0x11223344, 0x55667788, 0xaabbccdd, 0xddeeff00, \ + 0xaabb3344, 0xddee7788, 0 + TEST_PSIMD_PAIR_RR_SET 277, ppairoe.dh, \ + 0x11223344, 0x55667788, 0xaabbccdd, 0xddeeff00, \ + 0xccdd1122, 0xff005566, 0 + TEST_PSIMD_PAIR_RR_SET 278, ppairo.dh, \ + 0x11223344, 0x55667788, 0xaabbccdd, 0xddeeff00, \ + 0xaabb1122, 0xddee5566, 0 + + /* Signed narrowing clip: exact bounds plus both overflow directions. = */ + TEST_PSIMD_PAIR_CLIP_RI_SET 231, pnclipi.b, \ + 0x00feff00, 0x0002fffe, 1, 0x01ff7f80, \ + 0x0100fefe, 0x7fff8000, 0x7f807f80 + TEST_PSIMD_PAIR_CLIP_RR_SET 232, pnclip.bs, \ + 0x00feff00, 0x0002fffe, 1, 0x01ff7f80, \ + 0x0100fefe, 0x7fff8000, 0x7f807f80 + TEST_PSIMD_PAIR_CLIP_RI_SET 233, pnclipri.b, \ + 0x00fdff01, 0x0001fffd, 1, 0x01ff7f81, \ + 0x00fffefd, 0x7fff8000, 0x7f807f80 + TEST_PSIMD_PAIR_CLIP_RR_SET 234, pnclipr.bs, \ + 0x00fdff01, 0x0001fffd, 1, 0x01ff7f81, \ + 0x00fffefd, 0x7fff8000, 0x7f807f80 + + TEST_PSIMD_PAIR_CLIP_RI_SET 235, pnclipi.h, \ + 0xffff0000, 0x0000fffe, 1, 0x7fff8000, \ + 0xfffefffe, 0x00010000, 0x7fff8000 + TEST_PSIMD_PAIR_CLIP_RR_SET 236, pnclip.hs, \ + 0xffff0000, 0x0000fffe, 1, 0x7fff8000, \ + 0xfffefffe, 0x00010000, 0x7fff8000 + TEST_PSIMD_PAIR_CLIP_RI_SET 237, pnclipri.h, \ + 0xffff0001, 0x0000fffd, 1, 0x7fff8001, \ + 0xfffefffd, 0x0000ffff, 0x7fff8000 + TEST_PSIMD_PAIR_CLIP_RR_SET 238, pnclipr.hs, \ + 0xffff0001, 0x0000fffd, 1, 0x7fff8001, \ + 0xfffefffd, 0x0000ffff, 0x7fff8000 + + TEST_PSIMD_PAIR_CLIP_RI_SET 239, nclipi, \ + 0xfffffffe, -1, 1, 0xffffffff, \ + 0, 1, 0x7fffffff + TEST_PSIMD_PAIR_NARROW_RI_VXSAT_STATE 239, nclipi, 0, -2, 1, \ + 0x80000000, 0, 1 + TEST_PSIMD_PAIR_CLIP_RR_SET 240, nclip, \ + 0xfffffffe, -1, 1, 0xffffffff, \ + 0, 1, 0x7fffffff + TEST_PSIMD_PAIR_NARROW_RR_VXSAT_STATE 240, nclip, 0, -2, 1, \ + 0x80000000, 0, 1 + TEST_PSIMD_PAIR_CLIP_RI_SET 241, nclipri, \ + 0xffffffff, -1, 1, 0, \ + 1, 2, 0x7fffffff + TEST_PSIMD_PAIR_NARROW_RI_VXSAT_STATE 241, nclipri, 0, -2, 1, \ + 0x80000000, 0, 1 + TEST_PSIMD_PAIR_CLIP_RR_SET 242, nclipr, \ + 0xffffffff, -1, 1, 0, \ + 1, 2, 0x7fffffff + TEST_PSIMD_PAIR_NARROW_RR_VXSAT_STATE 242, nclipr, 0, -2, 1, \ + 0x80000000, 0, 1 + + /* Unsigned clip uses logical shifts; high-bit inputs are not negative= . */ + TEST_PSIMD_PAIR_CLIP_RI_SET 243, pnclipiu.b, \ + 0x01fe0000, 0x00030002, 1, 0x0101ff00, \ + 0x02000000, 0xffff0400, 0xffffff00 + TEST_PSIMD_PAIR_CLIP_RR_SET 244, pnclipu.bs, \ + 0x01fe0000, 0x00030002, 1, 0x0101ff00, \ + 0x02000000, 0xffff0400, 0xffffff00 + TEST_PSIMD_PAIR_CLIP_RI_SET 245, pnclipriu.b, \ + 0x01fd0000, 0x00030002, 1, 0x0201ff00, \ + 0x01ff0000, 0xffff0400, 0xffffff00 + TEST_PSIMD_PAIR_CLIP_RR_SET 246, pnclipru.bs, \ + 0x01fd0000, 0x00030002, 1, 0x0201ff00, \ + 0x01ff0000, 0xffff0400, 0xffffff00 + + TEST_PSIMD_PAIR_CLIP_RI_SET 247, pnclipiu.h, \ + 0x0001fffe, 2, 1, 0x0001ffff, \ + 0x00020000, 0xffffffff, 0xffffffff + TEST_PSIMD_PAIR_CLIP_RR_SET 248, pnclipu.hs, \ + 0x0001fffe, 2, 1, 0x0001ffff, \ + 0x00020000, 0xffffffff, 0xffffffff + TEST_PSIMD_PAIR_CLIP_RI_SET 249, pnclipriu.h, \ + 0x0001fffd, 3, 1, 0x0002ffff, \ + 0x0001ffff, 0xffffffff, 0xffffffff + TEST_PSIMD_PAIR_CLIP_RR_SET 250, pnclipru.hs, \ + 0x0001fffd, 3, 1, 0x0002ffff, \ + 0x0001ffff, 0xffffffff, 0xffffffff + + TEST_PSIMD_PAIR_CLIP_RI_SET 251, nclipiu, \ + 0xfffffffe, 1, 1, 0xffffffff, 0, 2, -1 + TEST_PSIMD_PAIR_CLIP_RR_SET 252, nclipu, \ + 0xfffffffe, 1, 1, 0xffffffff, 0, 2, -1 + TEST_PSIMD_PAIR_CLIP_RI_SET 253, nclipriu, \ + 0xfffffffd, 1, 1, 0xffffffff, 0xffffffff, 3, -1 + TEST_PSIMD_PAIR_CLIP_RR_SET 254, nclipru, \ + 0xfffffffd, 1, 1, 0xffffffff, 0xffffffff, 3, -1 + + /* Narrowing shifts pack pair lanes in low-to-high source order. */ + TEST_PSIMD_PAIR_NARROW_RI_SET 213, pnsrli.b, \ + 0x0003fffc, 0x80017fff, 0x01ff03fc, 0x00ff01fe, \ + 15, 0x01000001 + pnsrli.b a0, zero, 1 + PSIMD_FAIL_IF_NE a0, zero, 213 + TEST_PSIMD_PAIR_NARROW_RR_SET 214, pnsrl.bs, \ + 0x0003fffc, 0x80017fff, 0x01ff03fc, 0x00ff01fe, \ + 15, 0x01000001 + TEST_PSIMD_PAIR_NARROW_RI_SET 215, pnsrai.b, \ + 0x0003fffc, 0x80017fff, 0x01ff03fc, 0x00ff01fe, \ + 15, 0xff0000ff + TEST_PSIMD_PAIR_NARROW_RR_SET 216, pnsra.bs, \ + 0x0003fffc, 0x80017fff, 0x01ff03fc, 0x00ff01fe, \ + 15, 0xff0000ff + TEST_PSIMD_PAIR_NARROW_RI_SET 217, pnsrari.b, \ + 0x0003fffc, 0x80017fff, 0x01ff03fc, 0x010002fe, \ + 15, 0xff010000 + TEST_PSIMD_PAIR_NARROW_RR_SET 218, pnsrar.bs, \ + 0x0003fffc, 0x80017fff, 0x01ff03fc, 0x010002fe, \ + 15, 0xff010000 + + TEST_PSIMD_PAIR_NARROW_RI_SET 219, pnsrli.h, \ + 0x80000003, 0x7ffffffc, 0xfffc0003, 0xfffe0001, \ + 31, 1 + TEST_PSIMD_PAIR_NARROW_RR_SET 220, pnsrl.hs, \ + 0x80000003, 0x7ffffffc, 0xfffc0003, 0xfffe0001, \ + 31, 1 + TEST_PSIMD_PAIR_NARROW_RI_SET 221, pnsrai.h, \ + 0x80000003, 0x7ffffffc, 0xfffc0003, 0xfffe0001, \ + 31, 0x0000ffff + TEST_PSIMD_PAIR_NARROW_RR_SET 222, pnsra.hs, \ + 0x80000003, 0x7ffffffc, 0xfffc0003, 0xfffe0001, \ + 31, 0x0000ffff + TEST_PSIMD_PAIR_NARROW_RI_SET 223, pnsrari.h, \ + 0x80000003, 0x7ffffffc, 0xfffc0003, 0xfffe0002, \ + 31, 0x0001ffff + TEST_PSIMD_PAIR_NARROW_RR_SET 224, pnsrar.hs, \ + 0x80000003, 0x7ffffffc, 0xfffc0003, 0xfffe0002, \ + 31, 0x0001ffff + + TEST_PSIMD_PAIR_NARROW_RI_SET 225, nsrli, \ + 3, 0x80000001, 3, 0x80000001, 63, 1 + TEST_PSIMD_PAIR_NARROW_RR_SET 226, nsrl, \ + 3, 0x80000001, 3, 0x80000001, 63, 1 + TEST_PSIMD_PAIR_NARROW_RI_SET 227, nsrai, \ + 3, 0x80000001, 3, 0x80000001, 63, -1 + TEST_PSIMD_PAIR_NARROW_RR_SET 228, nsra, \ + 3, 0x80000001, 3, 0x80000001, 63, -1 + TEST_PSIMD_PAIR_NARROW_RI_SET 229, nsrari, \ + 3, 0x80000001, 3, 0x80000002, 63, -1 + TEST_PSIMD_PAIR_NARROW_RR_SET 230, nsrar, \ + 3, 0x80000001, 3, 0x80000002, 63, -1 + + /* Pair rounded shifts cover guard zero/one and signed negative lanes.= */ + TEST_PSIMD_PAIR_SHIFT_RI_SET 211, psrari.dh, \ + 0xfffd0002, 0x80017fff, 0xffff0001, 0xc0014000, \ + 15, 0, 0xffff0001 + TEST_PSIMD_PAIR_SHIFT_RI_SET 212, psrari.dw, \ + 0x80000001, 0x7fffffff, 0xc0000001, 0x40000000, \ + 31, -1, 1 + + /* Double-wide absolute difference verifies low/high pair ordering. */ + TEST_PSIMD_PAIR_RR_SET 162, pabd.db, 0x7f7f01ff, 0x807f0201, \ + 0x7f70ff7e, 0x018001ff, \ + 0x000f027f, 0x81ff0102, 0 + TEST_PSIMD_PAIR_RR_SET 163, pabdu.db, 0x807f01ff, 0x807f0201, \ + 0x7f01fffe, 0x018001ff, \ + 0x017efe01, 0x7f0101fe, 0 + TEST_PSIMD_PAIR_RR_SET 164, pabd.dh, 0x00017fff, 0xfffe7fff, \ + 0x00020001, 0x00010001, \ + 0x00017ffe, 0x00037ffe, 0 + TEST_PSIMD_PAIR_RR_SET 165, pabdu.dh, 0xfffe7fff, 0x00020002, \ + 0x00010001, 0x00010004, \ + 0xfffd7ffe, 0x00010002, 0 + + TEST_PSIMD_PAIR_SAT_R_SET 166, psabs.db, \ + 0x7fff0181, 0x01ff7f81, 0x7f01017f, 0x01017f7f, \ + 0x80008000, 0x00800080, 0x7f007f00, 0x007f007f + TEST_PSIMD_PAIR_SAT_R_SET 167, psabs.dh, \ + 0x7fffffff, 0x0001ffff, 0x7fff0001, 0x00010001, \ + 0x80000001, 0x00018000, 0x7fff0001, 0x00017fff + + /* Pair reductions use all eight bytes/four halfwords and scalar rs2. = */ + TEST_PSIMD_PAIR_REDUCE 168, predsum.dbs, 0x0403fe01, \ + 0x807f02ff, 0xa, 0x10 + TEST_PSIMD_PAIR_REDUCE 169, predsumu.dbs, 0x0403fe01, \ + 0x807f02ff, 0xa, 0x310 + TEST_PSIMD_PAIR_REDUCE 170, predsum.dhs, 0x0403fe01, \ + 0x807f02ff, 0xa, 0xffff858c + TEST_PSIMD_PAIR_REDUCE 171, predsumu.dhs, 0x0403fe01, \ + 0x807f02ff, 0xa, 0x0001858c + + /* + * Widening multiply: every source lane differs, so these values also + * check lane placement and the low/high destination-register ordering. + * The SET form additionally covers zero and rd overlap with each sour= ce. + */ + TEST_PSIMD_WIDE_RR_SET 401, pwmul.b, 0x7f80ff01, 0x0203fe04, \ + 0x00020004, 0x00fefe80 + TEST_PSIMD_WIDE_RR_SET 402, pwmulsu.b, 0x7f80ff01, 0x0203fe04, \ + 0xff020004, 0x00fefe80 + TEST_PSIMD_WIDE_RR_SET 403, pwmulu.b, 0x7f80ff01, 0x0203fe04, \ + 0xfd020004, 0x00fe0180 + TEST_PSIMD_WIDE_RR_SET 404, pwmul.h, 0x7fff8000, 0x0002ffff, \ + 0x00008000, 0x0000fffe + TEST_PSIMD_WIDE_RR_SET 405, pwmulsu.h, 0x7fff8000, 0x0002ffff, \ + 0x80008000, 0x0000fffe + TEST_PSIMD_WIDE_RR_SET 406, pwmulu.h, 0x7fff8000, 0x0002ffff, \ + 0x7fff8000, 0x0000fffe + + /* Full-width products distinguish signed, signed/unsigned and unsigne= d. */ + TEST_PSIMD_WIDE_RR_SET 407, wmul, 0x80000000, 3, \ + 0x80000000, 0xfffffffe + TEST_PSIMD_WIDE_RR_SET 408, wmulsu, -2, 0xffffffff, \ + 2, 0xfffffffe + TEST_PSIMD_WIDE_RR_SET 409, wmulu, 0xffffffff, 2, \ + 0xfffffffe, 1 + + /* Packed widening add/sub: signedness changes the widened upper bits.= */ + TEST_PSIMD_WIDE_RR_SET 418, pwadd.b, 0x7f80ff01, 0x0203fe04, \ + 0xfffd0005, 0x0081ff83 + TEST_PSIMD_WIDE_RR_SET 419, pwaddu.b, 0x7f80ff01, 0x0203fe04, \ + 0x01fd0005, 0x00810083 + TEST_PSIMD_WIDE_RR_SET 420, pwsub.b, 0x7f80ff01, 0x0203fe04, \ + 0x0001fffd, 0x007dff7d + TEST_PSIMD_WIDE_RR_SET 421, pwsubu.b, 0x7f80ff01, 0x0203fe04, \ + 0x0001fffd, 0x007d007d + TEST_PSIMD_WIDE_RR_SET 422, pwadd.h, 0x7fff8000, 0x0002ffff, \ + 0xffff7fff, 0x00008001 + TEST_PSIMD_WIDE_RR_SET 423, pwaddu.h, 0x7fff8000, 0x0002ffff, \ + 0x00017fff, 0x00008001 + TEST_PSIMD_WIDE_RR_SET 424, pwsub.h, 0x8000ffff, 0x00017fff, \ + 0xffff8000, 0xffff7fff + TEST_PSIMD_WIDE_RR_SET 425, pwsubu.h, 0x8000ffff, 0x00017fff, \ + 0x00008000, 0x00007fff + + /* Accumulating forms start from distinct nonzero widened lanes. */ + TEST_PSIMD_WIDE_ACC_RR_SET 426, pwadda.b, \ + 0x000a0001, 0x03e8fffb, 0x7f80ff01, 0x0203fe04, \ + 0x00070006, 0x0469ff7e, 0x7f7dff06, 0x0469ff7e, \ + 0x0200fe09, 0x0469ff7e + TEST_PSIMD_WIDE_ACC_RR_SET 427, pwaddau.b, \ + 0x000a0001, 0x03e8fffb, 0x7f80ff01, 0x0203fe04, \ + 0x02070006, 0x0469007e, 0x817dff06, 0x0469007e, \ + 0x0400fe09, 0x0469007e + TEST_PSIMD_WIDE_ACC_RR_SET 428, pwsuba.b, \ + 0x000a0001, 0x03e8fffb, 0x7f80ff01, 0x0203fe04, \ + 0x000bfffe, 0x0465ff78, 0x7f81fefe, 0x0465ff78, \ + 0x0204fe01, 0x0465ff78 + TEST_PSIMD_WIDE_ACC_RR_SET 429, pwsubau.b, \ + 0x000a0001, 0x03e8fffb, 0x7f80ff01, 0x0203fe04, \ + 0x000bfffe, 0x04650078, 0x7f81fefe, 0x04650078, \ + 0x0204fe01, 0x04650078 + TEST_PSIMD_WIDE_ACC_RR_SET 430, pwadda.h, \ + 5, -7, 0x7fff8000, 0x0002ffff, \ + 0xffff8004, 0x00007ffa, 0x7ffeffff, 0x00007ffa, \ + 0x00027ffe, 0x00007ffa + TEST_PSIMD_WIDE_ACC_RR_SET 431, pwaddau.h, \ + 5, -7, 0x7fff8000, 0x0002ffff, \ + 0x00018004, 0x00007ffa, 0x8000ffff, 0x00007ffa, \ + 0x00047ffe, 0x00007ffa + TEST_PSIMD_WIDE_ACC_RR_SET 432, pwsuba.h, \ + 5, -7, 0x8000ffff, 0x00017fff, \ + 0xffff8005, 0xffff7ff8, 0x80007fff, 0xffff7ff8, \ + 0x0000ffff, 0xffff7ff8 + TEST_PSIMD_WIDE_ACC_RR_SET 433, pwsubau.h, \ + 5, -7, 0x8000ffff, 0x00017fff, \ + 0x00008005, 0x00007ff8, 0x80017fff, 0x00007ff8, \ + 0x0001ffff, 0x00007ff8 + + /* Scalar halfword MAC selection, modulo-32 accumulation and rd aliase= s. */ + TEST_PSIMD_ACC_RR_SET 434, macc.h00, 0x7ffffffd, \ + 0x8002fffd, 0x0004ffff, 0x80000000, \ + 0x80030000, 0x00050002 + TEST_PSIMD_ACC_RR_SET 435, macc.h01, 0x7ffffffd, \ + 0x8002fffd, 0x0004ffff, 0x7ffffff1, \ + 0x8002fff1, 0x0004fff3 + TEST_PSIMD_ACC_RR_SET 436, macc.h11, 0x7ffffffd, \ + 0x8002fffd, 0x0004ffff, 0x7ffe0005, \ + 0x80010005, 0x00030007 + TEST_PSIMD_ACC_RR_SET 437, maccsu.h00, 0x7ffffffd, \ + 0x8002fffd, 0x0004ffff, 0x7ffd0000, \ + 0x80000000, 0x00020002 + TEST_PSIMD_ACC_RR_SET 438, maccsu.h11, 0x7ffffffd, \ + 0x8002fffd, 0x0004ffff, 0x7ffe0005, \ + 0x80010005, 0x00030007 + TEST_PSIMD_ACC_RR_SET 439, maccu.h00, 0x7ffffffd, \ + 0x8002fffd, 0x0004ffff, 0x7ffc0000, \ + 0x7fff0000, 0x00010002 + TEST_PSIMD_ACC_RR_SET 440, maccu.h01, 0x7ffffffd, \ + 0x8002fffd, 0x0004ffff, 0x8003fff1, \ + 0x8006fff1, 0x0008fff3 + TEST_PSIMD_ACC_RR_SET 441, maccu.h11, 0x7ffffffd, \ + 0x8002fffd, 0x0004ffff, 0x80020005, \ + 0x80050005, 0x00070007 + + /* Multiply-high accumulation; rounded lanes straddle the guard bit. */ + TEST_PSIMD_ACC_RR_SET 5, pmhacc.h, 0xfffe0001, \ + 0x8001ffff, 0x7fff8000, 0xbffe0001, \ + 0x4001ffff, 0x3fff8000 + TEST_PSIMD_ACC_RR_SET 451, pmhaccsu.h, 0xfffe0001, \ + 0x8001ffff, 0x7fff8000, 0xbffe0000, \ + 0x4001fffe, 0x3fff7fff + TEST_PSIMD_ACC_RR_SET 452, pmhaccu.h, 0xfffe0001, \ + 0x8001ffff, 0x7fff8000, 0x3ffd8000, \ + 0xc0007ffe, 0xbffeffff + TEST_PSIMD_ACC_RR_SET 453, pmhracc.h, 0xfffe0001, \ + 0x8001ffff, 0x7fff8000, 0xbfff0002, \ + 0x40020000, 0x40008001 + TEST_PSIMD_ACC_RR_SET 454, pmhraccsu.h, 0xfffe0001, \ + 0x8001ffff, 0x7fff8000, 0xbfff0001, \ + 0x4002ffff, 0x40008000 + TEST_PSIMD_ACC_RR_SET 455, pmhraccu.h, 0xfffe0001, \ + 0x8001ffff, 0x7fff8000, 0x3ffe8001, \ + 0xc0017fff, 0xbfff0000 + + /* Scalar high-half MAC: product low word is exactly the rounding guar= d. */ + TEST_PSIMD_ACC_RR_SET 456, mhacc, 0x7fffffff, \ + 0x80000000, 0xffffffff, 0x7fffffff, \ + 0x80000000, 0xffffffff + TEST_PSIMD_ACC_RR_SET 457, mhaccsu, 0x7fffffff, \ + 0x80000000, 0xffffffff, 0xffffffff, \ + 0, 0x7fffffff + TEST_PSIMD_ACC_RR_SET 458, mhaccu, 0x7fffffff, \ + 0x80000000, 0xffffffff, 0xfffffffe, \ + 0xffffffff, 0x7ffffffe + TEST_PSIMD_ACC_RR_SET 459, mhracc, 0x7fffffff, \ + 0x80000000, 0xffffffff, 0x80000000, \ + 0x80000001, 0 + TEST_PSIMD_ACC_RR_SET 460, mhraccsu, 0x7fffffff, \ + 0x80000000, 0xffffffff, 0, \ + 1, 0x80000000 + TEST_PSIMD_ACC_RR_SET 461, mhraccu, 0x7fffffff, \ + 0x80000000, 0xffffffff, 0xffffffff, \ + 0, 0x7fffffff + + /* Halfword-by-selected-byte high products. */ + TEST_PSIMD_ACC_RR_SET 462, pmhacc.h.b0, 0xfffe0001, \ + 0x7fff8001, 0x02ff7f80, 0xff7e4000, \ + 0x7f7fc000, 0x027fbf7f + TEST_PSIMD_ACC_RR_SET 463, pmhacc.h.b1, 0xfffe0001, \ + 0x7fff8001, 0x02ff7f80, 0x00fdc081, \ + 0x80fe4081, 0x03fe4000 + TEST_PSIMD_ACC_RR_SET 464, pmhaccsu.h.b0, 0xfffe0001, \ + 0x7fff8001, 0x02ff7f80, 0x7f7dc001, \ + 0xff7e4001, 0x827e3f80 + TEST_PSIMD_ACC_RR_SET 465, pmhaccsu.h.b1, 0xfffe0001, \ + 0x7fff8001, 0x02ff7f80, 0x00fdc081, \ + 0x80fe4081, 0x03fe4000 + + /* Full word by selected halfword, extracting product bits [47:16]. */ + TEST_PSIMD_ACC_RR_SET 466, mhacc.h0, 0x7ffffffd, \ + 0x80000001, 0x0004ffff, 0x80007ffc, \ + 0x80008000, 0x00057ffe + TEST_PSIMD_ACC_RR_SET 467, mhacc.h1, 0x7ffffffd, \ + 0x80000001, 0x0004ffff, 0x7ffdfffd, \ + 0x7ffe0001, 0x0002ffff + TEST_PSIMD_ACC_RR_SET 468, mhaccsu.h0, 0x7ffffffd, \ + 0x80000001, 0x0004ffff, 0x00007ffd, \ + 0x00008001, 0x80057fff + TEST_PSIMD_ACC_RR_SET 469, mhaccsu.h1, 0x7ffffffd, \ + 0x80000001, 0x0004ffff, 0x7ffdfffd, \ + 0x7ffe0001, 0x0002ffff + + /* Q15 selected-halfword accumulation; H00 has a set rounding guard. */ + TEST_PSIMD_ACC_RR_SET 470, mqacc.h00, 0x7ffffffd, \ + 0x80004001, 0x80004000, 0x80001ffd, \ + 0x80006001, 0x80006000 + TEST_PSIMD_ACC_RR_SET 471, mqacc.h01, 0x7ffffffd, \ + 0x80004001, 0x80004000, 0x7fffbffc, \ + 0x80000000, 0x7fffffff + TEST_PSIMD_ACC_RR_SET 472, mqacc.h11, 0x7ffffffd, \ + 0x80004001, 0x80004000, 0x80007ffd, \ + 0x8000c001, 0x8000c000 + TEST_PSIMD_ACC_RR_SET 473, mqracc.h00, 0x7ffffffd, \ + 0x80004001, 0x80004000, 0x80001ffe, \ + 0x80006002, 0x80006001 + TEST_PSIMD_ACC_RR_SET 474, mqracc.h01, 0x7ffffffd, \ + 0x80004001, 0x80004000, 0x7fffbffc, \ + 0x80000000, 0x7fffffff + TEST_PSIMD_ACC_RR_SET 475, mqracc.h11, 0x7ffffffd, \ + 0x80004001, 0x80004000, 0x80007ffd, \ + 0x8000c001, 0x8000c000 + + /* Cross add/sub and signed averaging verify both source permutations.= */ + TEST_PSIMD_RR_SET 486, pas.hx, 0x7fff8001, 0x0003fffe, \ + 0x7ffd7ffe + TEST_PSIMD_RR_SET 487, psa.hx, 0x7fff8001, 0x0003fffe, \ + 0x80018004 + TEST_PSIMD_RR_SET 488, paas.hx, 0x7fff8001, 0x0003fffe, \ + 0x3ffebfff + TEST_PSIMD_RR_SET 489, pasa.hx, 0x7fff8001, 0x0003fffe, \ + 0x4000c002 + + /* Double-wide variants additionally check pair ordering and overlap. = */ + TEST_PSIMD_PAIR_RR_SET 490, pas.dhx, \ + 0x7fff8001, 0x00048002, 0x0003fffe, 0x7ffd0005, \ + 0x7ffd7ffe, 0x00090005, 0 + TEST_PSIMD_PAIR_RR_SET 491, psa.dhx, \ + 0x7fff8001, 0x00048002, 0x0003fffe, 0x7ffd0005, \ + 0x80018004, 0xffffffff, 0 + TEST_PSIMD_PAIR_RR_SET 492, paas.dhx, \ + 0x7fff8001, 0x00048002, 0x0003fffe, 0x7ffd0005, \ + 0x3ffebfff, 0x00048002, 0 + TEST_PSIMD_PAIR_RR_SET 493, pasa.dhx, \ + 0x7fff8001, 0x00048002, 0x0003fffe, 0x7ffd0005, \ + 0x4000c002, 0xffffffff, 0 + + /* Saturating cross operations cover normal, positive/negative overflo= w. */ + TEST_PSIMD_SAT_RR_SET 494, psas.hx, \ + 0xff380064, 0xffd8001e, 0xff56008c, \ + 0x7fff7fff, 0xffff0001, 0x7fff7fff, \ + 0x80008000, 0x0001ffff, 0x80008000 + TEST_PSIMD_SAT_RR_SET 495, pssa.hx, \ + 0xff380064, 0xffd8001e, 0xff1a003c, \ + 0x7fff7fff, 0x0001ffff, 0x7fff7fff, \ + 0x80008000, 0xffff0001, 0x80008000 + TEST_PSIMD_PAIR_SAT_RR_SET 496, psas.dhx, \ + 0xff380064, 0xfe70012c, 0xffd8001e, 0x003cffce, \ + 0xff56008c, 0xfe3e00f0, \ + 0x7fff7fff, 0x7fff7fff, 0xffff0001, 0xffff0001, \ + 0x7fff7fff, 0x7fff7fff, \ + 0x80008000, 0x80008000, 0x0001ffff, 0x0001ffff, \ + 0x80008000, 0x80008000 + TEST_PSIMD_PAIR_SAT_RR_SET 497, pssa.dhx, \ + 0xff380064, 0xfe70012c, 0xffd8001e, 0x003cffce, \ + 0xff1a003c, 0xfea20168, \ + 0x7fff7fff, 0x7fff7fff, 0x0001ffff, 0x0001ffff, \ + 0x7fff7fff, 0x7fff7fff, \ + 0x80008000, 0x80008000, 0xffff0001, 0xffff0001, \ + 0x80008000, 0x80008000 + + /* Two-product horizontal add/sub: direct and crossed pairings differ.= */ + TEST_PSIMD_RR_SET 498, pm2add.h, 0x0004fffd, 0xfffe0005, \ + 0xffffffe9 + TEST_PSIMD_RR_SET 499, pm2addsu.h, 0x0004fffd, 0xfffe0005, \ + 0x0003ffe9 + TEST_PSIMD_RR_SET 500, pm2addu.h, 0x0004fffd, 0xfffe0005, \ + 0x0008ffe9 + TEST_PSIMD_RR_SET 501, pm2add.hx, 0x0004fffd, 0xfffe0005, 0x1a + TEST_PSIMD_RR_SET 502, pm2sub.h, 0x0004fffd, 0xfffe0005, \ + 0xfffffff9 + TEST_PSIMD_RR_SET 503, pm2sub.hx, 0x0004fffd, 0xfffe0005, \ + 0xfffffff2 + /* PM2SADD cannot negatively overflow; -2147418112 is the exact minimu= m. */ + TEST_PSIMD_RR_VXSAT_STATE 510, pm2sadd.h, \ + 0x0004fffd, 0xfffe0005, -23, 0, 0 + TEST_PSIMD_RR_VXSAT_STATE 510, pm2sadd.h, \ + 0x80008000, 0x80008000, 0x7fffffff, 0, 1 + TEST_PSIMD_RR_VXSAT_STATE 510, pm2sadd.h, \ + 0x80008000, 0x7fff7fff, 0x80010000, 0, 0 + TEST_PSIMD_RR_VXSAT_STATE 510, pm2sadd.h, 0, 0, 0, 1, 1 + TEST_PSIMD_RR_RD_RS1 510, pm2sadd.h, \ + 0x0004fffd, 0xfffe0005, -23 + TEST_PSIMD_RR_RD_RS2 510, pm2sadd.h, \ + 0x0004fffd, 0xfffe0005, -23 + TEST_PSIMD_RR_VXSAT_STATE 511, pm2sadd.hx, \ + 0x0004fffd, 0xfffe0005, 26, 0, 0 + TEST_PSIMD_RR_VXSAT_STATE 511, pm2sadd.hx, \ + 0x80008000, 0x80008000, 0x7fffffff, 0, 1 + TEST_PSIMD_RR_VXSAT_STATE 511, pm2sadd.hx, \ + 0x80008000, 0x7fff7fff, 0x80010000, 0, 0 + TEST_PSIMD_RR_VXSAT_STATE 511, pm2sadd.hx, 0, 0, 0, 1, 1 + TEST_PSIMD_RR_RD_RS1 511, pm2sadd.hx, \ + 0x0004fffd, 0xfffe0005, 26 + TEST_PSIMD_RR_RD_RS2 511, pm2sadd.hx, \ + 0x0004fffd, 0xfffe0005, 26 + TEST_PSIMD_ACC_RR_SET 512, pm2adda.h, 0x7ffffffd, \ + 0x0004fffd, 0xfffe0005, 0x7fffffe6, 0x0004ffe6, 0xfffdffee + TEST_PSIMD_ACC_RR_SET 513, pm2addasu.h, 0x7ffffffd, \ + 0x0004fffd, 0xfffe0005, 0x8003ffe6, 0x0008ffe6, 0x0001ffee + TEST_PSIMD_ACC_RR_SET 514, pm2addau.h, 0x7ffffffd, \ + 0x0004fffd, 0xfffe0005, 0x8008ffe6, 0x000dffe6, 0x0006ffee + TEST_PSIMD_ACC_RR_SET 515, pm2adda.hx, 0x7ffffffd, \ + 0x0004fffd, 0xfffe0005, 0x80000017, 0x00050017, 0xfffe001f + TEST_PSIMD_ACC_RR_SET 516, pm2suba.h, 0x7ffffffd, \ + 0x0004fffd, 0xfffe0005, 0x7ffffff6, 0x0004fff6, 0xfffdfffe + TEST_PSIMD_ACC_RR_SET 517, pm2suba.hx, 0x7ffffffd, \ + 0x0004fffd, 0xfffe0005, 0x7fffffef, 0x0004ffef, 0xfffdfff7 + TEST_PSIMD_RR_SET 524, pm4add.b, 0xfc03fe01, 0x08f90605, \ + 0xffffffc4 + TEST_PSIMD_RR_SET 525, pm4addsu.b, 0xfc03fe01, 0x08f90605, \ + 0x000002c4 + TEST_PSIMD_RR_SET 526, pm4addu.b, 0xfc03fe01, 0x08f90605, \ + 0x000010c4 + TEST_PSIMD_ACC_RR_SET 527, pm4adda.b, 0x7ffffffd, \ + 0xfc03fe01, 0x08f90605, 0x7fffffc1, 0xfc03fdc5, 0x08f905c9 + TEST_PSIMD_ACC_RR_SET 528, pm4addasu.b, 0x7ffffffd, \ + 0xfc03fe01, 0x08f90605, 0x800002c1, 0xfc0400c5, 0x08f908c9 + TEST_PSIMD_ACC_RR_SET 529, pm4addau.b, 0x7ffffffd, \ + 0xfc03fe01, 0x08f90605, 0x800010c1, 0xfc040ec5, 0x08f916c9 + TEST_PSIMD_RR_SET 536, pmq2add.h, \ + 0x80004001, 0x80004000, 0x0000a000 + TEST_PSIMD_RR_SET 537, pmqr2add.h, \ + 0x80004001, 0x80004000, 0x0000a001 + TEST_PSIMD_ACC_RR_SET 538, pmq2adda.h, 0x7ffffffd, \ + 0x80004001, 0x80004000, 0x80009ffd, 0x8000e001, 0x8000e000 + TEST_PSIMD_ACC_RR_SET 539, pmqr2adda.h, 0x7ffffffd, \ + 0x80004001, 0x80004000, 0x80009ffe, 0x8000e002, 0x8000e001 + + /* Widening MACs keep independent low/high accumulator words. */ + TEST_PSIMD_WIDE_ACC_RR_SET 544, pwmacc.h, \ + 0x7ffffffd, 0xfffffffd, 0x7fff8000, 0x0002ffff, \ + 0x80007ffd, 0x0000fffb, 0x80000000, 0x0000fffb, \ + 0x00037fff, 0x0000fffb + TEST_PSIMD_WIDE_ACC_RR_SET 545, pwmaccsu.h, \ + 0x7ffffffd, 0xfffffffd, 0x7fff8000, 0x0002ffff, \ + 0x00007ffd, 0x0000fffb, 0, 0x0000fffb, \ + 0x80037fff, 0x0000fffb + TEST_PSIMD_WIDE_ACC_RR_SET 546, pwmaccu.h, \ + 0x7ffffffd, 0xfffffffd, 0x7fff8000, 0x0002ffff, \ + 0xffff7ffd, 0x0000fffb, 0xffff0000, 0x0000fffb, \ + 0x80027fff, 0x0000fffb + TEST_PSIMD_WIDE_ACC_RR_SET 547, wmacc, \ + 0xfffffffd, 0x7fffffff, 0x80000000, 3, \ + 0x7ffffffd, 0x7ffffffe, 0, 0x7ffffffe, \ + 0x80000003, 0x7ffffffd + TEST_PSIMD_WIDE_ACC_RR_SET 548, wmaccsu, \ + 0xfffffffd, 0x7fffffff, -2, 0xffffffff, \ + 0xffffffff, 0x7ffffffd, 0, 0x7ffffffe, \ + 1, 0x7ffffffe + TEST_PSIMD_WIDE_ACC_RR_SET 549, wmaccu, \ + 0xfffffffd, 0x7fffffff, 0xffffffff, 2, \ + 0xfffffffb, 0x80000001, 0xfffffffd, 0x80000001, \ + 0, 0x80000001 + + /* Two halfword products combine into one signed/unsigned 64-bit resul= t. */ + TEST_PSIMD_WIDE_RR_SET 550, pm2wadd.h, \ + 0x0004fffd, 0xfffe0005, 0xffffffe9, 0xffffffff + TEST_PSIMD_WIDE_RR_SET 551, pm2waddsu.h, \ + 0x0004fffd, 0xfffe0005, 0x0003ffe9, 0 + TEST_PSIMD_WIDE_RR_SET 552, pm2waddu.h, \ + 0x0004fffd, 0xfffe0005, 0x0008ffe9, 0 + TEST_PSIMD_WIDE_RR_SET 553, pm2wadd.hx, \ + 0x0004fffd, 0xfffe0005, 26, 0 + TEST_PSIMD_WIDE_RR_SET 554, pm2wsub.h, \ + 0x0004fffd, 0xfffe0005, -7, -1 + TEST_PSIMD_WIDE_RR_SET 555, pm2wsub.hx, \ + 0x0004fffd, 0xfffe0005, -14, -1 + TEST_PSIMD_WIDE_ACC_RR_SET 556, pm2wadda.h, \ + 0xfffffffd, 0x7fffffff, 0x0004fffd, 0xfffe0005, \ + 0xffffffe6, 0x7fffffff, 0x0004ffe6, 0x7fffffff, \ + 0xfffdffee, 0x7fffffff + TEST_PSIMD_WIDE_ACC_RR_SET 557, pm2waddasu.h, \ + 0xfffffffd, 0x7fffffff, 0x0004fffd, 0xfffe0005, \ + 0x0003ffe6, 0x80000000, 0x0008ffe6, 0x7fffffff, \ + 0x0001ffee, 0x80000000 + TEST_PSIMD_WIDE_ACC_RR_SET 558, pm2waddau.h, \ + 0xfffffffd, 0x7fffffff, 0x0004fffd, 0xfffe0005, \ + 0x0008ffe6, 0x80000000, 0x000dffe6, 0x7fffffff, \ + 0x0006ffee, 0x80000000 + TEST_PSIMD_WIDE_ACC_RR_SET 559, pm2wadda.hx, \ + 0xfffffffd, 0x7fffffff, 0x0004fffd, 0xfffe0005, \ + 0x00000017, 0x80000000, 0x00050017, 0x7fffffff, \ + 0xfffe001f, 0x7fffffff + TEST_PSIMD_WIDE_ACC_RR_SET 560, pm2wsuba.h, \ + 0xfffffffd, 0x7fffffff, 0x0004fffd, 0xfffe0005, \ + 0xfffffff6, 0x7fffffff, 0x0004fff6, 0x7fffffff, \ + 0xfffdfffe, 0x7fffffff + TEST_PSIMD_WIDE_ACC_RR_SET 561, pm2wsuba.hx, \ + 0xfffffffd, 0x7fffffff, 0x0004fffd, 0xfffe0005, \ + 0xffffffef, 0x7fffffff, 0x0004ffef, 0x7fffffff, \ + 0xfffdfff7, 0x7fffffff + TEST_PSIMD_RR_SET 562, padd.bs, 0xff807f01, 0xdeadbe80, 0x7f00ff81 + TEST_PSIMD_RR_SET 563, padd.hs, 0x7fff8001, 0xdead8000, 0xffff0001 + /* Widen before shifting: unsigned and signed forms differ at shift ze= ro. */ + TEST_PSIMD_WIDE_RI_SET 567, pwslli.b, 0x7f80ff01, \ + 0x00ff0001, 0x007f0080, 0x01fe0002, 0x00fe0100, \ + 15, 0x80008000, 0x80000000 + TEST_PSIMD_WIDE_RI_SET 568, pwslli.h, 0x7fff8001, \ + 0x00008001, 0x00007fff, 0x00010002, 0x0000fffe, \ + 31, 0x80000000, 0x80000000 + TEST_PSIMD_WIDE_RI_SET 569, wslli, 0x80000001, \ + 0x80000001, 0, 2, 1, 63, 0, 0x80000000 + TEST_PSIMD_WIDE_RI_SET 570, pwslai.b, 0x7f80ff01, \ + 0xffff0001, 0x007fff80, 0xfffe0002, 0x00feff00, \ + 15, 0x80008000, 0x80000000 + TEST_PSIMD_WIDE_RI_SET 571, pwslai.h, 0x7fff8001, \ + 0xffff8001, 0x00007fff, 0xffff0002, 0x0000fffe, \ + 31, 0x80000000, 0x80000000 + TEST_PSIMD_WIDE_RI_SET 572, wslai, 0x80000001, \ + 0x80000001, 0xffffffff, 2, 0xffffffff, \ + 63, 0, 0x80000000 + TEST_PSIMD_WIDE_RR_SET 573, pwsll.bs, \ + 0x7f80ff01, 1, 0x01fe0002, 0x00fe0100 + TEST_PSIMD_WIDE_RR 573, pwsll.bs, \ + 0x7f80ff01, 15, 0x80008000, 0x80000000 + TEST_PSIMD_WIDE_RR_SET 574, pwsll.hs, \ + 0x7fff8001, 1, 0x00010002, 0x0000fffe + TEST_PSIMD_WIDE_RR 574, pwsll.hs, \ + 0x7fff8001, 31, 0x80000000, 0x80000000 + TEST_PSIMD_WIDE_RR_SET 575, wsll, 0x80000001, 1, 2, 1 + TEST_PSIMD_WIDE_RR 575, wsll, 0x80000001, 63, 0, 0x80000000 + TEST_PSIMD_WIDE_RR_SET 576, pwsla.bs, \ + 0x7f80ff01, 1, 0xfffe0002, 0x00feff00 + TEST_PSIMD_WIDE_RR 576, pwsla.bs, \ + 0x7f80ff01, 15, 0x80008000, 0x80000000 + TEST_PSIMD_WIDE_RR_SET 577, pwsla.hs, \ + 0x7fff8001, 1, 0xffff0002, 0x0000fffe + TEST_PSIMD_WIDE_RR 577, pwsla.hs, \ + 0x7fff8001, 31, 0x80000000, 0x80000000 + TEST_PSIMD_WIDE_RR_SET 578, wsla, 0x80000001, 1, 2, 0xffffffff + TEST_PSIMD_WIDE_RR 578, wsla, 0x80000001, 63, 0, 0x80000000 + TEST_PSIMD_WIDE_RR_SET 579, wzip8p, \ + 0x44332211, 0x88776655, 0x66225511, 0x88447733 + TEST_PSIMD_WIDE_RR_SET 580, wzip16p, \ + 0x44332211, 0x88776655, 0x66552211, 0x88774433 + /* Extended shifts use the old rd and must snapshot aliased sources. */ + TEST_PSIMD_ACC_RR_SET 593, slx, 0x11223344, \ + 0x99aabb5a, 8, 0x22334499, 0xaabb5a99, 0x899 + TEST_PSIMD_ACC_RR_SET 594, srx, 0x11223344, \ + 0x99aabb5a, 8, 0x5a112233, 0x5a99aabb, 0x5a000000 + TEST_PSIMD_PAIR_SCALAR_RR_SET 564, padd.dbs, \ + 0xff807f01, 0x04030201, 0xdeadbe80, 0x7f00ff81, 0x84838281 + TEST_PSIMD_PAIR_SCALAR_RR_SET 565, padd.dhs, \ + 0x7fff8001, 0x00048002, 0xdead8000, 0xffff0001, 0x80040002 + TEST_PSIMD_PAIR_SCALAR_RR_SET 566, padd.dws, \ + 0x80000001, 0x7fffffff, 0x80000000, 1, 0xffffffff + + /* Pair selector zero supplies an all-zero source, including X1. */ + addi sp, sp, -16 + sw ra, 12(sp) + li ra, 0x12345678 + li a4, 0x80 + padd.dbs a0, zero, a4 + mv t4, a0 + mv t5, a1 + lw ra, 12(sp) + addi sp, sp, 16 + li t0, 0x80808080 + PSIMD_FAIL_IF_NE t4, t0, 564 + PSIMD_FAIL_IF_NE t5, t0, 564 + + /* Pair destination selector zero must suppress the write to X1 too. */ + addi sp, sp, -16 + sw ra, 12(sp) + li ra, 0x12345678 + li a2, 0x01020304 + li a3, 0x05060708 + li a4, 1 + padd.dbs zero, a2, a4 + mv t4, ra + lw ra, 12(sp) + addi sp, sp, 16 + li t0, 0x12345678 + PSIMD_FAIL_IF_NE t4, t0, 564 + + /* Every zero pair selector denotes { X[0], X[0] }, never { X[1], X[0]= }. */ + addi sp, sp, -16 + sw ra, 12(sp) + li ra, 0x12345678 + + /* Check both source positions in a three-pair instruction. */ + li a4, 0x01020304 + li a5, 0x10203040 + padd.db a0, zero, a4 + PSIMD_FAIL_IF_NE a0, a4, 610 + PSIMD_FAIL_IF_NE a1, a5, 610 + li a2, 0x11223344 + li a3, 0x55667788 + padd.db a0, a2, zero + PSIMD_FAIL_IF_NE a0, a2, 610 + PSIMD_FAIL_IF_NE a1, a3, 610 + + /* Cover concatenated, unary, immediate-shift, and arithmetic paths. */ + addd a0, zero, a4 + PSIMD_FAIL_IF_NE a0, a4, 610 + PSIMD_FAIL_IF_NE a1, a5, 610 + psext.dw.b a0, zero + PSIMD_FAIL_IF_NE a0, zero, 610 + PSIMD_FAIL_IF_NE a1, zero, 610 + pslli.dw a0, zero, 1 + PSIMD_FAIL_IF_NE a0, zero, 610 + PSIMD_FAIL_IF_NE a1, zero, 610 + pmin.dw a0, zero, a4 + PSIMD_FAIL_IF_NE a0, zero, 610 + PSIMD_FAIL_IF_NE a1, zero, 610 + + /* A zero destination suppresses both writes but not CSR side effects.= */ + pli.db zero, 1 + li t0, 0x12345678 + PSIMD_FAIL_IF_NE ra, t0, 610 + li a2, 0x7f7f7f7f + li a3, 0x7f7f7f7f + li a4, 0x01010101 + li a5, 0x01010101 + csrw vxsat, zero + psadd.db zero, a2, a4 + PSIMD_FAIL_IF_NE ra, t0, 610 + csrr t4, vxsat + li t5, 1 + PSIMD_FAIL_IF_NE t4, t5, 610 + + lw ra, 12(sp) + addi sp, sp, 16 + + /* Q15 lanes and Q31 scalar terms accumulate into an RV32 register pai= r. */ + TEST_PSIMD_WIDE_ACC_RR_SET 482, pmqwacc.h, \ + 0x7ffffffd, 0xfffffffd, 0x80004001, 0x80004000, \ + 0x80001ffd, 0x00007ffd, 0x80006001, 0x00007ffd, \ + 0x80006000, 0x00007ffd + TEST_PSIMD_WIDE_ACC_RR_SET 483, pmqrwacc.h, \ + 0x7ffffffd, 0xfffffffd, 0x80004001, 0x80004000, \ + 0x80001ffe, 0x00007ffd, 0x80006002, 0x00007ffd, \ + 0x80006001, 0x00007ffd + TEST_PSIMD_WIDE_ACC_RR_SET 484, mqwacc, \ + 0xfffffffd, 0x7fffffff, 0x40000001, 0x40000000, \ + 0x1ffffffd, 0x80000000, 0x60000001, 0x7fffffff, \ + 0x60000000, 0x7fffffff + TEST_PSIMD_WIDE_ACC_RR 484, mqwacc, 0, 0, \ + 0x80000000, 0x80000000, 0x80000000, 0 + TEST_PSIMD_WIDE_ACC_RR_SET 485, mqrwacc, \ + 0xfffffffd, 0x7fffffff, 0x40000001, 0x40000000, \ + 0x1ffffffe, 0x80000000, 0x60000002, 0x7fffffff, \ + 0x60000001, 0x7fffffff + TEST_PSIMD_WIDE_ACC_RR 485, mqrwacc, 0, 0, \ + 0x80000000, 0x80000000, 0x80000000, 0 + + /* LLVM RV32 encodes REV as 0x69f...; catches decoder-version skew. */ + TEST_PSIMD_R_SET 598, rev, 0x01234567, 0xe6a2c480 + + /* P v0.21 variable-shift mnemonics. */ + TEST_PSIMD_SAT_RR_SET 602, sshl, \ + 0x40000000, 1, 0x80000000, \ + 0x80000000, 1, -1, -1, 1, -1 + TEST_PSIMD_RR_VXSAT_STATE 602, sshl, \ + 0x80000001, -1, 0x40000000, 0, 0 + TEST_PSIMD_SAT_RR_SET 603, sshlr, \ + 0x40000000, 1, 0x80000000, \ + 0x80000000, 1, -1, -1, 1, -1 + TEST_PSIMD_RR_VXSAT_STATE 603, sshlr, \ + 0x80000003, -1, 0x40000002, 0, 0 + TEST_PSIMD_RR_VXSAT_STATE 603, sshlr, \ + 0x80000000, -33, 1, 0, 0 + + TEST_PSIMD_PAIR_VAR_SAT_SET 604, psshl.dhs, \ + 0x7ffe4000, 0x00020001, 0xfffc8000, 0x00040002, \ + 0x80004001, 0, 0xffff8002, 0, \ + 0xffff0001, 0, 0xffff0002, 0 + TEST_PSIMD_PAIR_SHIFT_RR_VXSAT_STATE 604, psshl.dhs, \ + 0x80017fff, 0xffff0002, -1, 0x40003fff, 0x7fff0001, 0, 0 + TEST_PSIMD_PAIR_VAR_SAT_SET 605, psshl.dws, \ + 0x40000000, 1, 0x80000000, 2, \ + 0x80000000, 0, -1, 0, -1, 0, -1, 0 + TEST_PSIMD_PAIR_SHIFT_RR_VXSAT_STATE 605, psshl.dws, \ + 0x80000001, 3, -1, 0x40000000, 1, 0, 0 + TEST_PSIMD_PAIR_VAR_SAT_SET 606, psshlr.dhs, \ + 0x7ffe4000, 0x00020001, 0xfffc8000, 0x00040002, \ + 0x80004001, 0, 0xffff8002, 0, \ + 0xffff0001, 0, 0xffff0002, 0 + TEST_PSIMD_PAIR_SHIFT_RR_VXSAT_STATE 606, psshlr.dhs, \ + 0x80030002, 0xffff0001, -1, 0x40020001, 0x80000001, 0, 0 + TEST_PSIMD_PAIR_VAR_SAT_SET 607, psshlr.dws, \ + 0x40000000, 1, 0x80000000, 2, \ + 0x80000000, 0, -1, 0, -1, 0, -1, 0 + TEST_PSIMD_PAIR_SHIFT_RR_VXSAT_STATE 607, psshlr.dws, \ + 0x80000003, 2, -1, 0x40000002, 1, 0, 0 + PSIMD_TEST_EXIT 0 + .size _start, .-_start + + PSIMD_DEFINE_FAILURE_HANDLER + + .section .note.GNU-stack,"",@progbits diff --git a/tests/tcg/riscv/psimd-rv64.S b/tests/tcg/riscv/psimd-rv64.S new file mode 100644 index 00000000000..ea1db55cd02 --- /dev/null +++ b/tests/tcg/riscv/psimd-rv64.S @@ -0,0 +1,578 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Basic RV64 P extension execution tests. */ + +#include "psimd-test-macros.inc" + + .text + .balign 4 + .globl _start + .type _start, @function +_start: +#include "psimd-common.S" + + /* + * Scalar word-selection products. Both input high words are nonzero; + * W00/W01/W11 therefore expose a wrong half selection immediately. + */ + TEST_PSIMD_RR_SET 410, mul.w00, \ + 0xfffffffdfffffffe, 0x00000004ffffffff, 2 + TEST_PSIMD_RR_SET 411, mul.w01, \ + 0xfffffffdfffffffe, 0x00000004ffffffff, -8 + TEST_PSIMD_RR_SET 412, mul.w11, \ + 0xfffffffdfffffffe, 0x00000004ffffffff, -12 + TEST_PSIMD_RR_SET 413, mulsu.w00, \ + 0xfffffffdfffffffe, 0x00000004ffffffff, \ + 0xfffffffe00000002 + TEST_PSIMD_RR_SET 414, mulsu.w11, \ + 0xfffffffdfffffffe, 0x00000004ffffffff, -12 + TEST_PSIMD_RR_SET 415, mulu.w00, \ + 0xfffffffdfffffffe, 0x00000004ffffffff, \ + 0xfffffffd00000002 + TEST_PSIMD_RR_SET 416, mulu.w01, \ + 0xfffffffdfffffffe, 0x00000004ffffffff, \ + 0x00000003fffffff8 + TEST_PSIMD_RR_SET 417, mulu.w11, \ + 0xfffffffdfffffffe, 0x00000004ffffffff, \ + 0x00000003fffffff4 + + /* Scalar word MAC selection, modulo-64 accumulation and rd aliases. */ + TEST_PSIMD_ACC_RR_SET 434, macc.w00, 0x7ffffffffffffffd, \ + 0x80000002fffffffd, 0x00000004ffffffff, \ + 0x8000000000000000, 0x8000000300000000, \ + 0x0000000500000002 + TEST_PSIMD_ACC_RR_SET 435, macc.w01, 0x7ffffffffffffffd, \ + 0x80000002fffffffd, 0x00000004ffffffff, \ + 0x7ffffffffffffff1, 0x80000002fffffff1, \ + 0x00000004fffffff3 + TEST_PSIMD_ACC_RR_SET 436, macc.w11, 0x7ffffffffffffffd, \ + 0x80000002fffffffd, 0x00000004ffffffff, \ + 0x7ffffffe00000005, 0x8000000100000005, \ + 0x0000000300000007 + TEST_PSIMD_ACC_RR_SET 437, maccsu.w00, 0x7ffffffffffffffd, \ + 0x80000002fffffffd, 0x00000004ffffffff, \ + 0x7ffffffd00000000, 0x8000000000000000, \ + 0x0000000200000002 + TEST_PSIMD_ACC_RR_SET 438, maccsu.w11, 0x7ffffffffffffffd, \ + 0x80000002fffffffd, 0x00000004ffffffff, \ + 0x7ffffffe00000005, 0x8000000100000005, \ + 0x0000000300000007 + TEST_PSIMD_ACC_RR_SET 439, maccu.w00, 0x7ffffffffffffffd, \ + 0x80000002fffffffd, 0x00000004ffffffff, \ + 0x7ffffffc00000000, 0x7fffffff00000000, \ + 0x0000000100000002 + TEST_PSIMD_ACC_RR_SET 440, maccu.w01, 0x7ffffffffffffffd, \ + 0x80000002fffffffd, 0x00000004ffffffff, \ + 0x80000003fffffff1, 0x80000006fffffff1, \ + 0x00000008fffffff3 + TEST_PSIMD_ACC_RR_SET 441, maccu.w11, 0x7ffffffffffffffd, \ + 0x80000002fffffffd, 0x00000004ffffffff, \ + 0x8000000200000005, 0x8000000500000005, \ + 0x0000000700000007 + + /* Packed halfword products accumulate independently into two words. */ + TEST_PSIMD_ACC_RR_SET 442, pmacc.w.h00, 0x800000057ffffffd, \ + 0x8002fffd7fff0002, 0x0004ffff00030005, \ + 0x8000000880000007, 0x800300007fff000c, \ + 0x000500020003000f + TEST_PSIMD_ACC_RR_SET 443, pmacc.w.h01, 0x800000057ffffffd, \ + 0x8002fffd7fff0002, 0x0004ffff00030005, \ + 0x7ffffff980000003, 0x8002fff17fff0008, \ + 0x0004fff30003000b + TEST_PSIMD_ACC_RR_SET 444, pmacc.w.h11, 0x800000057ffffffd, \ + 0x8002fffd7fff0002, 0x0004ffff00030005, \ + 0x7ffe000d80017ffa, 0x8001000580007fff, \ + 0x0003000700048002 + TEST_PSIMD_ACC_RR_SET 445, pmaccsu.w.h00, 0x800000057ffffffd, \ + 0x8002fffd7fff0002, 0x0004ffff00030005, \ + 0x7ffd000880000007, 0x800000007fff000c, \ + 0x000200020003000f + TEST_PSIMD_ACC_RR_SET 446, pmaccsu.w.h11, 0x800000057ffffffd, \ + 0x8002fffd7fff0002, 0x0004ffff00030005, \ + 0x7ffe000d80017ffa, 0x8001000580007fff, \ + 0x0003000700048002 + TEST_PSIMD_ACC_RR_SET 447, pmaccu.w.h00, 0x800000057ffffffd, \ + 0x8002fffd7fff0002, 0x0004ffff00030005, \ + 0x7ffc000880000007, 0x7fff00007fff000c, \ + 0x000100020003000f + TEST_PSIMD_ACC_RR_SET 448, pmaccu.w.h01, 0x800000057ffffffd, \ + 0x8002fffd7fff0002, 0x0004ffff00030005, \ + 0x8003fff980000003, 0x8006fff17fff0008, \ + 0x0008fff30003000b + TEST_PSIMD_ACC_RR_SET 449, pmaccu.w.h11, 0x800000057ffffffd, \ + 0x8002fffd7fff0002, 0x0004ffff00030005, \ + 0x8002000d80017ffa, 0x8005000580007fff, \ + 0x0007000700048002 + + /* Four distinct halfword lanes cover high-half and rounded extraction= . */ + TEST_PSIMD_ACC_RR_SET 5, pmhacc.h, 0xfffc0003fffe0001, \ + 0x7fff00028001ffff, 0x0004fffd7fff8000, \ + 0xfffd0002bffe0001, 0x800000014001ffff, \ + 0x0005fffc3fff8000 + TEST_PSIMD_ACC_RR_SET 451, pmhaccsu.h, 0xfffc0003fffe0001, \ + 0x7fff00028001ffff, 0x0004fffd7fff8000, \ + 0xfffd0004bffe0000, 0x800000034001fffe, \ + 0x0005fffe3fff7fff + TEST_PSIMD_ACC_RR_SET 452, pmhaccu.h, 0xfffc0003fffe0001, \ + 0x7fff00028001ffff, 0x0004fffd7fff8000, \ + 0xfffd00043ffd8000, 0x80000003c0007ffe, \ + 0x0005fffebffeffff + TEST_PSIMD_ACC_RR_SET 453, pmhracc.h, 0xfffc0003fffe0001, \ + 0x7fff00028001ffff, 0x0004fffd7fff8000, \ + 0xfffe0003bfff0002, 0x8001000240020000, \ + 0x0006fffd40008001 + TEST_PSIMD_ACC_RR_SET 454, pmhraccsu.h, 0xfffc0003fffe0001, \ + 0x7fff00028001ffff, 0x0004fffd7fff8000, \ + 0xfffe0005bfff0001, 0x800100044002ffff, \ + 0x0006ffff40008000 + TEST_PSIMD_ACC_RR_SET 455, pmhraccu.h, 0xfffc0003fffe0001, \ + 0x7fff00028001ffff, 0x0004fffd7fff8000, \ + 0xfffe00053ffe8001, 0x80010004c0017fff, \ + 0x0006ffffbfff0000 + + /* Packed word high-half MAC, with guard-bit rounding in both lanes. */ + TEST_PSIMD_ACC_RR_SET 456, pmhacc.w, 0xfffffffd7fffffff, \ + 0x8000000180000000, 0x80000000ffffffff, \ + 0x3ffffffc7fffffff, 0xc000000080000000, \ + 0xbfffffffffffffff + TEST_PSIMD_ACC_RR_SET 457, pmhaccsu.w, 0xfffffffd7fffffff, \ + 0x8000000180000000, 0x80000000ffffffff, \ + 0xbffffffdffffffff, 0x4000000100000000, \ + 0x400000007fffffff + TEST_PSIMD_ACC_RR_SET 458, pmhaccu.w, 0xfffffffd7fffffff, \ + 0x8000000180000000, 0x80000000ffffffff, \ + 0x3ffffffdfffffffe, 0xc0000001ffffffff, \ + 0xc00000007ffffffe + TEST_PSIMD_ACC_RR_SET 459, pmhracc.w, 0xfffffffd7fffffff, \ + 0x8000000180000000, 0x80000000ffffffff, \ + 0x3ffffffd80000000, 0xc000000180000001, \ + 0xc000000000000000 + TEST_PSIMD_ACC_RR_SET 460, pmhraccsu.w, 0xfffffffd7fffffff, \ + 0x8000000180000000, 0x80000000ffffffff, \ + 0xbffffffe00000000, 0x4000000200000001, \ + 0x4000000180000000 + TEST_PSIMD_ACC_RR_SET 461, pmhraccu.w, 0xfffffffd7fffffff, \ + 0x8000000180000000, 0x80000000ffffffff, \ + 0x3ffffffeffffffff, 0xc000000200000000, \ + 0xc00000017fffffff + + /* Four halfword-by-selected-byte lanes exercise B0/B1 independently. = */ + TEST_PSIMD_ACC_RR_SET 462, pmhacc.h.b0, 0xfffc0003fffe0001, \ + 0x0003fffe7fff8001, 0x04fe800102ff7f80, \ + 0xfffb0002ff7e4000, 0x0002fffd7f7fc000, \ + 0x04fd8000027fbf7f + TEST_PSIMD_ACC_RR_SET 463, pmhacc.h.b1, 0xfffc0003fffe0001, \ + 0x0003fffe7fff8001, 0x04fe800102ff7f80, \ + 0xfffc000400fdc081, 0x0003ffff80fe4081, \ + 0x04fe800203fe4000 + TEST_PSIMD_ACC_RR_SET 464, pmhaccsu.h.b0, 0xfffc0003fffe0001, \ + 0x0003fffe7fff8001, 0x04fe800102ff7f80, \ + 0xfffe00027f7dc001, 0x0005fffdff7e4001, \ + 0x05008000827e3f80 + TEST_PSIMD_ACC_RR_SET 465, pmhaccsu.h.b1, 0xfffc0003fffe0001, \ + 0x0003fffe7fff8001, 0x04fe800102ff7f80, \ + 0xfffc000200fdc081, 0x0003fffd80fe4081, \ + 0x04fe800003fe4000 + + /* Two full words multiply selected H0/H1 values and keep bits [47:16]= . */ + TEST_PSIMD_ACC_RR_SET 466, pmhacc.w.h0, 0xfffffffd7ffffffd, \ + 0x7fffffff80000001, 0x0004fffd0003ffff, \ + 0xfffe7ffd80007ffc, 0x7ffe7fff80008000, \ + 0x00037ffd00047ffe + TEST_PSIMD_ACC_RR_SET 467, pmhacc.w.h1, 0xfffffffd7ffffffd, \ + 0x7fffffff80000001, 0x0004fffd0003ffff, \ + 0x0001fffc7ffe7ffd, 0x8001fffe7ffe8001, \ + 0x0006fffc00027fff + TEST_PSIMD_ACC_RR_SET 468, pmhaccsu.w.h0, 0xfffffffd7ffffffd, \ + 0x7fffffff80000001, 0x0004fffd0003ffff, \ + 0x7ffe7ffc00007ffd, 0xfffe7ffe00008001, \ + 0x80037ffc80047fff + TEST_PSIMD_ACC_RR_SET 469, pmhaccsu.w.h1, 0xfffffffd7ffffffd, \ + 0x7fffffff80000001, 0x0004fffd0003ffff, \ + 0x0001fffc7ffe7ffd, 0x8001fffe7ffe8001, \ + 0x0006fffc00027fff + + /* Q31 selected-word accumulation; W00 distinguishes rounded extractio= n. */ + TEST_PSIMD_ACC_RR_SET 470, mqacc.w00, 0x7ffffffffffffffd, \ + 0x8000000040000001, 0x8000000040000000, \ + 0x800000001ffffffd, 0x8000000060000001, \ + 0x8000000060000000 + TEST_PSIMD_ACC_RR_SET 471, mqacc.w01, 0x7ffffffffffffffd, \ + 0x8000000040000001, 0x8000000040000000, \ + 0x7fffffffbffffffc, 0x8000000000000000, \ + 0x7fffffffffffffff + TEST_PSIMD_ACC_RR_SET 472, mqacc.w11, 0x7ffffffffffffffd, \ + 0x8000000040000001, 0x8000000040000000, \ + 0x800000007ffffffd, 0x80000000c0000001, \ + 0x80000000c0000000 + TEST_PSIMD_ACC_RR_SET 473, mqracc.w00, 0x7ffffffffffffffd, \ + 0x8000000040000001, 0x8000000040000000, \ + 0x800000001ffffffe, 0x8000000060000002, \ + 0x8000000060000001 + TEST_PSIMD_ACC_RR_SET 474, mqracc.w01, 0x7ffffffffffffffd, \ + 0x8000000040000001, 0x8000000040000000, \ + 0x7fffffffbffffffc, 0x8000000000000000, \ + 0x7fffffffffffffff + TEST_PSIMD_ACC_RR_SET 475, mqracc.w11, 0x7ffffffffffffffd, \ + 0x8000000040000001, 0x8000000040000000, \ + 0x800000007ffffffd, 0x80000000c0000001, \ + 0x80000000c0000000 + + /* Packed Q15 products accumulate into independent 32-bit lanes. */ + TEST_PSIMD_ACC_RR_SET 476, pmqacc.w.h00, 0xfffffffd7ffffffd, \ + 0x4001800080004001, 0x4000800080004000, \ + 0x00007ffd80001ffd, 0x4002000080006001, \ + 0x4001000080006000 + TEST_PSIMD_ACC_RR_SET 477, pmqacc.w.h01, 0xfffffffd7ffffffd, \ + 0x4001800080004001, 0x4000800080004000, \ + 0xffffbffd7fffbffc, 0x4001400080000000, \ + 0x400040007fffffff + TEST_PSIMD_ACC_RR_SET 478, pmqacc.w.h11, 0xfffffffd7ffffffd, \ + 0x4001800080004001, 0x4000800080004000, \ + 0x00001ffd80007ffd, 0x4001a0008000c001, \ + 0x4000a0008000c000 + TEST_PSIMD_ACC_RR_SET 479, pmqracc.w.h00, 0xfffffffd7ffffffd, \ + 0x4001800080004001, 0x4000800080004000, \ + 0x00007ffd80001ffe, 0x4002000080006002, \ + 0x4001000080006001 + TEST_PSIMD_ACC_RR_SET 480, pmqracc.w.h01, 0xfffffffd7ffffffd, \ + 0x4001800080004001, 0x4000800080004000, \ + 0xffffbffd7fffbffc, 0x4001400080000000, \ + 0x400040007fffffff + TEST_PSIMD_ACC_RR_SET 481, pmqracc.w.h11, 0xfffffffd7ffffffd, \ + 0x4001800080004001, 0x4000800080004000, \ + 0x00001ffe80007ffd, 0x4001a0018000c001, \ + 0x4000a0018000c000 + + /* Halfword and word cross operations use nonzero upper RV64 lanes. */ + TEST_PSIMD_RR_SET 486, pas.hx, \ + 0x000480027fff8001, 0x7ffd00050003fffe, \ + 0x000900057ffd7ffe + TEST_PSIMD_RR_SET 487, psa.hx, \ + 0x000480027fff8001, 0x7ffd00050003fffe, \ + 0xffffffff80018004 + TEST_PSIMD_RR_SET 488, paas.hx, \ + 0x000480027fff8001, 0x7ffd00050003fffe, \ + 0x000480023ffebfff + TEST_PSIMD_RR_SET 489, pasa.hx, \ + 0x000480027fff8001, 0x7ffd00050003fffe, \ + 0xffffffff4000c002 + TEST_PSIMD_RR_SET 490, pas.wx, \ + 0x7fffffff80000001, 0x00000003fffffffe, \ + 0x7ffffffd7ffffffe + TEST_PSIMD_RR_SET 491, psa.wx, \ + 0x7fffffff80000001, 0x00000003fffffffe, \ + 0x8000000180000004 + TEST_PSIMD_RR_SET 492, paas.wx, \ + 0x7fffffff80000001, 0x00000003fffffffe, \ + 0x3ffffffebfffffff + TEST_PSIMD_RR_SET 493, pasa.wx, \ + 0x7fffffff80000001, 0x00000003fffffffe, \ + 0x40000000c0000002 + + TEST_PSIMD_SAT_RR_SET 494, psas.hx, \ + 0xfe70012cff380064, 0x003cffceffd8001e, \ + 0xfe3e00f0ff56008c, \ + 0x7fff7fff7fff7fff, 0xffff0001ffff0001, \ + 0x7fff7fff7fff7fff, \ + 0x8000800080008000, 0x0001ffff0001ffff, \ + 0x8000800080008000 + TEST_PSIMD_SAT_RR_SET 495, pssa.hx, \ + 0xfe70012cff380064, 0x003cffceffd8001e, \ + 0xfea20168ff1a003c, \ + 0x7fff7fff7fff7fff, 0x0001ffff0001ffff, \ + 0x7fff7fff7fff7fff, \ + 0x8000800080008000, 0xffff0001ffff0001, \ + 0x8000800080008000 + TEST_PSIMD_SAT_RR_SET 496, psas.wx, \ + 0xfffff830000003e8, 0xfffffe700000012c, \ + 0xfffff95c00000578, \ + 0x7fffffff7fffffff, 0xffffffff00000001, \ + 0x7fffffff7fffffff, \ + 0x8000000080000000, 0x00000001ffffffff, \ + 0x8000000080000000 + TEST_PSIMD_SAT_RR_SET 497, pssa.wx, \ + 0xfffff830000003e8, 0xfffffe700000012c, \ + 0xfffff70400000258, \ + 0x7fffffff7fffffff, 0x00000001ffffffff, \ + 0x7fffffff7fffffff, \ + 0x8000000080000000, 0xffffffff00000001, \ + 0x8000000080000000 + + /* Two independent halfword groups and full-width word pairings. */ + TEST_PSIMD_RR_SET 498, pm2add.h, \ + 0xfffb00020004fffd, 0x0003fff9fffe0005, \ + 0xffffffe3ffffffe9 + TEST_PSIMD_RR_SET 499, pm2addsu.h, \ + 0xfffb00020004fffd, 0x0003fff9fffe0005, \ + 0x0001ffe30003ffe9 + TEST_PSIMD_RR_SET 500, pm2addu.h, \ + 0xfffb00020004fffd, 0x0003fff9fffe0005, \ + 0x0004ffe30008ffe9 + TEST_PSIMD_RR_SET 501, pm2add.hx, \ + 0xfffb00020004fffd, 0x0003fff9fffe0005, \ + 0x000000290000001a + TEST_PSIMD_RR_SET 502, pm2sub.h, \ + 0xfffb00020004fffd, 0x0003fff9fffe0005, \ + 0x00000001fffffff9 + TEST_PSIMD_RR_SET 503, pm2sub.hx, \ + 0xfffb00020004fffd, 0x0003fff9fffe0005, \ + 0xffffffe3fffffff2 + TEST_PSIMD_RR_SET 504, pm2add.w, \ + 0x00000004fffffffd, 0xfffffffe00000005, \ + 0xffffffffffffffe9 + TEST_PSIMD_RR_SET 505, pm2addsu.w, \ + 0x00000004fffffffd, 0xfffffffe00000005, \ + 0x00000003ffffffe9 + TEST_PSIMD_RR_SET 506, pm2addu.w, \ + 0x00000004fffffffd, 0xfffffffe00000005, \ + 0x00000008ffffffe9 + TEST_PSIMD_RR_SET 507, pm2add.wx, \ + 0x00000004fffffffd, 0xfffffffe00000005, 0x1a + TEST_PSIMD_RR_SET 508, pm2sub.w, \ + 0x00000004fffffffd, 0xfffffffe00000005, -7 + TEST_PSIMD_RR_SET 509, pm2sub.wx, \ + 0x00000004fffffffd, 0xfffffffe00000005, -14 + + TEST_PSIMD_RR_VXSAT_STATE 510, pm2sadd.h, \ + 0xfffb00020004fffd, 0x0003fff9fffe0005, \ + 0xffffffe3ffffffe9, 0, 0 + TEST_PSIMD_RR_VXSAT_STATE 510, pm2sadd.h, \ + 0x8000800080008000, 0x8000800080008000, \ + 0x7fffffff7fffffff, 0, 1 + TEST_PSIMD_RR_VXSAT_STATE 510, pm2sadd.h, \ + 0x8000800080008000, 0x7fff7fff7fff7fff, \ + 0x8001000080010000, 0, 0 + TEST_PSIMD_RR_VXSAT_STATE 510, pm2sadd.h, 0, 0, 0, 1, 1 + TEST_PSIMD_RR_RD_RS1 510, pm2sadd.h, \ + 0xfffb00020004fffd, 0x0003fff9fffe0005, \ + 0xffffffe3ffffffe9 + TEST_PSIMD_RR_RD_RS2 510, pm2sadd.h, \ + 0xfffb00020004fffd, 0x0003fff9fffe0005, \ + 0xffffffe3ffffffe9 + TEST_PSIMD_RR_VXSAT_STATE 511, pm2sadd.hx, \ + 0xfffb00020004fffd, 0x0003fff9fffe0005, \ + 0x000000290000001a, 0, 0 + TEST_PSIMD_RR_VXSAT_STATE 511, pm2sadd.hx, \ + 0x8000800080008000, 0x8000800080008000, \ + 0x7fffffff7fffffff, 0, 1 + TEST_PSIMD_RR_VXSAT_STATE 511, pm2sadd.hx, \ + 0x8000800080008000, 0x7fff7fff7fff7fff, \ + 0x8001000080010000, 0, 0 + TEST_PSIMD_RR_VXSAT_STATE 511, pm2sadd.hx, 0, 0, 0, 1, 1 + TEST_PSIMD_RR_RD_RS1 511, pm2sadd.hx, \ + 0xfffb00020004fffd, 0x0003fff9fffe0005, \ + 0x000000290000001a + TEST_PSIMD_RR_RD_RS2 511, pm2sadd.hx, \ + 0xfffb00020004fffd, 0x0003fff9fffe0005, \ + 0x000000290000001a + TEST_PSIMD_ACC_RR_SET 512, pm2adda.h, 0xfffffffd7ffffffd, \ + 0xfffb00020004fffd, 0x0003fff9fffe0005, \ + 0xffffffe07fffffe6, 0xfffaffe50004ffe6, 0x0003ffdcfffdffee + TEST_PSIMD_ACC_RR_SET 513, pm2addasu.h, 0xfffffffd7ffffffd, \ + 0xfffb00020004fffd, 0x0003fff9fffe0005, \ + 0x0001ffe08003ffe6, 0xfffcffe50008ffe6, 0x0005ffdc0001ffee + TEST_PSIMD_ACC_RR_SET 514, pm2addau.h, 0xfffffffd7ffffffd, \ + 0xfffb00020004fffd, 0x0003fff9fffe0005, \ + 0x0004ffe08008ffe6, 0xffffffe5000dffe6, 0x0008ffdc0006ffee + TEST_PSIMD_ACC_RR_SET 515, pm2adda.hx, 0xfffffffd7ffffffd, \ + 0xfffb00020004fffd, 0x0003fff9fffe0005, \ + 0x0000002680000017, 0xfffb002b00050017, 0x00040022fffe001f + TEST_PSIMD_ACC_RR_SET 516, pm2suba.h, 0xfffffffd7ffffffd, \ + 0xfffb00020004fffd, 0x0003fff9fffe0005, \ + 0xfffffffe7ffffff6, 0xfffb00030004fff6, 0x0003fffafffdfffe + TEST_PSIMD_ACC_RR_SET 517, pm2suba.hx, 0xfffffffd7ffffffd, \ + 0xfffb00020004fffd, 0x0003fff9fffe0005, \ + 0xffffffe07fffffef, 0xfffaffe50004ffef, 0x0003ffdcfffdfff7 + TEST_PSIMD_ACC_RR_SET 518, pm2adda.w, 0x7ffffffffffffffd, \ + 0x00000004fffffffd, 0xfffffffe00000005, \ + 0x7fffffffffffffe6, 0x00000004ffffffe6, 0xfffffffdffffffee + TEST_PSIMD_ACC_RR_SET 519, pm2addasu.w, 0x7ffffffffffffffd, \ + 0x00000004fffffffd, 0xfffffffe00000005, \ + 0x80000003ffffffe6, 0x00000008ffffffe6, 0x00000001ffffffee + TEST_PSIMD_ACC_RR_SET 520, pm2addau.w, 0x7ffffffffffffffd, \ + 0x00000004fffffffd, 0xfffffffe00000005, \ + 0x80000008ffffffe6, 0x0000000dffffffe6, 0x00000006ffffffee + TEST_PSIMD_ACC_RR_SET 521, pm2adda.wx, 0x7ffffffffffffffd, \ + 0x00000004fffffffd, 0xfffffffe00000005, \ + 0x8000000000000017, 0x0000000500000017, 0xfffffffe0000001f + TEST_PSIMD_ACC_RR_SET 522, pm2suba.w, 0x7ffffffffffffffd, \ + 0x00000004fffffffd, 0xfffffffe00000005, \ + 0x7ffffffffffffff6, 0x00000004fffffff6, 0xfffffffdfffffffe + TEST_PSIMD_ACC_RR_SET 523, pm2suba.wx, 0x7ffffffffffffffd, \ + 0x00000004fffffffd, 0xfffffffe00000005, \ + 0x7fffffffffffffef, 0x00000004ffffffef, 0xfffffffdfffffff7 + TEST_PSIMD_RR_SET 524, pm4add.b, \ + 0x08f906fbfc03fe01, 0xf40b0af708f90605, \ + 0xffffffbcffffffc4 + TEST_PSIMD_RR_SET 525, pm4addsu.b, \ + 0x08f906fbfc03fe01, 0xf40b0af708f90605, \ + 0x000002bc000002c4 + TEST_PSIMD_RR_SET 526, pm4addu.b, \ + 0x08f906fbfc03fe01, 0xf40b0af708f90605, \ + 0x000104bc000010c4 + TEST_PSIMD_ACC_RR_SET 527, pm4adda.b, 0xfffffffd7ffffffd, \ + 0x08f906fbfc03fe01, 0xf40b0af708f90605, \ + 0xffffffb97fffffc1, 0x08f906b7fc03fdc5, 0xf40b0ab308f905c9 + TEST_PSIMD_ACC_RR_SET 528, pm4addasu.b, 0xfffffffd7ffffffd, \ + 0x08f906fbfc03fe01, 0xf40b0af708f90605, \ + 0x000002b9800002c1, 0x08f909b7fc0400c5, 0xf40b0db308f908c9 + TEST_PSIMD_ACC_RR_SET 529, pm4addau.b, 0xfffffffd7ffffffd, \ + 0x08f906fbfc03fe01, 0xf40b0af708f90605, \ + 0x000104b9800010c1, 0x08fa0bb7fc040ec5, 0xf40c0fb308f916c9 + TEST_PSIMD_RR_SET 530, pm4add.h, \ + 0x0006fffb0004fffd, 0xfff60009fff80007, -158 + TEST_PSIMD_RR_SET 531, pm4addsu.h, \ + 0x0006fffb0004fffd, 0xfff60009fff80007, \ + 0x000000000009ff62 + TEST_PSIMD_RR_SET 532, pm4addu.h, \ + 0x0006fffb0004fffd, 0xfff60009fff80007, \ + 0x000000000019ff62 + TEST_PSIMD_ACC_RR_SET 533, pm4adda.h, 0x7ffffffffffffffd, \ + 0x0006fffb0004fffd, 0xfff60009fff80007, \ + 0x7fffffffffffff5f, 0x0006fffb0004ff5f, 0xfff60009fff7ff69 + TEST_PSIMD_ACC_RR_SET 534, pm4addasu.h, 0x7ffffffffffffffd, \ + 0x0006fffb0004fffd, 0xfff60009fff80007, \ + 0x800000000009ff5f, 0x0006fffb000eff5f, 0xfff6000a0001ff69 + TEST_PSIMD_ACC_RR_SET 535, pm4addau.h, 0x7ffffffffffffffd, \ + 0x0006fffb0004fffd, 0xfff60009fff80007, \ + 0x800000000019ff5f, 0x0006fffb001eff5f, 0xfff6000a0011ff69 + TEST_PSIMD_RR_SET 536, pmq2add.h, \ + 0x4001800080004001, 0x4000400080004000, \ + 0xffffe0000000a000 + TEST_PSIMD_RR_SET 537, pmqr2add.h, \ + 0x4001800080004001, 0x4000400080004000, \ + 0xffffe0010000a001 + TEST_PSIMD_ACC_RR_SET 538, pmq2adda.h, 0xfffffffd7ffffffd, \ + 0x4001800080004001, 0x4000400080004000, \ + 0xffffdffd80009ffd, 0x400160008000e001, 0x400020008000e000 + TEST_PSIMD_ACC_RR_SET 539, pmqr2adda.h, 0xfffffffd7ffffffd, \ + 0x4001800080004001, 0x4000400080004000, \ + 0xffffdffe80009ffe, 0x400160018000e002, 0x400020018000e001 + TEST_PSIMD_RR_SET 540, pmq2add.w, \ + 0x8000000040000001, 0x8000000040000000, \ + 0x00000000a0000000 + TEST_PSIMD_RR_SET 541, pmqr2add.w, \ + 0x8000000040000001, 0x8000000040000000, \ + 0x00000000a0000001 + TEST_PSIMD_ACC_RR_SET 542, pmq2adda.w, 0x7ffffffffffffffd, \ + 0x8000000040000001, 0x8000000040000000, \ + 0x800000009ffffffd, 0x80000000e0000001, 0x80000000e0000000 + TEST_PSIMD_ACC_RR_SET 543, pmqr2adda.w, 0x7ffffffffffffffd, \ + 0x8000000040000001, 0x8000000040000000, \ + 0x800000009ffffffe, 0x80000000e0000002, 0x80000000e0000001 + TEST_PSIMD_RR_SET 562, padd.bs, \ + 0x04030201ff807f01, 0x1234567880000080, 0x848382817f00ff81 + TEST_PSIMD_RR_SET 563, padd.hs, \ + 0x000480027fff8001, 0x1234567880008000, 0x80040002ffff0001 + TEST_PSIMD_RR_SET 564, padd.ws, \ + 0x7fffffff80000001, 0x1234567880000000, 0xffffffff00000001 + + /* ZIP/UNZIP: every byte is unique so lane source and order are visibl= e. */ + TEST_PSIMD_RR_SET 581, zip8p, \ + 0x7766554433221100, 0xffeeddccbbaa9988, 0xbb33aa2299118800 + TEST_PSIMD_RR_SET 582, zip8hp, \ + 0x7766554433221100, 0xffeeddccbbaa9988, 0xff77ee66dd55cc44 + TEST_PSIMD_RR_SET 583, zip16p, \ + 0x7766554433221100, 0xffeeddccbbaa9988, 0xbbaa332299881100 + TEST_PSIMD_RR_SET 584, zip16hp, \ + 0x7766554433221100, 0xffeeddccbbaa9988, 0xffee7766ddcc5544 + TEST_PSIMD_RR_SET 585, unzip8p, \ + 0x7766554433221100, 0xffeeddccbbaa9988, 0xeeccaa8866442200 + TEST_PSIMD_RR_SET 586, unzip8hp, \ + 0x7766554433221100, 0xffeeddccbbaa9988, 0xffddbb9977553311 + TEST_PSIMD_RR_SET 587, unzip16p, \ + 0x7766554433221100, 0xffeeddccbbaa9988, 0xddcc998855441100 + TEST_PSIMD_RR_SET 588, unzip16hp, \ + 0x7766554433221100, 0xffeeddccbbaa9988, 0xffeebbaa77663322 + + /* Signed-direction whole-register shifts, including both right guards= . */ + TEST_PSIMD_RR_SET 589, sha, 0x8000000000000001, 1, 2 + TEST_PSIMD_RR 589, sha, 0x8000000000000001, -1, \ + 0xc000000000000000 + TEST_PSIMD_RR 589, sha, 0x8000000000000001, -64, -1 + TEST_PSIMD_RR 589, sha, 0x8000000000000001, 64, 0 + /* Rounded right shifts: guard 0/1, negative operand, and -XLEN. */ + TEST_PSIMD_RR_SET 591, shar, 3, -1, 2 + TEST_PSIMD_RR 591, shar, 2, -1, 1 + TEST_PSIMD_RR 591, shar, -3, -1, -1 + /* Extended shifts consume the old rd; exercise it and both aliases. */ + TEST_PSIMD_ACC_RR_SET 593, slx, 0x1122334455667788, \ + 0x99aabbccddeeff5a, 8, 0x2233445566778899, \ + 0xaabbccddeeff5a99, 0x899 + TEST_PSIMD_ACC_RR_SET 594, srx, 0x1122334455667788, \ + 0x99aabbccddeeff5a, 8, 0x5a11223344556677, \ + 0x5a99aabbccddeeff, 0x5a00000000000000 + + TEST_PSIMD_R_SET 598, rev, 0x0123456789abcdef, 0xf7b3d591e6a2c480 + TEST_PSIMD_R_SET 599, rev16, \ + 0x0123456789abcdef, 0xcdef89ab45670123 + + /* SPEC: rounding -1 by XLEN yields zero; kept last as a bug detector.= */ + TEST_PSIMD_RR 591, shar, -1, -64, 0 + + /* P v0.21 variable-shift and narrowing mnemonics. */ + TEST_PSIMD_SAT_RR_SET 608, psshl.ws, \ + 0x400000007ffffffe, 1, 0x80000000fffffffc, \ + 0x8000000040000001, 1, 0xffffffff80000002, \ + 0xffffffff00000001, 1, 0xffffffff00000002 + TEST_PSIMD_RR_VXSAT_STATE 608, psshl.ws, \ + 0x800000017fffffff, -1, 0x400000003fffffff, 0, 0 + TEST_PSIMD_SAT_RR_SET 609, psshlr.ws, \ + 0x400000007ffffffe, 1, 0x80000000fffffffc, \ + 0x8000000040000001, 1, 0xffffffff80000002, \ + 0xffffffff00000001, 1, 0xffffffff00000002 + TEST_PSIMD_RR_VXSAT_STATE 609, psshlr.ws, \ + 0x800000037ffffffe, -1, 0x400000023fffffff, 0, 0 + TEST_PSIMD_RR_VXSAT_STATE 609, psshlr.ws, \ + 0x800000017fffffff, -33, 0x0000000100000000, 0, 0 + + TEST_PSIMD_RR_SET 610, shl, 0x8000000000000001, -1, \ + 0x4000000000000000 + TEST_PSIMD_RR 610, shl, 0x8000000000000001, 64, 0 + TEST_PSIMD_RR_SET 611, shlr, 0x8000000000000003, -1, \ + 0x4000000000000002 + TEST_PSIMD_RR 611, shlr, -1, -1, 0x8000000000000000 + TEST_PSIMD_RR 611, shlr, -1, -64, 1 + TEST_PSIMD_RR 611, shlr, 0x8000000000000000, -65, 1 + + TEST_PSIMD_SAT_RR_SET 612, pnclipp.b, \ + 0x0001ffff007fff80, 0x007efffe00020000, \ + 0x7efe020001ff7f80, \ + 0x0080008000800080, 0x0080008000800080, \ + 0x7f7f7f7f7f7f7f7f, \ + 0xff7fff7fff7fff7f, 0xff7fff7fff7fff7f, \ + 0x8080808080808080 + TEST_PSIMD_SAT_RR_SET 613, pnclipp.h, \ + 0x00007fffffff8000, 0x00000001ffffffff, \ + 0x0001ffff7fff8000, \ + 0x0000800000008000, 0x0000800000008000, \ + 0x7fff7fff7fff7fff, \ + 0xffff7fffffff7fff, 0xffff7fffffff7fff, \ + 0x8000800080008000 + TEST_PSIMD_SAT_RR_SET 614, pnclipp.w, \ + 0xffffffff80000000, 0x000000007fffffff, \ + 0x7fffffff80000000, \ + 0x0000000080000000, 0x0000000080000000, \ + 0x7fffffff7fffffff, \ + 0xffffffff7fffffff, 0xffffffff7fffffff, \ + 0x8000000080000000 + TEST_PSIMD_SAT_RR_SET 615, pnclipup.b, \ + 0x00fe000100ff0000, 0x002a007f00800002, \ + 0x2a7f8002fe01ff00, \ + 0x0100010001000100, 0x0100010001000100, -1, \ + -1, -1, -1 + TEST_PSIMD_SAT_RR_SET 616, pnclipup.h, \ + 0x0000ffff00000000, 0x0000fffe00000001, \ + 0xfffe0001ffff0000, \ + 0x0001000000010000, 0x0001000000010000, -1, \ + -1, -1, -1 + TEST_PSIMD_SAT_RR_SET 617, pnclipup.w, \ + 0x00000000ffffffff, 1, 0x00000001ffffffff, \ + 0x0000000100000000, 0x0000000100000000, -1, \ + -1, -1, -1 + PSIMD_TEST_EXIT 0 + .size _start, .-_start + + PSIMD_DEFINE_FAILURE_HANDLER + + .section .note.GNU-stack,"",@progbits diff --git a/tests/tcg/riscv/psimd-test-macros.inc b/tests/tcg/riscv/psimd-= test-macros.inc new file mode 100644 index 00000000000..7fd270762b9 --- /dev/null +++ b/tests/tcg/riscv/psimd-test-macros.inc @@ -0,0 +1,952 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Common assembly test macros for the RISC-V P extension. */ + +/* + * Allocate a stable assertion number for every case ID at assembly time. + * The per-case symbol survives non-contiguous groups of vectors, so the s= ame + * instruction can add tests later without reusing an earlier subcase numb= er. + */ +.macro PSIMD_FAIL_IF_NE actual, expected, case_id + .ifndef .Lpsimd_subcase_\case_id + .set .Lpsimd_subcase_\case_id, 0 + .else + .set .Lpsimd_subcase_\case_id, .Lpsimd_subcase_\case_id + 1 + .endif + beq \actual, \expected, .Lpass\@ + li a0, \case_id + li a1, .Lpsimd_subcase_\case_id + tail psimd_test_fail +.Lpass\@: +.endm + +/* Linux syscall numbers are shared by RV32 and RV64. */ +#define PSIMD_NR_WRITE 64 +#define PSIMD_NR_EXIT 93 + +.macro PSIMD_TEST_EXIT status + li a0, \status + li a7, PSIMD_NR_EXIT + ecall +.endm + +/* + * Emit once, after _start. Keep diagnostics independent of libc by filli= ng + * fixed-width decimal fields and writing the message directly to stdout. + */ +.macro PSIMD_DEFINE_FAILURE_HANDLER + .section .data +.Lpsimd_fail_message: + .ascii "PSIMD FAIL: case=3D00000 subcase=3D00000\n" +.Lpsimd_fail_message_end: + + .text + .balign 4 + .type psimd_test_fail, @function +psimd_test_fail: + la t0, .Lpsimd_fail_message + li t1, 10 + + /* Fill the five case digits from right to left. */ + addi t2, t0, 21 + li t3, 5 +.Lpsimd_case_loop: + remu t4, a0, t1 + addi t4, t4, '0' + sb t4, 0(t2) + divu a0, a0, t1 + addi t2, t2, -1 + addi t3, t3, -1 + bnez t3, .Lpsimd_case_loop + + /* Fill the five subcase digits from right to left. */ + addi t2, t0, 35 + li t3, 5 +.Lpsimd_subcase_loop: + remu t4, a1, t1 + addi t4, t4, '0' + sb t4, 0(t2) + divu a1, a1, t1 + addi t2, t2, -1 + addi t3, t3, -1 + bnez t3, .Lpsimd_subcase_loop + + li a0, 1 + la a1, .Lpsimd_fail_message + li a2, .Lpsimd_fail_message_end - .Lpsimd_fail_message + li a7, PSIMD_NR_WRITE + ecall + + li a0, 1 + li a7, PSIMD_NR_EXIT + ecall + .size psimd_test_fail, .-psimd_test_fail +.endm + +.macro TEST_PSIMD_RR case_id, insn, input1, input2, expected + li t0, \input1 + li t1, \input2 + \insn t2, t0, t1 + li t3, \expected + PSIMD_FAIL_IF_NE t2, t3, \case_id +.endm + +.macro TEST_PSIMD_RR_RD_RS1 case_id, insn, input1, input2, expected + li t0, \input1 + li t1, \input2 + \insn t0, t0, t1 + li t3, \expected + PSIMD_FAIL_IF_NE t0, t3, \case_id +.endm + +.macro TEST_PSIMD_RR_RD_RS2 case_id, insn, input1, input2, expected + li t0, \input1 + li t1, \input2 + \insn t1, t0, t1 + li t3, \expected + PSIMD_FAIL_IF_NE t1, t3, \case_id +.endm + +.macro TEST_PSIMD_R case_id, insn, input, expected + li t0, \input + \insn t2, t0 + li t3, \expected + PSIMD_FAIL_IF_NE t2, t3, \case_id +.endm + +.macro TEST_PSIMD_R_RD_RS1 case_id, insn, input, expected + li t0, \input + \insn t0, t0 + li t3, \expected + PSIMD_FAIL_IF_NE t0, t3, \case_id +.endm + +/* Normal value, zero, and rd =3D=3D rs1. */ +.macro TEST_PSIMD_R_SET case_id, insn, input, expected + TEST_PSIMD_R \case_id, \insn, \input, \expected + TEST_PSIMD_R \case_id, \insn, 0, 0 + TEST_PSIMD_R_RD_RS1 \case_id, \insn, \input, \expected +.endm + +.macro TEST_PSIMD_R_VXSAT_STATE case_id, insn, input, expected, \ + initial_vxsat, expected_vxsat + li t4, \initial_vxsat + csrw vxsat, t4 + li t0, \input + \insn t2, t0 + li t3, \expected + PSIMD_FAIL_IF_NE t2, t3, \case_id + csrr t4, vxsat + li t5, \expected_vxsat + PSIMD_FAIL_IF_NE t4, t5, \case_id +.endm + +/* Unary saturation: ordinary, minimum negative, sticky, and source alias.= */ +.macro TEST_PSIMD_SAT_R_SET case_id, insn, normal, normal_expected, \ + saturating, saturating_expected + TEST_PSIMD_R_VXSAT_STATE \case_id, \insn, \normal, \ + \normal_expected, 0, 0 + TEST_PSIMD_R_VXSAT_STATE \case_id, \insn, \saturating, \ + \saturating_expected, 0, 1 + TEST_PSIMD_R_VXSAT_STATE \case_id, \insn, 0, 0, 1, 1 + TEST_PSIMD_R_RD_RS1 \case_id, \insn, \normal, \normal_expected +.endm + +/* Normal, zero, and both legal destination/source aliasing forms. */ +.macro TEST_PSIMD_RR_SET case_id, insn, input1, input2, expected, zero_exp= ected=3D0 + TEST_PSIMD_RR \case_id, \insn, \input1, \input2, \expected + TEST_PSIMD_RR \case_id, \insn, 0, 0, \zero_expected + TEST_PSIMD_RR_RD_RS1 \case_id, \insn, \input1, \input2, \expected + TEST_PSIMD_RR_RD_RS2 \case_id, \insn, \input1, \input2, \expected +.endm + +.macro TEST_PSIMD_RI case_id, insn, input, immediate, expected + li t0, \input + \insn t2, t0, \immediate + li t3, \expected + PSIMD_FAIL_IF_NE t2, t3, \case_id +.endm + +.macro TEST_PSIMD_RI_RD_RS1 case_id, insn, input, immediate, expected + li t0, \input + \insn t0, t0, \immediate + li t3, \expected + PSIMD_FAIL_IF_NE t0, t3, \case_id +.endm + +/* Immediate shift: amount 1, zero, legal maximum, and rd =3D=3D rs1. */ +.macro TEST_PSIMD_SHIFT_RI_SET case_id, insn, input, shift1_expected, \ + max_shift, max_expected + TEST_PSIMD_RI \case_id, \insn, \input, 1, \shift1_expected + TEST_PSIMD_RI \case_id, \insn, \input, 0, \input + TEST_PSIMD_RI \case_id, \insn, \input, \max_shift, \max_expected + TEST_PSIMD_RI_RD_RS1 \case_id, \insn, \input, 1, \shift1_expected +.endm + +/* Register shift adds a maximum masked amount to the standard RR set. */ +.macro TEST_PSIMD_SHIFT_RR_SET case_id, insn, input, shift1_expected, \ + max_shift, max_expected + TEST_PSIMD_RR_SET \case_id, \insn, \input, 1, \shift1_expected + TEST_PSIMD_RR \case_id, \insn, \input, \max_shift, \max_expected +.endm + +.macro TEST_PSIMD_LI case_id, insn, immediate, expected + \insn t2, \immediate + li t3, \expected + PSIMD_FAIL_IF_NE t2, t3, \case_id +.endm + +.macro TEST_PSIMD_PAIR_LI case_id, insn, immediate, expected_lo, expected_= hi + \insn a0, \immediate + li t0, \expected_lo + PSIMD_FAIL_IF_NE a0, t0, \case_id + li t0, \expected_hi + PSIMD_FAIL_IF_NE a1, t0, \case_id +.endm + +.macro TEST_PSIMD_PAIR_LI_SET case_id, insn, one_expected, max_immediate, \ + max_expected, min_immediate, min_expected + TEST_PSIMD_PAIR_LI \case_id, \insn, 0, 0, 0 + TEST_PSIMD_PAIR_LI \case_id, \insn, 1, \one_expected, \one_expected + TEST_PSIMD_PAIR_LI \case_id, \insn, \max_immediate, \max_expected, \ + \max_expected + TEST_PSIMD_PAIR_LI \case_id, \insn, \min_immediate, \min_expected, \ + \min_expected +.endm + +/* rd is both the accumulator input and the result. */ +.macro TEST_PSIMD_ACC_RR case_id, insn, initial, input1, input2, expected + li t0, \input1 + li t1, \input2 + li t2, \initial + \insn t2, t0, t1 + li t3, \expected + PSIMD_FAIL_IF_NE t2, t3, \case_id +.endm + +/* Accumulator result, zero case, and both architecturally valid rd aliase= s. */ +.macro TEST_PSIMD_ACC_RR_SET case_id, insn, initial, input1, input2, expec= ted, \ + rd_rs1_expected, rd_rs2_expected + TEST_PSIMD_ACC_RR \case_id, \insn, \initial, \input1, \input2, \expect= ed + TEST_PSIMD_ACC_RR \case_id, \insn, 0, 0, 0, 0 + + li t0, \input1 + li t1, \input2 + \insn t0, t0, t1 + li t3, \rd_rs1_expected + PSIMD_FAIL_IF_NE t0, t3, \case_id + + li t0, \input1 + li t1, \input2 + \insn t1, t0, t1 + li t3, \rd_rs2_expected + PSIMD_FAIL_IF_NE t1, t3, \case_id +.endm + +/* + * Check the saturated result, vxsat, and its sticky behavior. The second + * operation (1 + 1 in each XLEN value) does not saturate. + */ +.macro TEST_PSIMD_RR_VXSAT case_id, insn, input1, input2, expected + csrw vxsat, zero + li t0, \input1 + li t1, \input2 + \insn t2, t0, t1 + li t3, \expected + PSIMD_FAIL_IF_NE t2, t3, \case_id + csrr t4, vxsat + li t5, 1 + PSIMD_FAIL_IF_NE t4, t5, \case_id + + li t0, 1 + li t1, 1 + \insn t2, t0, t1 + csrr t4, vxsat + PSIMD_FAIL_IF_NE t4, t5, \case_id +.endm + +.macro TEST_PSIMD_RR_VXSAT_STATE case_id, insn, input1, input2, expected, \ + initial_vxsat, expected_vxsat + li t4, \initial_vxsat + csrw vxsat, t4 + li t0, \input1 + li t1, \input2 + \insn t2, t0, t1 + li t3, \expected + PSIMD_FAIL_IF_NE t2, t3, \case_id + csrr t4, vxsat + li t5, \expected_vxsat + PSIMD_FAIL_IF_NE t4, t5, \case_id +.endm + +/* + * Saturating RR operation: normal, two saturating boundaries, sticky flag, + * and both destination/source aliases. Both saturation vectors must set + * vxsat; their meaning (positive/negative/unsigned underflow) is per opco= de. + */ +.macro TEST_PSIMD_SAT_RR_SET case_id, insn, normal1, normal2, normal_expec= ted, \ + sat1_1, sat1_2, sat1_expected, sat2_1, sat2_= 2, \ + sat2_expected + TEST_PSIMD_RR_VXSAT_STATE \case_id, \insn, \normal1, \normal2, \ + \normal_expected, 0, 0 + TEST_PSIMD_RR_VXSAT_STATE \case_id, \insn, \sat1_1, \sat1_2, \ + \sat1_expected, 0, 1 + TEST_PSIMD_RR_VXSAT_STATE \case_id, \insn, \sat2_1, \sat2_2, \ + \sat2_expected, 0, 1 + TEST_PSIMD_RR_VXSAT_STATE \case_id, \insn, 0, 0, 0, 1, 1 + TEST_PSIMD_RR_RD_RS1 \case_id, \insn, \normal1, \normal2, \ + \normal_expected + TEST_PSIMD_RR_RD_RS2 \case_id, \insn, \normal1, \normal2, \ + \normal_expected +.endm + +.macro TEST_PSIMD_RI_VXSAT case_id, insn, input, immediate, expected + csrw vxsat, zero + li t0, \input + \insn t2, t0, \immediate + li t3, \expected + PSIMD_FAIL_IF_NE t2, t3, \case_id + csrr t4, vxsat + li t5, 1 + PSIMD_FAIL_IF_NE t4, t5, \case_id +.endm + +.macro TEST_PSIMD_RI_VXSAT_STATE case_id, insn, input, immediate, expected= , \ + initial_vxsat, expected_vxsat + li t4, \initial_vxsat + csrw vxsat, t4 + li t0, \input + \insn t2, t0, \immediate + li t3, \expected + PSIMD_FAIL_IF_NE t2, t3, \case_id + csrr t4, vxsat + li t5, \expected_vxsat + PSIMD_FAIL_IF_NE t4, t5, \case_id +.endm + +.macro TEST_PSIMD_SAT_RI_SET case_id, insn, immediate, normal, \ + normal_expected, positive, positive_expected= , \ + negative, negative_expected + TEST_PSIMD_RI_VXSAT_STATE \case_id, \insn, \normal, \immediate, \ + \normal_expected, 0, 0 + TEST_PSIMD_RI_VXSAT_STATE \case_id, \insn, \positive, \immediate, \ + \positive_expected, 0, 1 + TEST_PSIMD_RI_VXSAT_STATE \case_id, \insn, \negative, \immediate, \ + \negative_expected, 0, 1 + TEST_PSIMD_RI_VXSAT_STATE \case_id, \insn, 0, \immediate, 0, 1, 1 + TEST_PSIMD_RI_RD_RS1 \case_id, \insn, \normal, \immediate, \ + \normal_expected +.endm + +/* RV32 register-pair operands: a0/a1, a2/a3, and a4/a5. */ +.macro TEST_PSIMD_PAIR_RR case_id, insn, input1_lo, input1_hi, input2_lo, \ + input2_hi, expected_lo, expected_hi + li a2, \input1_lo + li a3, \input1_hi + li a4, \input2_lo + li a5, \input2_hi + \insn a0, a2, a4 + li t0, \expected_lo + PSIMD_FAIL_IF_NE a0, t0, \case_id + li t0, \expected_hi + PSIMD_FAIL_IF_NE a1, t0, \case_id +.endm + +/* RV32 scalar sources with a 64-bit destination register pair. */ +.macro TEST_PSIMD_WIDE_RR case_id, insn, input1, input2, expected_lo, \ + expected_hi + li t0, \input1 + li t1, \input2 + \insn a0, t0, t1 + li t2, \expected_lo + PSIMD_FAIL_IF_NE a0, t2, \case_id + li t2, \expected_hi + PSIMD_FAIL_IF_NE a1, t2, \case_id +.endm + +.macro TEST_PSIMD_WIDE_RR_SET case_id, insn, input1, input2, expected_lo, \ + expected_hi + TEST_PSIMD_WIDE_RR \case_id, \insn, \input1, \input2, \expected_lo, \ + \expected_hi + TEST_PSIMD_WIDE_RR \case_id, \insn, 0, 0, 0, 0 + + li a2, \input1 + li a4, \input2 + \insn a2, a2, a4 + li t0, \expected_lo + PSIMD_FAIL_IF_NE a2, t0, \case_id + li t0, \expected_hi + PSIMD_FAIL_IF_NE a3, t0, \case_id + + li a2, \input1 + li a4, \input2 + \insn a4, a2, a4 + li t0, \expected_lo + PSIMD_FAIL_IF_NE a4, t0, \case_id + li t0, \expected_hi + PSIMD_FAIL_IF_NE a5, t0, \case_id +.endm + +.macro TEST_PSIMD_WIDE_RI case_id, insn, input, immediate, expected_lo, \ + expected_hi + li t0, \input + \insn a0, t0, \immediate + li t1, \expected_lo + PSIMD_FAIL_IF_NE a0, t1, \case_id + li t1, \expected_hi + PSIMD_FAIL_IF_NE a1, t1, \case_id +.endm + +.macro TEST_PSIMD_WIDE_RI_SET case_id, insn, input, zero_lo, zero_hi, \ + one_lo, one_hi, max_imm, max_lo, max_hi + TEST_PSIMD_WIDE_RI \case_id, \insn, \input, 0, \zero_lo, \zero_hi + TEST_PSIMD_WIDE_RI \case_id, \insn, \input, 1, \one_lo, \one_hi + TEST_PSIMD_WIDE_RI \case_id, \insn, \input, \max_imm, \max_lo, \max_hi + + li a2, \input + \insn a2, a2, 1 + li t0, \one_lo + PSIMD_FAIL_IF_NE a2, t0, \case_id + li t0, \one_hi + PSIMD_FAIL_IF_NE a3, t0, \case_id +.endm + +.macro TEST_PSIMD_WIDE_ACC_RR case_id, insn, initial_lo, initial_hi, input= 1, \ + input2, expected_lo, expected_hi + li a0, \initial_lo + li a1, \initial_hi + li a2, \input1 + li a3, \input2 + \insn a0, a2, a3 + li t0, \expected_lo + PSIMD_FAIL_IF_NE a0, t0, \case_id + li t0, \expected_hi + PSIMD_FAIL_IF_NE a1, t0, \case_id +.endm + +.macro TEST_PSIMD_WIDE_ACC_RR_SET case_id, insn, initial_lo, initial_hi, \ + input1, input2, expected_lo, expected_h= i, \ + rd_rs1_lo, rd_rs1_hi, rd_rs2_lo, rd_rs2= _hi + TEST_PSIMD_WIDE_ACC_RR \case_id, \insn, \initial_lo, \initial_hi, \ + \input1, \input2, \expected_lo, \expected_hi + TEST_PSIMD_WIDE_ACC_RR \case_id, \insn, 0, 0, 0, 0, 0, 0 + + li a2, \input1 + li a3, \initial_hi + li a4, \input2 + \insn a2, a2, a4 + li t0, \rd_rs1_lo + PSIMD_FAIL_IF_NE a2, t0, \case_id + li t0, \rd_rs1_hi + PSIMD_FAIL_IF_NE a3, t0, \case_id + + li a2, \input1 + li a4, \input2 + li a5, \initial_hi + \insn a4, a2, a4 + li t0, \rd_rs2_lo + PSIMD_FAIL_IF_NE a4, t0, \case_id + li t0, \rd_rs2_hi + PSIMD_FAIL_IF_NE a5, t0, \case_id +.endm + +/* RV32 pair-to-scalar reduction: rs1 is a pair and rs2 is scalar. */ +.macro TEST_PSIMD_PAIR_REDUCE case_id, insn, input_lo, input_hi, scalar, \ + expected + li a2, \input_lo + li a3, \input_hi + li a4, \scalar + \insn a0, a2, a4 + li t0, \expected + PSIMD_FAIL_IF_NE a0, t0, \case_id + + li a2, 0 + li a3, 0 + li a4, 0 + \insn a0, a2, a4 + PSIMD_FAIL_IF_NE a0, zero, \case_id + + /* Scalar destination overlaps the low register of the source pair. */ + li a2, \input_lo + li a3, \input_hi + li a4, \scalar + \insn a2, a2, a4 + li t0, \expected + PSIMD_FAIL_IF_NE a2, t0, \case_id + + /* Scalar destination overlaps the scalar accumulator source. */ + li a2, \input_lo + li a3, \input_hi + li a4, \scalar + \insn a4, a2, a4 + li t0, \expected + PSIMD_FAIL_IF_NE a4, t0, \case_id +.endm + +/* RV32 register-pair result and rs1, with a scalar rs2 element. */ +.macro TEST_PSIMD_PAIR_SCALAR_RR_SET case_id, insn, input_lo, input_hi, \ + scalar, expected_lo, expected_hi + li a2, \input_lo + li a3, \input_hi + li a4, \scalar + \insn a0, a2, a4 + li t0, \expected_lo + PSIMD_FAIL_IF_NE a0, t0, \case_id + li t0, \expected_hi + PSIMD_FAIL_IF_NE a1, t0, \case_id + + li a2, 0 + li a3, 0 + li a4, 0 + \insn a0, a2, a4 + PSIMD_FAIL_IF_NE a0, zero, \case_id + PSIMD_FAIL_IF_NE a1, zero, \case_id + + li a2, \input_lo + li a3, \input_hi + li a4, \scalar + \insn a2, a2, a4 + li t0, \expected_lo + PSIMD_FAIL_IF_NE a2, t0, \case_id + li t0, \expected_hi + PSIMD_FAIL_IF_NE a3, t0, \case_id + + li a2, \input_lo + li a3, \input_hi + li a4, \scalar + \insn a4, a2, a4 + li t0, \expected_lo + PSIMD_FAIL_IF_NE a4, t0, \case_id + li t0, \expected_hi + PSIMD_FAIL_IF_NE a5, t0, \case_id +.endm + +/* RV32 pair result with scalar shift amount in rs2. */ +.macro TEST_PSIMD_PAIR_SHIFT_RR_SET case_id, insn, input_lo, input_hi, \ + shift1_lo, shift1_hi, max_shift, \ + max_lo, max_hi + li a2, \input_lo + li a3, \input_hi + li a4, 1 + \insn a0, a2, a4 + li t0, \shift1_lo + PSIMD_FAIL_IF_NE a0, t0, \case_id + li t0, \shift1_hi + PSIMD_FAIL_IF_NE a1, t0, \case_id + + li a2, 0 + li a3, 0 + li a4, 0 + \insn a0, a2, a4 + PSIMD_FAIL_IF_NE a0, zero, \case_id + PSIMD_FAIL_IF_NE a1, zero, \case_id + + li a2, \input_lo + li a3, \input_hi + li a4, \max_shift + \insn a0, a2, a4 + li t0, \max_lo + PSIMD_FAIL_IF_NE a0, t0, \case_id + li t0, \max_hi + PSIMD_FAIL_IF_NE a1, t0, \case_id + + li a2, \input_lo + li a3, \input_hi + li a4, 1 + \insn a2, a2, a4 + li t0, \shift1_lo + PSIMD_FAIL_IF_NE a2, t0, \case_id + li t0, \shift1_hi + PSIMD_FAIL_IF_NE a3, t0, \case_id +.endm + +.macro TEST_PSIMD_PAIR_SHIFT_RR_VXSAT_STATE case_id, insn, input_lo, \ + input_hi, shift, expected_lo= , \ + expected_hi, initial_vxsat, \ + expected_vxsat + li t4, \initial_vxsat + csrw vxsat, t4 + li a2, \input_lo + li a3, \input_hi + li a4, \shift + \insn a0, a2, a4 + li t0, \expected_lo + PSIMD_FAIL_IF_NE a0, t0, \case_id + li t0, \expected_hi + PSIMD_FAIL_IF_NE a1, t0, \case_id + csrr t4, vxsat + li t5, \expected_vxsat + PSIMD_FAIL_IF_NE t4, t5, \case_id +.endm + +.macro TEST_PSIMD_PAIR_VAR_SAT_SET case_id, insn, normal_lo, normal_hi, \ + normal_exp_lo, normal_exp_hi, sat1_lo,= \ + sat1_hi, sat1_exp_lo, sat1_exp_hi, \ + sat2_lo, sat2_hi, sat2_exp_lo, sat2_ex= p_hi + TEST_PSIMD_PAIR_SHIFT_RR_VXSAT_STATE \case_id, \insn, \normal_lo, \ + \normal_hi, 1, \normal_exp_lo, \normal_exp_hi, 0, 0 + TEST_PSIMD_PAIR_SHIFT_RR_VXSAT_STATE \case_id, \insn, \sat1_lo, \ + \sat1_hi, 1, \sat1_exp_lo, \sat1_exp_hi, 0, 1 + TEST_PSIMD_PAIR_SHIFT_RR_VXSAT_STATE \case_id, \insn, \sat2_lo, \ + \sat2_hi, 1, \sat2_exp_lo, \sat2_exp_hi, 0, 1 + TEST_PSIMD_PAIR_SHIFT_RR_VXSAT_STATE \case_id, \insn, 0, 0, 0, \ + 0, 0, 1, 1 + li a2, \normal_lo + li a3, \normal_hi + li a4, 1 + \insn a2, a2, a4 + li t0, \normal_exp_lo + PSIMD_FAIL_IF_NE a2, t0, \case_id + li t0, \normal_exp_hi + PSIMD_FAIL_IF_NE a3, t0, \case_id +.endm + +/* RV32 pair immediate shift with immediate 1, zero, maximum, and overlap.= */ +.macro TEST_PSIMD_PAIR_SHIFT_RI_SET case_id, insn, input_lo, input_hi, \ + shift1_lo, shift1_hi, max_shift, \ + max_lo, max_hi + li a2, \input_lo + li a3, \input_hi + \insn a0, a2, 1 + li t0, \shift1_lo + PSIMD_FAIL_IF_NE a0, t0, \case_id + li t0, \shift1_hi + PSIMD_FAIL_IF_NE a1, t0, \case_id + + li a2, \input_lo + li a3, \input_hi + \insn a0, a2, 0 + PSIMD_FAIL_IF_NE a0, a2, \case_id + PSIMD_FAIL_IF_NE a1, a3, \case_id + + li a2, \input_lo + li a3, \input_hi + \insn a0, a2, \max_shift + li t0, \max_lo + PSIMD_FAIL_IF_NE a0, t0, \case_id + li t0, \max_hi + PSIMD_FAIL_IF_NE a1, t0, \case_id + + li a2, \input_lo + li a3, \input_hi + \insn a2, a2, 1 + li t0, \shift1_lo + PSIMD_FAIL_IF_NE a2, t0, \case_id + li t0, \shift1_hi + PSIMD_FAIL_IF_NE a3, t0, \case_id +.endm + +/* RV32 register-pair source narrowed to one scalar destination. */ +.macro TEST_PSIMD_PAIR_NARROW_RI_SET case_id, insn, input_lo, input_hi, \ + shift0_expected, shift1_expected, \ + max_shift, max_expected + li a2, \input_lo + li a3, \input_hi + \insn a0, a2, 1 + li t0, \shift1_expected + PSIMD_FAIL_IF_NE a0, t0, \case_id + + li a2, \input_lo + li a3, \input_hi + \insn a0, a2, 0 + li t0, \shift0_expected + PSIMD_FAIL_IF_NE a0, t0, \case_id + + li a2, \input_lo + li a3, \input_hi + \insn a0, a2, \max_shift + li t0, \max_expected + PSIMD_FAIL_IF_NE a0, t0, \case_id + + li a2, \input_lo + li a3, \input_hi + \insn a2, a2, 1 + li t0, \shift1_expected + PSIMD_FAIL_IF_NE a2, t0, \case_id +.endm + +.macro TEST_PSIMD_PAIR_NARROW_RR_SET case_id, insn, input_lo, input_hi, \ + shift0_expected, shift1_expected, \ + max_shift, max_expected + li a2, \input_lo + li a3, \input_hi + li a4, 1 + \insn a0, a2, a4 + li t0, \shift1_expected + PSIMD_FAIL_IF_NE a0, t0, \case_id + + li a2, \input_lo + li a3, \input_hi + li a4, 0 + \insn a0, a2, a4 + li t0, \shift0_expected + PSIMD_FAIL_IF_NE a0, t0, \case_id + + li a2, \input_lo + li a3, \input_hi + li a4, \max_shift + \insn a0, a2, a4 + li t0, \max_expected + PSIMD_FAIL_IF_NE a0, t0, \case_id + + li a2, \input_lo + li a3, \input_hi + li a4, 1 + \insn a2, a2, a4 + li t0, \shift1_expected + PSIMD_FAIL_IF_NE a2, t0, \case_id +.endm + +.macro TEST_PSIMD_PAIR_NARROW_RI_VXSAT_STATE case_id, insn, input_lo, \ + input_hi, immediate, expect= ed, \ + initial_vxsat, expected_vxs= at + li t4, \initial_vxsat + csrw vxsat, t4 + li a2, \input_lo + li a3, \input_hi + \insn a0, a2, \immediate + li t0, \expected + PSIMD_FAIL_IF_NE a0, t0, \case_id + csrr t4, vxsat + li t5, \expected_vxsat + PSIMD_FAIL_IF_NE t4, t5, \case_id +.endm + +.macro TEST_PSIMD_PAIR_NARROW_RR_VXSAT_STATE case_id, insn, input_lo, \ + input_hi, shift, expected, \ + initial_vxsat, expected_vxs= at + li t4, \initial_vxsat + csrw vxsat, t4 + li a2, \input_lo + li a3, \input_hi + li a4, \shift + \insn a0, a2, a4 + li t0, \expected + PSIMD_FAIL_IF_NE a0, t0, \case_id + csrr t4, vxsat + li t5, \expected_vxsat + PSIMD_FAIL_IF_NE t4, t5, \case_id +.endm + +.macro TEST_PSIMD_PAIR_CLIP_RI_SET case_id, insn, normal_lo, normal_hi, \ + immediate, normal_expected, sat_lo, \ + sat_hi, sat_expected + TEST_PSIMD_PAIR_NARROW_RI_VXSAT_STATE \case_id, \insn, \normal_lo, \ + \normal_hi, \immediate, \normal_expected, 0, 0 + TEST_PSIMD_PAIR_NARROW_RI_VXSAT_STATE \case_id, \insn, \sat_lo, \ + \sat_hi, \immediate, \sat_expected, 0, 1 + TEST_PSIMD_PAIR_NARROW_RI_VXSAT_STATE \case_id, \insn, 0, 0, 0, \ + 0, 1, 1 + li a2, \normal_lo + li a3, \normal_hi + \insn a2, a2, \immediate + li t0, \normal_expected + PSIMD_FAIL_IF_NE a2, t0, \case_id +.endm + +.macro TEST_PSIMD_PAIR_CLIP_RR_SET case_id, insn, normal_lo, normal_hi, \ + shift, normal_expected, sat_lo, sat_hi= , \ + sat_expected + TEST_PSIMD_PAIR_NARROW_RR_VXSAT_STATE \case_id, \insn, \normal_lo, \ + \normal_hi, \shift, \normal_expected, 0, 0 + TEST_PSIMD_PAIR_NARROW_RR_VXSAT_STATE \case_id, \insn, \sat_lo, \ + \sat_hi, \shift, \sat_expected, 0, 1 + TEST_PSIMD_PAIR_NARROW_RR_VXSAT_STATE \case_id, \insn, 0, 0, 0, \ + 0, 1, 1 + li a2, \normal_lo + li a3, \normal_hi + li a4, \shift + \insn a2, a2, a4 + li t0, \normal_expected + PSIMD_FAIL_IF_NE a2, t0, \case_id +.endm + +.macro TEST_PSIMD_PAIR_R case_id, insn, input_lo, input_hi, expected_lo, \ + expected_hi + li a2, \input_lo + li a3, \input_hi + \insn a0, a2 + li t0, \expected_lo + PSIMD_FAIL_IF_NE a0, t0, \case_id + li t0, \expected_hi + PSIMD_FAIL_IF_NE a1, t0, \case_id +.endm + +.macro TEST_PSIMD_PAIR_R_RD_RS1 case_id, insn, input_lo, input_hi, \ + expected_lo, expected_hi + li a2, \input_lo + li a3, \input_hi + \insn a2, a2 + li t0, \expected_lo + PSIMD_FAIL_IF_NE a2, t0, \case_id + li t0, \expected_hi + PSIMD_FAIL_IF_NE a3, t0, \case_id +.endm + +/* Unary pair result: lane order, zero, and the legal rd =3D=3D rs1 overla= p. */ +.macro TEST_PSIMD_PAIR_R_SET case_id, insn, input_lo, input_hi, expected_l= o, \ + expected_hi + TEST_PSIMD_PAIR_R \case_id, \insn, \input_lo, \input_hi, \ + \expected_lo, \expected_hi + TEST_PSIMD_PAIR_R \case_id, \insn, 0, 0, 0, 0 + TEST_PSIMD_PAIR_R_RD_RS1 \case_id, \insn, \input_lo, \input_hi, \ + \expected_lo, \expected_hi +.endm + +.macro TEST_PSIMD_PAIR_R_VXSAT_STATE case_id, insn, input_lo, input_hi, \ + expected_lo, expected_hi, \ + initial_vxsat, expected_vxsat + li t4, \initial_vxsat + csrw vxsat, t4 + li a2, \input_lo + li a3, \input_hi + \insn a0, a2 + li t0, \expected_lo + PSIMD_FAIL_IF_NE a0, t0, \case_id + li t0, \expected_hi + PSIMD_FAIL_IF_NE a1, t0, \case_id + csrr t4, vxsat + li t5, \expected_vxsat + PSIMD_FAIL_IF_NE t4, t5, \case_id +.endm + +.macro TEST_PSIMD_PAIR_RI_VXSAT_STATE case_id, insn, input_lo, input_hi, \ + immediate, expected_lo, expected_hi= , \ + initial_vxsat, expected_vxsat + li t4, \initial_vxsat + csrw vxsat, t4 + li a2, \input_lo + li a3, \input_hi + \insn a0, a2, \immediate + li t0, \expected_lo + PSIMD_FAIL_IF_NE a0, t0, \case_id + li t0, \expected_hi + PSIMD_FAIL_IF_NE a1, t0, \case_id + csrr t4, vxsat + li t5, \expected_vxsat + PSIMD_FAIL_IF_NE t4, t5, \case_id +.endm + +.macro TEST_PSIMD_PAIR_SAT_RI_SET case_id, insn, immediate, normal_lo, \ + normal_hi, normal_exp_lo, normal_exp_hi= , \ + positive_lo, positive_hi, pos_exp_lo, \ + pos_exp_hi, negative_lo, negative_hi, \ + neg_exp_lo, neg_exp_hi + TEST_PSIMD_PAIR_RI_VXSAT_STATE \case_id, \insn, \normal_lo, \ + \normal_hi, \immediate, \normal_exp_lo, \normal_exp_hi, 0, 0 + TEST_PSIMD_PAIR_RI_VXSAT_STATE \case_id, \insn, \positive_lo, \ + \positive_hi, \immediate, \pos_exp_lo, \pos_exp_hi, 0, 1 + TEST_PSIMD_PAIR_RI_VXSAT_STATE \case_id, \insn, \negative_lo, \ + \negative_hi, \immediate, \neg_exp_lo, \neg_exp_hi, 0, 1 + TEST_PSIMD_PAIR_RI_VXSAT_STATE \case_id, \insn, 0, 0, \immediate, \ + 0, 0, 1, 1 + li a2, \normal_lo + li a3, \normal_hi + \insn a2, a2, \immediate + li t0, \normal_exp_lo + PSIMD_FAIL_IF_NE a2, t0, \case_id + li t0, \normal_exp_hi + PSIMD_FAIL_IF_NE a3, t0, \case_id +.endm + +.macro TEST_PSIMD_PAIR_SAT_R_SET case_id, insn, normal_lo, normal_hi, \ + normal_exp_lo, normal_exp_hi, sat_lo, \ + sat_hi, sat_exp_lo, sat_exp_hi + TEST_PSIMD_PAIR_R_VXSAT_STATE \case_id, \insn, \normal_lo, \ + \normal_hi, \normal_exp_lo, \ + \normal_exp_hi, 0, 0 + TEST_PSIMD_PAIR_R_VXSAT_STATE \case_id, \insn, \sat_lo, \sat_hi, \ + \sat_exp_lo, \sat_exp_hi, 0, 1 + TEST_PSIMD_PAIR_R_VXSAT_STATE \case_id, \insn, 0, 0, 0, 0, 1, 1 + TEST_PSIMD_PAIR_R_RD_RS1 \case_id, \insn, \normal_lo, \normal_hi, \ + \normal_exp_lo, \normal_exp_hi +.endm + + +.macro TEST_PSIMD_PAIR_RR_RD_RS1 case_id, insn, input1_lo, input1_hi, \ + input2_lo, input2_hi, expected_lo, \ + expected_hi + li a2, \input1_lo + li a3, \input1_hi + li a4, \input2_lo + li a5, \input2_hi + \insn a2, a2, a4 + li t0, \expected_lo + PSIMD_FAIL_IF_NE a2, t0, \case_id + li t0, \expected_hi + PSIMD_FAIL_IF_NE a3, t0, \case_id +.endm + +.macro TEST_PSIMD_PAIR_RR_RD_RS2 case_id, insn, input1_lo, input1_hi, \ + input2_lo, input2_hi, expected_lo, \ + expected_hi + li a2, \input1_lo + li a3, \input1_hi + li a4, \input2_lo + li a5, \input2_hi + \insn a4, a2, a4 + li t0, \expected_lo + PSIMD_FAIL_IF_NE a4, t0, \case_id + li t0, \expected_hi + PSIMD_FAIL_IF_NE a5, t0, \case_id +.endm + +.macro TEST_PSIMD_PAIR_RR_SET case_id, insn, input1_lo, input1_hi, \ + input2_lo, input2_hi, expected_lo, \ + expected_hi, zero_expected=3D-1 + TEST_PSIMD_PAIR_RR \case_id, \insn, \input1_lo, \input1_hi, \ + \input2_lo, \input2_hi, \expected_lo, \expected_hi + TEST_PSIMD_PAIR_RR \case_id, \insn, 0, 0, 0, 0, \ + \zero_expected, \zero_expected + TEST_PSIMD_PAIR_RR_RD_RS1 \case_id, \insn, \input1_lo, \input1_hi, \ + \input2_lo, \input2_hi, \expected_lo, \ + \expected_hi + TEST_PSIMD_PAIR_RR_RD_RS2 \case_id, \insn, \input1_lo, \input1_hi, \ + \input2_lo, \input2_hi, \expected_lo, \ + \expected_hi +.endm + +.macro TEST_PSIMD_PAIR_RR_VXSAT_STATE case_id, insn, input1_lo, input1_hi,= \ + input2_lo, input2_hi, expected_lo, \ + expected_hi, initial_vxsat, \ + expected_vxsat + li t4, \initial_vxsat + csrw vxsat, t4 + li a2, \input1_lo + li a3, \input1_hi + li a4, \input2_lo + li a5, \input2_hi + \insn a0, a2, a4 + li t0, \expected_lo + PSIMD_FAIL_IF_NE a0, t0, \case_id + li t0, \expected_hi + PSIMD_FAIL_IF_NE a1, t0, \case_id + csrr t4, vxsat + li t5, \expected_vxsat + PSIMD_FAIL_IF_NE t4, t5, \case_id +.endm + +.macro TEST_PSIMD_PAIR_SAT_RR_SET case_id, insn, normal1_lo, normal1_hi, \ + normal2_lo, normal2_hi, normal_exp_lo, \ + normal_exp_hi, sat1_1_lo, sat1_1_hi, \ + sat1_2_lo, sat1_2_hi, sat1_exp_lo, \ + sat1_exp_hi, sat2_1_lo, sat2_1_hi, \ + sat2_2_lo, sat2_2_hi, sat2_exp_lo, \ + sat2_exp_hi + TEST_PSIMD_PAIR_RR_VXSAT_STATE \case_id, \insn, \normal1_lo, \ + \normal1_hi, \normal2_lo, \normal2_hi,= \ + \normal_exp_lo, \normal_exp_hi, 0, 0 + TEST_PSIMD_PAIR_RR_VXSAT_STATE \case_id, \insn, \sat1_1_lo, \ + \sat1_1_hi, \sat1_2_lo, \sat1_2_hi, \ + \sat1_exp_lo, \sat1_exp_hi, 0, 1 + TEST_PSIMD_PAIR_RR_VXSAT_STATE \case_id, \insn, \sat2_1_lo, \ + \sat2_1_hi, \sat2_2_lo, \sat2_2_hi, \ + \sat2_exp_lo, \sat2_exp_hi, 0, 1 + TEST_PSIMD_PAIR_RR_VXSAT_STATE \case_id, \insn, 0, 0, 0, 0, \ + 0, 0, 1, 1 + TEST_PSIMD_PAIR_RR_RD_RS1 \case_id, \insn, \normal1_lo, \normal1_hi, \ + \normal2_lo, \normal2_hi, \normal_exp_lo, \ + \normal_exp_hi + TEST_PSIMD_PAIR_RR_RD_RS2 \case_id, \insn, \normal1_lo, \normal1_hi, \ + \normal2_lo, \normal2_hi, \normal_exp_lo, \ + \normal_exp_hi +.endm diff --git a/tests/tcg/riscv32/Makefile.target b/tests/tcg/riscv32/Makefile= .target new file mode 100644 index 00000000000..8f25cfb906a --- /dev/null +++ b/tests/tcg/riscv32/Makefile.target @@ -0,0 +1,30 @@ +# -*- Mode: makefile -*- +# RISC-V specific tweaks +# SPDX-License-Identifier: GPL-2.0-or-later + +VPATH +=3D $(SRC_PATH)/tests/tcg/riscv32 +VPATH +=3D $(SRC_PATH)/tests/tcg/riscv + +# Export PSIMD_CC=3D/path/to/clang to enable these freestanding tests with= out +# making the P-aware compiler the CC for every RISC-V TCG test. +PSIMD_CFLAGS =3D --target=3Driscv32-unknown-linux-gnu \ + -Wall -Werror -O0 -g -Wno-error=3Dunused-command-line-argument \ + -menable-experimental-extensions -march=3Drv32gp0p21 -mabi=3Dilp32 +PSIMD_LDFLAGS =3D -nostdlib -static -fuse-ld=3Dlld -Wl,-e,_start + +ifneq ($(strip $(PSIMD_CC)),) +TESTS +=3D psimd-rv32 +endif + +psimd-rv32: psimd-rv32.S \ + $(SRC_PATH)/tests/tcg/riscv/psimd-common.S \ + $(SRC_PATH)/tests/tcg/riscv/psimd-test-macros.inc +ifeq ($(strip $(PSIMD_CC)),) + $(error Set PSIMD_CC to a Clang with RISC-V P extension support) +else + $(call quiet-command,$(PSIMD_CC) $(PSIMD_CFLAGS) -Wa$(COMMA)--noexecstack= \ + $< -o $@ $(PSIMD_LDFLAGS),CC,$@) +endif + +run-psimd-rv32: QEMU_OPTS +=3D \ + -cpu rv32,x-p=3Dtrue,zmmul=3Dtrue,zba=3Dtrue,zbb=3Dtrue diff --git a/tests/tcg/riscv64/Makefile.target b/tests/tcg/riscv64/Makefile= .target index 4da5b9a3b32..e6645487f56 100644 --- a/tests/tcg/riscv64/Makefile.target +++ b/tests/tcg/riscv64/Makefile.target @@ -2,9 +2,34 @@ # RISC-V specific tweaks =20 VPATH +=3D $(SRC_PATH)/tests/tcg/riscv64 +VPATH +=3D $(SRC_PATH)/tests/tcg/riscv TESTS +=3D test-div TESTS +=3D noexec =20 +# Export PSIMD_CC=3D/path/to/clang to enable these freestanding tests with= out +# making the P-aware compiler the CC for every RISC-V TCG test. +PSIMD_CFLAGS =3D --target=3Driscv64-unknown-linux-gnu \ + -Wall -Werror -O0 -g -Wno-error=3Dunused-command-line-argument \ + -menable-experimental-extensions -march=3Drv64gp0p21 -mabi=3Dlp64d +PSIMD_LDFLAGS =3D -nostdlib -static -fuse-ld=3Dlld -Wl,-e,_start + +ifneq ($(strip $(PSIMD_CC)),) +TESTS +=3D psimd-rv64 +endif + +psimd-rv64: psimd-rv64.S \ + $(SRC_PATH)/tests/tcg/riscv/psimd-common.S \ + $(SRC_PATH)/tests/tcg/riscv/psimd-test-macros.inc +ifeq ($(strip $(PSIMD_CC)),) + $(error Set PSIMD_CC to a Clang with RISC-V P extension support) +else + $(call quiet-command,$(PSIMD_CC) $(PSIMD_CFLAGS) -Wa$(COMMA)--noexecstack= \ + $< -o $@ $(PSIMD_LDFLAGS),CC,$@) +endif + +run-psimd-rv64: QEMU_OPTS +=3D \ + -cpu rv64,x-p=3Dtrue,zmmul=3Dtrue,zba=3Dtrue,zbb=3Dtrue + # Disable compressed instructions for test-noc TESTS +=3D test-noc test-noc: LDFLAGS =3D -nostdlib -static --=20 2.34.1