get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.2/patches/2224357/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2224357,
    "url": "http://patchwork.ozlabs.org/api/1.2/patches/2224357/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260417104652.17857-6-xiaoou@iscas.ac.cn/",
    "project": {
        "id": 14,
        "url": "http://patchwork.ozlabs.org/api/1.2/projects/14/?format=api",
        "name": "QEMU Development",
        "link_name": "qemu-devel",
        "list_id": "qemu-devel.nongnu.org",
        "list_email": "qemu-devel@nongnu.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260417104652.17857-6-xiaoou@iscas.ac.cn>",
    "list_archive_url": null,
    "date": "2026-04-17T10:46:42",
    "name": "[05/14] target/riscv: rvp: add shift operations",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "fa0dd6fac1c795c9dbfa98dc4d5cb60f163f8615",
    "submitter": {
        "id": 89843,
        "url": "http://patchwork.ozlabs.org/api/1.2/people/89843/?format=api",
        "name": "Molly Chen",
        "email": "xiaoou@iscas.ac.cn"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260417104652.17857-6-xiaoou@iscas.ac.cn/mbox/",
    "series": [
        {
            "id": 500305,
            "url": "http://patchwork.ozlabs.org/api/1.2/series/500305/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=500305",
            "date": "2026-04-17T10:42:47",
            "name": "target/riscv: add support for RISC-V P extension (v0.20 draft)",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/500305/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2224357/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2224357/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)",
        "Received": [
            "from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fxs630WMqz1yCv\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 17 Apr 2026 20:47:39 +1000 (AEST)",
            "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wDgjS-0001Bn-1U; Fri, 17 Apr 2026 06:47:31 -0400",
            "from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <xiaoou@iscas.ac.cn>)\n id 1wDgjK-00014V-Ds; Fri, 17 Apr 2026 06:47:22 -0400",
            "from smtp21.cstnet.cn ([159.226.251.21] helo=cstnet.cn)\n by eggs.gnu.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256)\n (Exim 4.90_1) (envelope-from <xiaoou@iscas.ac.cn>)\n id 1wDgjG-0007yy-PO; Fri, 17 Apr 2026 06:47:22 -0400",
            "from Huawei.localdomain (unknown [36.110.52.2])\n by APP-01 (Coremail) with SMTP id qwCowAB3H2ulD+JpLDmSDQ--.804S7;\n Fri, 17 Apr 2026 18:47:12 +0800 (CST)"
        ],
        "From": "Molly Chen <xiaoou@iscas.ac.cn>",
        "To": "palmer@dabbelt.com, alistair.francis@wdc.com, liwei1518@gmail.com,\n daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com,\n chao.liu.zevorn@gmail.com",
        "Cc": "xiaoou@iscas.ac.cn,\n\tqemu-riscv@nongnu.org,\n\tqemu-devel@nongnu.org",
        "Subject": "[PATCH 05/14] target/riscv: rvp: add shift operations",
        "Date": "Fri, 17 Apr 2026 18:46:42 +0800",
        "Message-Id": "<20260417104652.17857-6-xiaoou@iscas.ac.cn>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20260417104652.17857-1-xiaoou@iscas.ac.cn>",
        "References": "<20260417104652.17857-1-xiaoou@iscas.ac.cn>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-CM-TRANSID": "qwCowAB3H2ulD+JpLDmSDQ--.804S7",
        "X-Coremail-Antispam": "1UD129KBjvAXoWftr1ruFyrAw48CrW7Zr1fWFg_yoW8Kr1rWo\n ZxKw1Yyw1fGr13u348uw48Xr1Iqry2vw1DJr4rZr4UXa97Wr12gF15J34kZF4xJrWayrW5\n XFZ3KF95JF1akr93n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3\n AaLaJ3UjIYCTnIWjp_UUUOU7AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva\n j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r126s0DM28Irc\n Ia0xkI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l\n 84ACjcxK6xIIjxv20xvE14v26r4j6ryUM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26F4j6r\n 4UJwA2z4x0Y4vEx4A2jsIE14v26rxl6s0DM28EF7xvwVC2z280aVCY1x0267AKxVW0oVCq\n 3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7\n IYx2IY67AKxVWUXVWUAwAv7VC2z280aVAFwI0_Gr0_Cr1lOx8S6xCaFVCjc4AY6r1j6r4U\n M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwCY1x0262kKe7AKxVWUtV\n W8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v2\n 6r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2\n Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_\n Cr0_Gr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJw\n CI42IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7VUbnNVPUU\n UUU==",
        "X-Originating-IP": "[36.110.52.2]",
        "X-CM-SenderInfo": "50ld003x6l2u1dvotugofq/",
        "Received-SPF": "pass client-ip=159.226.251.21; envelope-from=xiaoou@iscas.ac.cn;\n helo=cstnet.cn",
        "X-Spam_score_int": "-21",
        "X-Spam_score": "-2.2",
        "X-Spam_bar": "--",
        "X-Spam_report": "(-2.2 / 5.0 requ) BAYES_00=-1.9, HK_RANDOM_ENVFROM=0.998,\n HK_RANDOM_FROM=0.998, RCVD_IN_DNSWL_MED=-2.3,\n RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001,\n 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 <qemu-devel.nongnu.org>",
        "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>",
        "List-Post": "<mailto:qemu-devel@nongnu.org>",
        "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>",
        "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>",
        "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org",
        "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"
    },
    "content": "Signed-off-by: Molly Chen <xiaoou@iscas.ac.cn>\n---\n target/riscv/helper.h                   |  34 ++\n target/riscv/insn32.decode              |  44 ++\n target/riscv/insn_trans/trans_rvp.c.inc |  34 ++\n target/riscv/psimd_helper.c             | 736 ++++++++++++++++++++++++\n 4 files changed, 848 insertions(+)",
    "diff": "diff --git a/target/riscv/helper.h b/target/riscv/helper.h\nindex f6351ecd43..d97552eb58 100644\n--- a/target/riscv/helper.h\n+++ b/target/riscv/helper.h\n@@ -1449,3 +1449,37 @@ DEF_HELPER_3(mseq, i32, env, i32, i32)\n DEF_HELPER_3(mslt, i32, env, i32, i32)\n DEF_HELPER_3(msltu, i32, env, i32, i32)\n \n+/* Packed SIMD - Shift Operations */\n+DEF_HELPER_3(pslli_b, tl, env, tl, tl)\n+DEF_HELPER_3(psll_bs, tl, env, tl, tl)\n+DEF_HELPER_3(pslli_h, tl, env, tl, tl)\n+DEF_HELPER_3(psll_hs, tl, env, tl, tl)\n+DEF_HELPER_3(pslli_w, i64, env, i64, i64)\n+DEF_HELPER_3(psll_ws, i64, env, i64, i64)\n+DEF_HELPER_3(psrli_b, tl, env, tl, tl)\n+DEF_HELPER_3(psrl_bs, tl, env, tl, tl)\n+DEF_HELPER_3(psrli_h, tl, env, tl, tl)\n+DEF_HELPER_3(psrl_hs, tl, env, tl, tl)\n+DEF_HELPER_3(psrli_w, i64, env, i64, i64)\n+DEF_HELPER_3(psrl_ws, i64, env, i64, i64)\n+DEF_HELPER_3(psrai_b, tl, env, tl, tl)\n+DEF_HELPER_3(psra_bs, tl, env, tl, tl)\n+DEF_HELPER_3(psrai_h, tl, env, tl, tl)\n+DEF_HELPER_3(psra_hs, tl, env, tl, tl)\n+DEF_HELPER_3(psrai_w, i64, env, i64, i64)\n+DEF_HELPER_3(psra_ws, i64, env, i64, i64)\n+DEF_HELPER_3(psslai_h, tl, env, tl, tl)\n+DEF_HELPER_3(psslai_w, i64, env, i64, i64)\n+DEF_HELPER_3(sslai, i32, env, i32, i32)\n+DEF_HELPER_3(psrari_h, tl, env, tl, tl)\n+DEF_HELPER_3(psrari_w, i64, env, i64, i64)\n+DEF_HELPER_3(srari_32, i32, env, i32, i32)\n+DEF_HELPER_3(srari_64, i64, env, i64, i64)\n+DEF_HELPER_3(pssha_hs, tl, env, tl, tl)\n+DEF_HELPER_3(pssha_ws, i64, env, i64, i64)\n+DEF_HELPER_3(psshar_hs, tl, env, tl, tl)\n+DEF_HELPER_3(psshar_ws, i64, env, i64, i64)\n+DEF_HELPER_3(ssha, i32, env, i32, i32)\n+DEF_HELPER_3(sshar, i32, env, i32, i32)\n+DEF_HELPER_3(sha, i64, env, i64, i64)\n+DEF_HELPER_3(shar, i64, env, i64, i64)\ndiff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode\nindex 2034041639..69514e2cb9 100644\n--- a/target/riscv/insn32.decode\n+++ b/target/riscv/insn32.decode\n@@ -40,6 +40,7 @@\n %imm_z6   26:1 15:5\n %imm_mop5 30:1 26:2 20:2\n %imm_mop3 30:1 26:2\n+%imm_p_ui8  20:3\n %imm_p_ui16 20:4\n %imm_p_ui32 20:5\n %imm_p_ui64 20:6\n@@ -108,6 +109,7 @@\n @mop5 . . .. .. .... .. ..... ... ..... ....... &mop5 imm=%imm_mop5 %rd %rs1\n @mop3 . . .. .. . ..... ..... ... ..... ....... &mop3 imm=%imm_mop3 %rd %rs1 %rs2\n \n+@p_ui8  ..... .... ... ..... ... ..... ....... &i imm=%imm_p_ui8  %rs1 %rd\n @p_ui16 ..... .... ... ..... ... ..... ....... &i imm=%imm_p_ui16 %rs1 %rd\n @p_ui32 ..... .... ... ..... ... ..... ....... &i imm=%imm_p_ui32 %rs1 %rd\n @p_ui64 ..... .... ... ..... ... ..... ....... &i imm=%imm_p_ui64 %rs1 %rd\n@@ -1219,3 +1221,45 @@ pminu_w    1110101 ..... ..... 110 ..... 0111011 @r\n pmax_w     1111001 ..... ..... 110 ..... 0111011 @r\n pmaxu_w    1111101 ..... ..... 110 ..... 0111011 @r\n \n+# Packed SIMD - Shift Operations\n+pslli_b    10000 0001... ..... 010 ..... 0011011 @p_ui8\n+psll_bs    1000110 ..... ..... 010 ..... 0011011 @r\n+pslli_h    10000 001.... ..... 010 ..... 0011011 @p_ui16\n+psll_hs    1000100 ..... ..... 010 ..... 0011011 @r\n+pslli_w    10000 01..... ..... 010 ..... 0011011 @p_ui32\n+psll_ws    1000101 ..... ..... 010 ..... 0011011 @r\n+psrli_b    10000 0001... ..... 100 ..... 0011011 @p_ui8\n+psrl_bs    1000110 ..... ..... 100 ..... 0011011 @r\n+psrli_h    10000 001.... ..... 100 ..... 0011011 @p_ui16\n+psrl_hs    1000100 ..... ..... 100 ..... 0011011 @r\n+psrli_w    10000 01..... ..... 100 ..... 0011011 @p_ui32\n+psrl_ws    1000101 ..... ..... 100 ..... 0011011 @r\n+psrai_b    11000 0001... ..... 100 ..... 0011011 @p_ui8\n+psra_bs    1100110 ..... ..... 100 ..... 0011011 @r\n+psrai_h    11000 001.... ..... 100 ..... 0011011 @p_ui16\n+psra_hs    1100100 ..... ..... 100 ..... 0011011 @r\n+psrai_w    11000 01..... ..... 100 ..... 0011011 @p_ui32\n+psra_ws    1100101 ..... ..... 100 ..... 0011011 @r\n+psslai_h   11010 001.... ..... 010 ..... 0011011 @p_ui16\n+{\n+  sslai    11010 01..... ..... 010 ..... 0011011 @p_ui32\n+  psslai_w 11010 01..... ..... 010 ..... 0011011 @p_ui32\n+}\n+psrari_h   11010 001.... ..... 100 ..... 0011011 @p_ui16\n+{\n+  srari_32 11010 01..... ..... 100 ..... 0011011 @p_ui32\n+  psrari_w 11010 01..... ..... 100 ..... 0011011 @p_ui32\n+}\n+srari_64   110101 ...... ..... 100 ..... 0011011 @p_ui64\n+pssha_hs   1110100 ..... ..... 010 ..... 0011011 @r\n+{\n+  ssha     1110101 ..... ..... 010 ..... 0011011 @r\n+  pssha_ws 1110101 ..... ..... 010 ..... 0011011 @r\n+}\n+psshar_hs  1111100 ..... ..... 010 ..... 0011011 @r\n+{\n+  sshar    1111101 ..... ..... 010 ..... 0011011 @r\n+  psshar_ws 1111101 ..... ..... 010 ..... 0011011 @r\n+}\n+sha        1110111 ..... ..... 010 ..... 0011011 @r\n+shar       1111111 ..... ..... 010 ..... 0011011 @r\ndiff --git a/target/riscv/insn_trans/trans_rvp.c.inc b/target/riscv/insn_trans/trans_rvp.c.inc\nindex 27d482863c..d0b645d083 100644\n--- a/target/riscv/insn_trans/trans_rvp.c.inc\n+++ b/target/riscv/insn_trans/trans_rvp.c.inc\n@@ -620,3 +620,37 @@ GEN_SIMD_TRANS_32(mseq)\n GEN_SIMD_TRANS_32(mslt)\n GEN_SIMD_TRANS_32(msltu)\n \n+/* Packed SIMD - Shift Operations */\n+GEN_SIMD_TRANS_IMM(pslli_b)\n+GEN_SIMD_TRANS(psll_bs)\n+GEN_SIMD_TRANS_IMM(pslli_h)\n+GEN_SIMD_TRANS(psll_hs)\n+GEN_SIMD_TRANS_IMM_64(pslli_w)\n+GEN_SIMD_TRANS_64(psll_ws)\n+GEN_SIMD_TRANS_IMM(psrli_b)\n+GEN_SIMD_TRANS(psrl_bs)\n+GEN_SIMD_TRANS_IMM(psrli_h)\n+GEN_SIMD_TRANS(psrl_hs)\n+GEN_SIMD_TRANS_IMM_64(psrli_w)\n+GEN_SIMD_TRANS_64(psrl_ws)\n+GEN_SIMD_TRANS_IMM(psrai_b)\n+GEN_SIMD_TRANS(psra_bs)\n+GEN_SIMD_TRANS_IMM(psrai_h)\n+GEN_SIMD_TRANS(psra_hs)\n+GEN_SIMD_TRANS_IMM_64(psrai_w)\n+GEN_SIMD_TRANS_64(psra_ws)\n+GEN_SIMD_TRANS_IMM(psslai_h)\n+GEN_SIMD_TRANS_IMM_64(psslai_w)\n+GEN_SIMD_TRANS_IMM_32(sslai)\n+GEN_SIMD_TRANS_IMM(psrari_h)\n+GEN_SIMD_TRANS_IMM_64(psrari_w)\n+GEN_SIMD_TRANS_IMM_32(srari_32)\n+GEN_SIMD_TRANS_IMM_64(srari_64)\n+GEN_SIMD_TRANS(pssha_hs)\n+GEN_SIMD_TRANS_64(pssha_ws)\n+GEN_SIMD_TRANS(psshar_hs)\n+GEN_SIMD_TRANS_64(psshar_ws)\n+GEN_SIMD_TRANS_32(ssha)\n+GEN_SIMD_TRANS_32(sshar)\n+GEN_SIMD_TRANS_64(sha)\n+GEN_SIMD_TRANS_64(shar)\ndiff --git a/target/riscv/psimd_helper.c b/target/riscv/psimd_helper.c\nindex 38207c3a39..ef556eb007 100644\n--- a/target/riscv/psimd_helper.c\n+++ b/target/riscv/psimd_helper.c\n@@ -1967,3 +1967,739 @@ uint32_t HELPER(msltu)(CPURISCVState *env, uint32_t rs1, uint32_t rs2)\n     return (rs1 < rs2) ? 0xFFFFFFFFU : 0x00000000U;\n }\n \n+/* Shift operations (immediate and register) */\n+\n+/**\n+ * PSLLI.B - Packed 8-bit logical shift left immediate\n+ * For each byte: rd[i] = rs1[i] << imm\n+ */\n+target_ulong HELPER(pslli_b)(CPURISCVState *env,\n+                             target_ulong rs1, target_ulong imm)\n+{\n+    target_ulong rd = 0;\n+    int elems = ELEMS_B(rd);\n+    uint8_t shamt = imm & 0x07;  /* 8-bit elements, max shift 7 */\n+\n+    for (int i = 0; i < elems; i++) {\n+        uint8_t e1 = EXTRACT8(rs1, i);\n+        uint8_t res = e1 << shamt;\n+        rd = INSERT8(rd, res, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSLL.BS - Packed 8-bit logical shift left from register\n+ * For each byte: rd[i] = rs1[i] << rs2[4:0]\n+ */\n+target_ulong HELPER(psll_bs)(CPURISCVState *env,\n+                             target_ulong rs1, target_ulong rs2)\n+{\n+    target_ulong rd = 0;\n+    int elems = ELEMS_B(rd);\n+    uint8_t shamt = rs2 & 0x07;  /* rs2[2:0] for 8-bit */\n+\n+    for (int i = 0; i < elems; i++) {\n+        uint8_t e1 = EXTRACT8(rs1, i);\n+        uint8_t res = e1 << shamt;\n+        rd = INSERT8(rd, res, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSLLI.H - Packed 16-bit logical shift left immediate\n+ * For each halfword: rd[i] = rs1[i] << imm\n+ */\n+target_ulong HELPER(pslli_h)(CPURISCVState *env,\n+                             target_ulong rs1, target_ulong imm)\n+{\n+    target_ulong rd = 0;\n+    int elems = ELEMS_H(rd);\n+    uint8_t shamt = imm & 0x0F;  /* 16-bit elements, max shift 15 */\n+\n+    for (int i = 0; i < elems; i++) {\n+        uint16_t e1 = EXTRACT16(rs1, i);\n+        uint16_t res = e1 << shamt;\n+        rd = INSERT16(rd, res, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSLL.HS - Packed 16-bit logical shift left from register\n+ * For each halfword: rd[i] = rs1[i] << rs2[4:0]\n+ */\n+target_ulong HELPER(psll_hs)(CPURISCVState *env,\n+                             target_ulong rs1, target_ulong rs2)\n+{\n+    target_ulong rd = 0;\n+    int elems = ELEMS_H(rd);\n+    uint8_t shamt = rs2 & 0x0F;  /* rs2[3:0] for 16-bit */\n+\n+    for (int i = 0; i < elems; i++) {\n+        uint16_t e1 = EXTRACT16(rs1, i);\n+        uint16_t res = e1 << shamt;\n+        rd = INSERT16(rd, res, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSLLI.W - Packed 32-bit logical shift left immediate (RV64 only)\n+ * For each word: rd[i] = rs1[i] << imm\n+ */\n+uint64_t HELPER(pslli_w)(CPURISCVState *env, uint64_t rs1, uint64_t imm)\n+{\n+    uint64_t rd = 0;\n+    int elems = 2;\n+    uint8_t shamt = imm & 0x1F;  /* 32-bit elements, max shift 31 */\n+\n+    for (int i = 0; i < elems; i++) {\n+        uint32_t e1 = EXTRACT32(rs1, i);\n+        uint32_t res = e1 << shamt;\n+        rd = INSERT32(rd, res, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSLL.WS - Packed 32-bit logical shift left from register (RV64 only)\n+ * For each word: rd[i] = rs1[i] << rs2[5:0]\n+ */\n+uint64_t HELPER(psll_ws)(CPURISCVState *env, uint64_t rs1, uint64_t rs2)\n+{\n+    uint64_t rd = 0;\n+    int elems = 2;\n+    uint8_t shamt = rs2 & 0x1F;\n+\n+    for (int i = 0; i < elems; i++) {\n+        uint32_t e1 = EXTRACT32(rs1, i);\n+        uint32_t res = e1 << shamt;\n+        rd = INSERT32(rd, res, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSRLI.B - Packed 8-bit logical shift right immediate\n+ * For each byte: rd[i] = rs1[i] >> imm\n+ */\n+target_ulong HELPER(psrli_b)(CPURISCVState *env,\n+                             target_ulong rs1, target_ulong imm)\n+{\n+    target_ulong rd = 0;\n+    int elems = ELEMS_B(rd);\n+    uint8_t shamt = imm & 0x07;\n+\n+    for (int i = 0; i < elems; i++) {\n+        uint8_t e1 = EXTRACT8(rs1, i);\n+        uint8_t res = e1 >> shamt;\n+        rd = INSERT8(rd, res, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSRL.BS - Packed 8-bit logical shift right from register\n+ * For each byte: rd[i] = rs1[i] >> rs2[4:0]\n+ */\n+target_ulong HELPER(psrl_bs)(CPURISCVState *env,\n+                             target_ulong rs1, target_ulong rs2)\n+{\n+    target_ulong rd = 0;\n+    int elems = ELEMS_B(rd);\n+    uint8_t shamt = rs2 & 0x07;\n+\n+    for (int i = 0; i < elems; i++) {\n+        uint8_t e1 = EXTRACT8(rs1, i);\n+        uint8_t res = e1 >> shamt;\n+        rd = INSERT8(rd, res, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSRLI.H - Packed 16-bit logical shift right immediate\n+ * For each halfword: rd[i] = rs1[i] >> imm\n+ */\n+target_ulong HELPER(psrli_h)(CPURISCVState *env,\n+                             target_ulong rs1, target_ulong imm)\n+{\n+    target_ulong rd = 0;\n+    int elems = ELEMS_H(rd);\n+    uint8_t shamt = imm & 0x0F;\n+\n+    for (int i = 0; i < elems; i++) {\n+        uint16_t e1 = EXTRACT16(rs1, i);\n+        uint16_t res = e1 >> shamt;\n+        rd = INSERT16(rd, res, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSRL.HS - Packed 16-bit logical shift right from register\n+ * For each halfword: rd[i] = rs1[i] >> rs2[4:0]\n+ */\n+target_ulong HELPER(psrl_hs)(CPURISCVState *env,\n+                             target_ulong rs1, target_ulong rs2)\n+{\n+    target_ulong rd = 0;\n+    int elems = ELEMS_H(rd);\n+    uint8_t shamt = rs2 & 0x0F;\n+\n+    for (int i = 0; i < elems; i++) {\n+        uint16_t e1 = EXTRACT16(rs1, i);\n+        uint16_t res = e1 >> shamt;\n+        rd = INSERT16(rd, res, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSRLI.W - Packed 32-bit logical shift right immediate (RV64 only)\n+ * For each word: rd[i] = rs1[i] >> imm\n+ */\n+uint64_t HELPER(psrli_w)(CPURISCVState *env, uint64_t rs1, uint64_t imm)\n+{\n+    uint64_t rd = 0;\n+    int elems = 2;\n+    uint8_t shamt = imm & 0x1F;\n+\n+    for (int i = 0; i < elems; i++) {\n+        uint32_t e1 = EXTRACT32(rs1, i);\n+        uint32_t res = e1 >> shamt;\n+        rd = INSERT32(rd, res, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSRL.WS - Packed 32-bit logical shift right from register (RV64 only)\n+ * For each word: rd[i] = rs1[i] >> rs2[5:0]\n+ */\n+uint64_t HELPER(psrl_ws)(CPURISCVState *env, uint64_t rs1, uint64_t rs2)\n+{\n+    uint64_t rd = 0;\n+    int elems = 2;\n+    uint8_t shamt = rs2 & 0x1F;\n+\n+    for (int i = 0; i < elems; i++) {\n+        uint32_t e1 = EXTRACT32(rs1, i);\n+        uint32_t res = e1 >> shamt;\n+        rd = INSERT32(rd, res, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSRAI.B - Packed 8-bit arithmetic shift right immediate\n+ * For each byte: rd[i] = (int8_t)rs1[i] >> imm\n+ */\n+target_ulong HELPER(psrai_b)(CPURISCVState *env,\n+                             target_ulong rs1, target_ulong imm)\n+{\n+    target_ulong rd = 0;\n+    int elems = ELEMS_B(rd);\n+    uint8_t shamt = imm & 0x07;\n+\n+    for (int i = 0; i < elems; i++) {\n+        int8_t e1 = (int8_t)EXTRACT8(rs1, i);\n+        int8_t res = e1 >> shamt;  /* Arithmetic right shift */\n+        rd = INSERT8(rd, (uint8_t)res, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSRA.BS - Packed 8-bit arithmetic shift right from register\n+ * For each byte: rd[i] = (int8_t)rs1[i] >> rs2[4:0]\n+ */\n+target_ulong HELPER(psra_bs)(CPURISCVState *env,\n+                             target_ulong rs1, target_ulong rs2)\n+{\n+    target_ulong rd = 0;\n+    int elems = ELEMS_B(rd);\n+    uint8_t shamt = rs2 & 0x07;\n+\n+    for (int i = 0; i < elems; i++) {\n+        int8_t e1 = (int8_t)EXTRACT8(rs1, i);\n+        int8_t res = e1 >> shamt;\n+        rd = INSERT8(rd, (uint8_t)res, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSRAI.H - Packed 16-bit arithmetic shift right immediate\n+ * For each halfword: rd[i] = (int16_t)rs1[i] >> imm\n+ */\n+target_ulong HELPER(psrai_h)(CPURISCVState *env,\n+                             target_ulong rs1, target_ulong imm)\n+{\n+    target_ulong rd = 0;\n+    int elems = ELEMS_H(rd);\n+    uint8_t shamt = imm & 0x0F;\n+\n+    for (int i = 0; i < elems; i++) {\n+        int16_t e1 = (int16_t)EXTRACT16(rs1, i);\n+        int16_t res = e1 >> shamt;\n+        rd = INSERT16(rd, (uint16_t)res, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSRA.HS - Packed 16-bit arithmetic shift right from register\n+ * For each halfword: rd[i] = (int16_t)rs1[i] >> rs2[4:0]\n+ */\n+target_ulong HELPER(psra_hs)(CPURISCVState *env,\n+                             target_ulong rs1, target_ulong rs2)\n+{\n+    target_ulong rd = 0;\n+    int elems = ELEMS_H(rd);\n+    uint8_t shamt = rs2 & 0x0F;\n+\n+    for (int i = 0; i < elems; i++) {\n+        int16_t e1 = (int16_t)EXTRACT16(rs1, i);\n+        int16_t res = e1 >> shamt;\n+        rd = INSERT16(rd, (uint16_t)res, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSRAI.W - Packed 32-bit arithmetic shift right immediate (RV64 only)\n+ * For each word: rd[i] = (int32_t)rs1[i] >> imm\n+ */\n+uint64_t HELPER(psrai_w)(CPURISCVState *env, uint64_t rs1, uint64_t imm)\n+{\n+    uint64_t rd = 0;\n+    int elems = 2;\n+    uint8_t shamt = imm & 0x1F;\n+\n+    for (int i = 0; i < elems; i++) {\n+        int32_t e1 = (int32_t)EXTRACT32(rs1, i);\n+        int32_t res = e1 >> shamt;\n+        rd = INSERT32(rd, (uint32_t)res, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSRA.WS - Packed 32-bit arithmetic shift right from register (RV64 only)\n+ * For each word: rd[i] = (int32_t)rs1[i] >> rs2[5:0]\n+ */\n+uint64_t HELPER(psra_ws)(CPURISCVState *env, uint64_t rs1, uint64_t rs2)\n+{\n+    uint64_t rd = 0;\n+    int elems = 2;\n+    uint8_t shamt = rs2 & 0x1F;\n+\n+    for (int i = 0; i < elems; i++) {\n+        int32_t e1 = (int32_t)EXTRACT32(rs1, i);\n+        int32_t res = e1 >> shamt;\n+        rd = INSERT32(rd, (uint32_t)res, i);\n+    }\n+    return rd;\n+}\n+\n+/* Saturating shift operations */\n+\n+/**\n+ * PSSLAI.H - Packed 16-bit saturating shift left immediate\n+ * For each halfword: rd[i] = sat16(rs1[i] << imm)\n+ */\n+target_ulong HELPER(psslai_h)(CPURISCVState *env,\n+                              target_ulong rs1, target_ulong imm)\n+{\n+    target_ulong rd = 0;\n+    int elems = ELEMS_H(rd);\n+    int sat = 0;\n+    uint8_t shamt = imm & 0x0F;\n+\n+    for (int i = 0; i < elems; i++) {\n+        int16_t e1 = (int16_t)EXTRACT16(rs1, i);\n+        int32_t shifted = (int32_t)e1 << shamt;\n+        int16_t res = signed_saturate_h(shifted, &sat);\n+        rd = INSERT16(rd, res, i);\n+    }\n+\n+    if (sat) {\n+        env->vxsat = 1;\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSSLAI.W - Packed 32-bit saturating shift left immediate (RV64 only)\n+ * For each word: rd[i] = sat32(rs1[i] << imm)\n+ */\n+uint64_t HELPER(psslai_w)(CPURISCVState *env, uint64_t rs1, uint64_t imm)\n+{\n+    uint64_t rd = 0;\n+    int elems = 2;\n+    int sat = 0;\n+    uint8_t shamt = imm & 0x1F;\n+\n+    for (int i = 0; i < elems; i++) {\n+        int32_t e1 = (int32_t)EXTRACT32(rs1, i);\n+        int64_t shifted = (int64_t)e1 << shamt;\n+        int32_t res = signed_saturate_w(shifted, &sat);\n+        rd = INSERT32(rd, res, i);\n+    }\n+\n+    if (sat) {\n+        env->vxsat = 1;\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * SSLAL - 32-bit scalar saturating shift left immediate\n+ */\n+uint32_t HELPER(sslai)(CPURISCVState *env, uint32_t rs1, uint32_t imm)\n+{\n+    int32_t a = (int32_t)rs1;\n+    uint8_t shamt = imm & 0x1F;\n+    int64_t shifted = (int64_t)a << shamt;\n+    int sat = 0;\n+    int32_t res = signed_saturate_w(shifted, &sat);\n+\n+    if (sat) {\n+        env->vxsat = 1;\n+    }\n+    return (uint32_t)res;\n+}\n+\n+/* Rounding shift operations */\n+\n+/**\n+ * PSRARI.H - Packed 16-bit arithmetic shift right with rounding (immediate)\n+ * For each halfword: rd[i] = round((int16_t)rs1[i] >> imm)\n+ */\n+target_ulong HELPER(psrari_h)(CPURISCVState *env,\n+                              target_ulong rs1, target_ulong imm)\n+{\n+    target_ulong rd = 0;\n+    int elems = ELEMS_H(rd);\n+    uint8_t shamt = imm & 0x0F;\n+\n+    if (shamt == 0) {\n+        return rs1;\n+    }\n+\n+    for (int i = 0; i < elems; i++) {\n+        int16_t e1 = (int16_t)EXTRACT16(rs1, i);\n+        int32_t rounded = ((e1 >> (shamt - 1)) + 1) >> 1;\n+        rd = INSERT16(rd, (int16_t)rounded, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSRARI.W - Packed 32-bit arithmetic shift right\n+ * with rounding (immediate) (RV64 only)\n+ * For each word: rd[i] = round((int32_t)rs1[i] >> imm)\n+ */\n+uint64_t HELPER(psrari_w)(CPURISCVState *env, uint64_t rs1, uint64_t imm)\n+{\n+    uint64_t rd = 0;\n+    int elems = 2;\n+    uint8_t shamt = imm & 0x1F;\n+\n+    if (shamt == 0) {\n+        return rs1;\n+    }\n+\n+    for (int i = 0; i < elems; i++) {\n+        int32_t e1 = (int32_t)EXTRACT32(rs1, i);\n+        int64_t rounded = ((e1 >> (shamt - 1)) + 1) >> 1;\n+        rd = INSERT32(rd, (int32_t)rounded, i);\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * SRARI_32 - 32-bit scalar arithmetic shift right with rounding\n+ */\n+uint32_t HELPER(srari_32)(CPURISCVState *env, uint32_t rs1, uint32_t imm)\n+{\n+    int32_t a = (int32_t)rs1;\n+    uint8_t shamt = imm & 0x1F;\n+\n+    if (shamt == 0) {\n+        return rs1;\n+    }\n+\n+    return (uint32_t)(((a >> (shamt - 1)) + 1) >> 1);\n+}\n+\n+/**\n+ * SRARI_64 - 64-bit scalar arithmetic shift right with rounding\n+ */\n+uint64_t HELPER(srari_64)(CPURISCVState *env, uint64_t rs1, uint64_t imm)\n+{\n+    int64_t a = (int64_t)rs1;\n+    uint8_t shamt = imm & 0x3F;\n+\n+    if (shamt == 0) {\n+        return rs1;\n+    }\n+\n+    return (uint64_t)(((a >> (shamt - 1)) + 1) >> 1);\n+}\n+\n+/* Variable shift operations (with saturation and rounding) */\n+\n+/**\n+ * PSSHA.HS - Packed 16-bit variable shift with saturation\n+ * Positive shift left (saturating), negative shift right (non-saturating)\n+ */\n+target_ulong HELPER(pssha_hs)(CPURISCVState *env,\n+                              target_ulong rs1, target_ulong rs2)\n+{\n+    target_ulong rd = 0;\n+    int elems = ELEMS_H(rd);\n+    int sat = 0;\n+    int8_t shamt = (int8_t)(rs2 & 0xFF);  /* rs2[7:0] as signed */\n+\n+    for (int i = 0; i < elems; i++) {\n+        int16_t e1 = (int16_t)EXTRACT16(rs1, i);\n+        int16_t res;\n+\n+        if (shamt >= 0) {\n+            /* Left shift with saturation */\n+            int32_t shifted = (int32_t)e1 << shamt;\n+            res = signed_saturate_h(shifted, &sat);\n+        } else {\n+            /* Right shift (no saturation) */\n+            int right = -shamt;\n+            if (right >= 16) {\n+                res = (e1 < 0) ? -1 : 0;\n+            } else {\n+                res = e1 >> right;\n+            }\n+        }\n+\n+        rd = INSERT16(rd, res, i);\n+    }\n+\n+    if (sat) {\n+        env->vxsat = 1;\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSSHA.WS - Packed 32-bit variable shift with saturation (RV64 only)\n+ * Positive shift left (saturating), negative shift right (non-saturating)\n+ */\n+uint64_t HELPER(pssha_ws)(CPURISCVState *env, uint64_t rs1, uint64_t rs2)\n+{\n+    uint64_t rd = 0;\n+    int elems = 2;\n+    int sat = 0;\n+    int8_t shamt = (int8_t)(rs2 & 0xFF);\n+\n+    for (int i = 0; i < elems; i++) {\n+        int32_t e1 = (int32_t)EXTRACT32(rs1, i);\n+        int32_t res;\n+\n+        if (shamt >= 0) {\n+            int64_t shifted = (int64_t)e1 << shamt;\n+            res = signed_saturate_w(shifted, &sat);\n+        } else {\n+            int right = -shamt;\n+            if (right >= 32) {\n+                res = (e1 < 0) ? -1 : 0;\n+            } else {\n+                res = e1 >> right;\n+            }\n+        }\n+\n+        rd = INSERT32(rd, res, i);\n+    }\n+\n+    if (sat) {\n+        env->vxsat = 1;\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSSHAR.HS - Packed 16-bit variable shift with rounding and saturation\n+ * Positive shift left (saturating), negative shift right (rounded)\n+ */\n+target_ulong HELPER(psshar_hs)(CPURISCVState *env,\n+                               target_ulong rs1, target_ulong rs2)\n+{\n+    target_ulong rd = 0;\n+    int elems = ELEMS_H(rd);\n+    int sat = 0;\n+    int8_t shamt = (int8_t)(rs2 & 0xFF);\n+\n+    for (int i = 0; i < elems; i++) {\n+        int16_t e1 = (int16_t)EXTRACT16(rs1, i);\n+        int16_t res;\n+\n+        if (shamt >= 0) {\n+            /* Left shift with saturation */\n+            int32_t shifted = (int32_t)e1 << shamt;\n+            res = signed_saturate_h(shifted, &sat);\n+        } else {\n+            /* Right shift with rounding */\n+            int right = -shamt;\n+            if (right >= 16) {\n+                res = (e1 < 0) ? -1 : 0;\n+            } else {\n+                int32_t rounded = ((e1 >> (right - 1)) + 1) >> 1;\n+                res = (int16_t)rounded;\n+            }\n+        }\n+\n+        rd = INSERT16(rd, res, i);\n+    }\n+\n+    if (sat) {\n+        env->vxsat = 1;\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * PSSHAR.WS - Packed 32-bit variable shift with\n+ * rounding and saturation (RV64 only)\n+ * Positive shift left (saturating), negative shift right (rounded)\n+ */\n+uint64_t HELPER(psshar_ws)(CPURISCVState *env, uint64_t rs1, uint64_t rs2)\n+{\n+    uint64_t rd = 0;\n+    int elems = 2;\n+    int sat = 0;\n+    int8_t shamt = (int8_t)(rs2 & 0xFF);\n+\n+    for (int i = 0; i < elems; i++) {\n+        int32_t e1 = (int32_t)EXTRACT32(rs1, i);\n+        int32_t res;\n+\n+        if (shamt >= 0) {\n+            int64_t shifted = (int64_t)e1 << shamt;\n+            res = signed_saturate_w(shifted, &sat);\n+        } else {\n+            int right = -shamt;\n+            if (right >= 32) {\n+                res = (e1 < 0) ? -1 : 0;\n+            } else {\n+                int64_t rounded = ((e1 >> (right - 1)) + 1) >> 1;\n+                res = (int32_t)rounded;\n+            }\n+        }\n+\n+        rd = INSERT32(rd, res, i);\n+    }\n+\n+    if (sat) {\n+        env->vxsat = 1;\n+    }\n+    return rd;\n+}\n+\n+/**\n+ * SSHA - 32-bit scalar variable shift with saturation\n+ */\n+uint32_t HELPER(ssha)(CPURISCVState *env, uint32_t rs1, uint32_t rs2)\n+{\n+    int32_t a = (int32_t)rs1;\n+    int8_t shamt = (int8_t)(rs2 & 0xFF);\n+    int sat = 0;\n+    int32_t res;\n+\n+    if (shamt >= 0) {\n+        int64_t shifted = (int64_t)a << shamt;\n+        res = signed_saturate_w(shifted, &sat);\n+    } else {\n+        int right = -shamt;\n+        if (right >= 32) {\n+            res = (a < 0) ? -1 : 0;\n+        } else {\n+            res = a >> right;\n+        }\n+    }\n+\n+    if (sat) {\n+        env->vxsat = 1;\n+    }\n+    return (uint32_t)res;\n+}\n+\n+/**\n+ * SSHAR - 32-bit scalar variable shift with rounding and saturation\n+ */\n+uint32_t HELPER(sshar)(CPURISCVState *env, uint32_t rs1, uint32_t rs2)\n+{\n+    int32_t a = (int32_t)rs1;\n+    int8_t shamt = (int8_t)(rs2 & 0xFF);\n+    int sat = 0;\n+    int32_t res;\n+\n+    if (shamt >= 0) {\n+        int64_t shifted = (int64_t)a << shamt;\n+        res = signed_saturate_w(shifted, &sat);\n+    } else {\n+        int right = -shamt;\n+        if (right >= 32) {\n+            res = (a < 0) ? -1 : 0;\n+        } else {\n+            int64_t rounded = ((a >> (right - 1)) + 1) >> 1;\n+            res = (int32_t)rounded;\n+        }\n+    }\n+\n+    if (sat) {\n+        env->vxsat = 1;\n+    }\n+    return (uint32_t)res;\n+}\n+\n+/**\n+ * SHA - 64-bit scalar variable shift\n+ */\n+uint64_t HELPER(sha)(CPURISCVState *env, uint64_t rs1, uint64_t rs2)\n+{\n+    int64_t a = (int64_t)rs1;\n+    int8_t shamt = (int8_t)(rs2 & 0xFF);\n+\n+    if (shamt >= 0) {\n+        return (uint64_t)(a << shamt);\n+    } else {\n+        int right = -shamt;\n+        if (right >= 64) {\n+            return (a < 0) ? (uint64_t)-1 : 0;\n+        } else {\n+            return (uint64_t)(a >> right);\n+        }\n+    }\n+}\n+\n+/**\n+ * SHAR - 64-bit scalar variable shift with rounding\n+ */\n+uint64_t HELPER(shar)(CPURISCVState *env, uint64_t rs1, uint64_t rs2)\n+{\n+    int64_t a = (int64_t)rs1;\n+    int8_t shamt = (int8_t)(rs2 & 0xFF);\n+\n+    if (shamt >= 0) {\n+        return (uint64_t)(a << shamt);\n+    } else {\n+        int right = -shamt;\n+        if (right >= 64) {\n+            return (a < 0) ? (uint64_t)-1 : 0;\n+        } else {\n+            __int128_t rounded = ((__int128_t)a >> (right - 1)) + 1;\n+            return (uint64_t)((int64_t)(rounded >> 1));\n+        }\n+    }\n+}\n",
    "prefixes": [
        "05/14"
    ]
}