[{"id":3678914,"web_url":"http://patchwork.ozlabs.org/comment/3678914/","msgid":"<59793b74-2ecb-442b-ba67-41d90492b4f5@linaro.org>","list_archive_url":null,"date":"2026-04-18T00:01:03","subject":"Re: [PATCH 02/14] target/riscv: rvp: add arithmetic instructions,\n including saturating and non-saturating operations","submitter":{"id":72104,"url":"http://patchwork.ozlabs.org/api/people/72104/","name":"Richard Henderson","email":"richard.henderson@linaro.org"},"content":"On 4/17/26 20:46, Molly Chen wrote:\n> +/**\n> + * PADD.B - Packed 8-bit addition\n> + * For each byte: rd[i] = rs1[i] + rs2[i] (modular)\n> + */\n> +target_ulong HELPER(padd_b)(CPURISCVState *env,\n> +                          target_ulong rs1, target_ulong rs2)\n> +{\n> +    target_ulong rd = 0;\n> +    int elems = ELEMS_B(rd);\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        uint8_t e1 = EXTRACT8(rs1, i);\n> +        uint8_t e2 = EXTRACT8(rs2, i);\n> +        uint8_t res = e1 + e2;\n> +        rd = INSERT8(rd, res, i);\n> +    }\n> +    return rd;\n> +}\n\ntcg_gen_vec_add8_{i32,i64}.\n\nThere are a fair few other vector operations that can be expanded from wide integer \noperands at the end of include/tcg/tcg-op-gvec-common.h.\n\n\nr~","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\tdkim=pass (2048-bit key;\n unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256\n header.s=google header.b=E4h+smdF;\n\tdkim-atps=neutral","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 4fyBkb0H41z1yDF\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 18 Apr 2026 10:01:57 +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 1wDt7d-0007Tw-MB; Fri, 17 Apr 2026 20:01:17 -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 <richard.henderson@linaro.org>)\n id 1wDt7b-0007Tk-7Z\n for qemu-devel@nongnu.org; Fri, 17 Apr 2026 20:01:15 -0400","from mail-pj1-x102b.google.com ([2607:f8b0:4864:20::102b])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.90_1) (envelope-from <richard.henderson@linaro.org>)\n id 1wDt7Z-00059a-JA\n for qemu-devel@nongnu.org; Fri, 17 Apr 2026 20:01:14 -0400","by mail-pj1-x102b.google.com with SMTP id\n 98e67ed59e1d1-35d90833cacso849889a91.2\n for <qemu-devel@nongnu.org>; Fri, 17 Apr 2026 17:01:11 -0700 (PDT)","from ?IPV6:2401:d002:dc0f:2100:742f:8dfc:5be0:dc23?\n ([2401:d002:dc0f:2100:742f:8dfc:5be0:dc23])\n by smtp.gmail.com with ESMTPSA id\n 41be03b00d2f7-c7976f9cacasm2427470a12.8.2026.04.17.17.01.08\n for <qemu-devel@nongnu.org>\n (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n Fri, 17 Apr 2026 17:01:09 -0700 (PDT)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=linaro.org; s=google; t=1776470471; x=1777075271; darn=nongnu.org;\n h=content-transfer-encoding:in-reply-to:content-language:from\n :references:to:subject:user-agent:mime-version:date:message-id:from\n :to:cc:subject:date:message-id:reply-to;\n bh=le/YmQzmlY9MiCvkr9nid44C8Rmu09QXeLU/kryfTvo=;\n b=E4h+smdFdUqJR48EwZW1SWi/pFAuwJfrvJeNDn5JlprATsKzfTL9dGTPvLf0Ve3qcW\n TXUstaLr9RSWBFaV+PCDQk0ka5ENjy4MtNu3LC0xgNxCW5rxl3c+Ue9w+RFev5YTzNd4\n /Oa/A99Ty3mXeQxM0EXKhjWW0RN5OQFYz76K3/A/3AOcXwHHsKs3kdRU2eOOY9vLqcRd\n LG87nFYDYoLCOD6Xjczt30Fszb7DV2HUrif62tq2z8U7NUtjFppexLplpSDCre0NY5Qk\n YRF2v/Rjf5XaJrLcpXtUBbsJUfFVPJChQc846NjM2aeCNBKMjTsHmGox1bO/A1Uxb7lB\n dq9w==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776470471; x=1777075271;\n h=content-transfer-encoding:in-reply-to:content-language:from\n :references:to:subject:user-agent:mime-version:date:message-id\n :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id\n :reply-to;\n bh=le/YmQzmlY9MiCvkr9nid44C8Rmu09QXeLU/kryfTvo=;\n b=BQvxqd+hAxIipG6mSiYcEduRnKICEGmqT2Is54oYuWaL0vJ8WRHO9jBLm/P8jSKV0M\n 8ZleiH70bIfgBUcamxBYgCi9QDHMxVXTQqS2pArWVKwaOF5IoVBEAv8LgQ4oh/16HT8y\n 5ofUNUxT9BTo4XVGNIrXPumSGkcCgR1/hOSgWk/BMC/gu7ttBYu83UJP+PwR8PZPBNsY\n 9EhQMC3aA6/gsSOffqtC1AYwLAeMZ66xwYaz2nt+PH2C439zrCWFoMC9wwe3wk5cL1Vr\n jtl6MHwigw52+cYGPnyoeyijdk/U2VYjI4Y3nMnYD55WQtCY4VdM4ULAOiz74bMPIRKO\n hb6A==","X-Gm-Message-State":"AOJu0YxtVtppybP6KqRAV+CSpeJqYoZ32m0qiAtUCbUKHYdES1TxnjQo\n GwIRAvxk9GW0FVdO6EG/LJu1iM3W4WyM3t0qWGPgCjqd4BHL9VqrgzXgYQruKzdnFuAGOmWfN9/\n ujW/LJ80=","X-Gm-Gg":"AeBDieuS54FfI/CiDTx+9evVvYkngXWqa+Zi8h/yenHnGSEQZmu3XJrV+PU+2q2Zx1v\n BIZbfnuNo81ojScPUtNYCCFy2d+cGsiOzF4xD36YzJHzn5pRRrliLE2TkSwrYnhJgn9m46yu9El\n S+ppETZp6X6Fc2e+JrTTgO2gBhUog4eAtfl+MyrPncrLexE0DQ9sHQ0d8TwbeRmVhMgyGq3hWrH\n zBJSenHuSXjyU3bpOEdEUbfXdeRj4kH9j7MwEUFuAByZSamntIB2RTITt2RGhxuulcljPca/dbw\n f1/hrB1UQfuulcyTU9FGnq9AX7SNGiMJ01Xl2pdYhR020+pVU1fzzBk/CBbMeIF9TIwrfsjO9Ip\n u7BbB0c1A7e9DLIA/+QdRcExe/dg1xru0HINGmczwM3LfSNql9/XIy5O1Cf5CeKhG0NWV4vdePh\n 98IW2cJ6lBFg9CM3ovmCMoWbLyuR9qWNK9gSP1wkO+jeRMgYgmIM6nXz/RqsmsJq9VnX0KP1d7G\n xd/q4ls52+LNoQJK87QNqKs","X-Received":"by 2002:a05:6a20:2451:b0:39f:461f:be7e with SMTP id\n adf61e73a8af0-3a08d8fe55bmr5099374637.44.1776470470328;\n Fri, 17 Apr 2026 17:01:10 -0700 (PDT)","Message-ID":"<59793b74-2ecb-442b-ba67-41d90492b4f5@linaro.org>","Date":"Sat, 18 Apr 2026 10:01:03 +1000","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH 02/14] target/riscv: rvp: add arithmetic instructions,\n including saturating and non-saturating operations","To":"qemu-devel@nongnu.org","References":"<20260417104652.17857-1-xiaoou@iscas.ac.cn>\n <20260417104652.17857-3-xiaoou@iscas.ac.cn>","From":"Richard Henderson <richard.henderson@linaro.org>","Content-Language":"en-US","In-Reply-To":"<20260417104652.17857-3-xiaoou@iscas.ac.cn>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","Received-SPF":"pass client-ip=2607:f8b0:4864:20::102b;\n envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102b.google.com","X-Spam_score_int":"-20","X-Spam_score":"-2.1","X-Spam_bar":"--","X-Spam_report":"(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,\n 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"}},{"id":3680590,"web_url":"http://patchwork.ozlabs.org/comment/3680590/","msgid":"<87b09e01-c988-4b7f-ad38-7a5196992bd2@oss.qualcomm.com>","list_archive_url":null,"date":"2026-04-22T12:24:48","subject":"Re: [PATCH 02/14] target/riscv: rvp: add arithmetic\n instructions,including saturating and non-saturating operations","submitter":{"id":92288,"url":"http://patchwork.ozlabs.org/api/people/92288/","name":"Daniel Henrique Barboza","email":"daniel.barboza@oss.qualcomm.com"},"content":"On 4/17/2026 7:46 AM, Molly Chen wrote:\n> Signed-off-by: Molly Chen <xiaoou@iscas.ac.cn>\n> ---\n>   target/riscv/helper.h                   |   40 +\n>   target/riscv/insn32.decode              |   65 ++\n>   target/riscv/insn_trans/trans_rvp.c.inc |  564 ++++++++++++\n>   target/riscv/meson.build                |    3 +-\n>   target/riscv/psimd_helper.c             | 1069 +++++++++++++++++++++++\n>   target/riscv/translate.c                |    1 +\n>   6 files changed, 1741 insertions(+), 1 deletion(-)\n>   create mode 100644 target/riscv/insn_trans/trans_rvp.c.inc\n>   create mode 100644 target/riscv/psimd_helper.c\n> \n> diff --git a/target/riscv/helper.h b/target/riscv/helper.h\n> index 54d2331966..76bc6583fb 100644\n> --- a/target/riscv/helper.h\n> +++ b/target/riscv/helper.h\n> @@ -1351,3 +1351,43 @@ DEF_HELPER_4(vsm4r_vs, void, ptr, ptr, env, i32)\n>   #ifndef CONFIG_USER_ONLY\n>   DEF_HELPER_1(ssamoswap_disabled, void, env)\n>   #endif\n> +\n> +/* Packed SIMD */\n> +DEF_HELPER_3(padd_b, tl, env, tl, tl)\n> +DEF_HELPER_3(padd_h, tl, env, tl, tl)\n> +DEF_HELPER_3(padd_w, i64, env, i64, i64)\n> +DEF_HELPER_3(padd_bs, tl, env, tl, tl)\n> +DEF_HELPER_3(padd_hs, tl, env, tl, tl)\n> +DEF_HELPER_3(padd_ws, i64, env, i64, i64)\n> +DEF_HELPER_3(psub_b, tl, env, tl, tl)\n> +DEF_HELPER_3(psub_h, tl, env, tl, tl)\n> +DEF_HELPER_3(psub_w, i64, env, i64, i64)\n> +DEF_HELPER_3(psh1add_h, tl, env, tl, tl)\n> +DEF_HELPER_3(psh1add_w, i64, env, i64, i64)\n> +DEF_HELPER_3(pssh1sadd_h, tl, env, tl, tl)\n> +DEF_HELPER_3(pssh1sadd_w, i64, env, i64, i64)\n> +DEF_HELPER_3(ssh1sadd, i32, env, i32, i32)\n> +DEF_HELPER_3(psadd_b, tl, env, tl, tl)\n> +DEF_HELPER_3(psadd_h, tl, env, tl, tl)\n> +DEF_HELPER_3(psadd_w, i64, env, i64, i64)\n> +DEF_HELPER_3(psaddu_b, tl, env, tl, tl)\n> +DEF_HELPER_3(psaddu_h, tl, env, tl, tl)\n> +DEF_HELPER_3(psaddu_w, i64, env, i64, i64)\n> +DEF_HELPER_3(sadd, i32, env, i32, i32)\n> +DEF_HELPER_3(saddu, i32, env, i32, i32)\n> +DEF_HELPER_3(pssub_b, tl, env, tl, tl)\n> +DEF_HELPER_3(pssub_h, tl, env, tl, tl)\n> +DEF_HELPER_3(pssub_w, i64, env, i64, i64)\n> +DEF_HELPER_3(pssubu_b, tl, env, tl, tl)\n> +DEF_HELPER_3(pssubu_h, tl, env, tl, tl)\n> +DEF_HELPER_3(pssubu_w, i64, env, i64, i64)\n> +DEF_HELPER_3(ssub, i32, env, i32, i32)\n> +DEF_HELPER_3(ssubu, i32, env, i32, i32)\n> +DEF_HELPER_3(psati_h, tl, env, tl, tl)\n> +DEF_HELPER_3(pusati_h, tl, env, tl, tl)\n> +DEF_HELPER_3(psati_w, i64, env, i64, i64)\n> +DEF_HELPER_3(pusati_w, i64, env, i64, i64)\n> +DEF_HELPER_3(sati_32, i32, env, i32, i32)\n> +DEF_HELPER_3(usati_32, i32, env, i32, i32)\n> +DEF_HELPER_3(sati_64, i64, env, i64, i64)\n> +DEF_HELPER_3(usati_64, i64, env, i64, i64)\n> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode\n> index 6e35c4b1e6..6043eb39cf 100644\n> --- a/target/riscv/insn32.decode\n> +++ b/target/riscv/insn32.decode\n> @@ -40,6 +40,9 @@\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_ui16 20:4\n> +%imm_p_ui32 20:5\n> +%imm_p_ui64 20:6\n>   \n>   # Argument sets:\n>   &empty\n> @@ -105,6 +108,10 @@\n>   @mop5 . . .. .. .... .. ..... ... ..... ....... &mop5 imm=%imm_mop5 %rd %rs1\n>   @mop3 . . .. .. . ..... ..... ... ..... ....... &mop3 imm=%imm_mop3 %rd %rs1 %rs2\n>   \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> +\n>   # Formats 64:\n>   @sh5     .......  ..... .....  ... ..... ....... &shift  shamt=%sh5      %rs1 %rd\n>   \n> @@ -1084,3 +1091,61 @@ sb_aqrl  00111 . . ..... ..... 000 ..... 0101111 @atom_st\n>   sh_aqrl  00111 . . ..... ..... 001 ..... 0101111 @atom_st\n>   sw_aqrl  00111 . . ..... ..... 010 ..... 0101111 @atom_st\n>   sd_aqrl  00111 . . ..... ..... 011 ..... 0101111 @atom_st\n> +\n> +\n> +# *** P Experimental Extension Version v018 ***\n> +# Arithmetic Operations(Non-Saturating and Saturating)\n> +padd_b     1000010 ..... ..... 000 ..... 0111011 @r\n> +padd_h     1000000 ..... ..... 000 ..... 0111011 @r\n> +padd_w     1000001 ..... ..... 000 ..... 0111011 @r\n> +padd_bs    1001110 ..... ..... 010 ..... 0011011 @r\n> +padd_hs    1001100 ..... ..... 010 ..... 0011011 @r\n> +padd_ws    1001101 ..... ..... 010 ..... 0011011 @r\n> +psub_b     1100010 ..... ..... 000 ..... 0111011 @r\n> +psub_h     1100000 ..... ..... 000 ..... 0111011 @r\n> +psub_w     1100001 ..... ..... 000 ..... 0111011 @r\n> +psh1add_h  1010000 ..... ..... 010 ..... 0111011 @r\n> +psh1add_w  1010001 ..... ..... 010 ..... 0111011 @r\n> +pssh1sadd_h   1011000 ..... ..... 010 ..... 0111011 @r\n> +{\n> +  ssh1sadd    1011001 ..... ..... 010 ..... 0111011 @r\n> +  pssh1sadd_w 1011001 ..... ..... 010 ..... 0111011 @r\n> +}\n> +psadd_b    1001010 ..... ..... 000 ..... 0111011 @r\n> +psadd_h    1001000 ..... ..... 000 ..... 0111011 @r\n> +{\n> +  sadd     1001001 ..... ..... 000 ..... 0111011 @r\n> +  psadd_w  1001001 ..... ..... 000 ..... 0111011 @r\n> +}\n> +psaddu_b   1011010 ..... ..... 000 ..... 0111011 @r\n> +psaddu_h   1011000 ..... ..... 000 ..... 0111011 @r\n> +{\n> +  saddu    1011001 ..... ..... 000 ..... 0111011 @r\n> +  psaddu_w 1011001 ..... ..... 000 ..... 0111011 @r\n> +}\n> +pssub_b    1101010 ..... ..... 000 ..... 0111011 @r\n> +pssub_h    1101000 ..... ..... 000 ..... 0111011 @r\n> +{\n> +  ssub     1101001 ..... ..... 000 ..... 0111011 @r\n> +  pssub_w  1101001 ..... ..... 000 ..... 0111011 @r\n> +}\n> +pssubu_b   1111010 ..... ..... 000 ..... 0111011 @r\n> +pssubu_h   1111000 ..... ..... 000 ..... 0111011 @r\n> +{\n> +  ssubu      1111001 ..... ..... 000 ..... 0111011 @r\n> +  pssubu_w   1111001 ..... ..... 000 ..... 0111011 @r\n> +}\n> +psati_h    11100 001.... ..... 100 ..... 0011011 @p_ui16\n> +pusati_h   10100 001.... ..... 100 ..... 0011011 @p_ui16\n> +{\n> +  sati_32    11100 01..... ..... 100 ..... 0011011 @p_ui32\n> +  psati_w      11100 01..... ..... 100 ..... 0011011 @p_ui32\n> +}\n> +{\n> +  usati_32   10100 01..... ..... 100 ..... 0011011 @p_ui32\n> +  pusati_w     10100 01..... ..... 100 ..... 0011011 @p_ui32\n> +}\n> +\n> +sati_64    111001 ...... ..... 100 ..... 0011011 @p_ui64\n> +usati_64   101001 ...... ..... 100 ..... 0011011 @p_ui64\n> +\n> diff --git a/target/riscv/insn_trans/trans_rvp.c.inc b/target/riscv/insn_trans/trans_rvp.c.inc\n> new file mode 100644\n> index 0000000000..6f7246b563\n> --- /dev/null\n> +++ b/target/riscv/insn_trans/trans_rvp.c.inc\n> @@ -0,0 +1,564 @@\n> +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> +/* RISC-V translation routines for the P Standard Extensions. */\n> +/* Copyright (c) 2026 ISRC ISCAS. */\n> +\n> +#define GEN_SIMD_TRANS(NAME)                                \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +   REQUIRE_EXT(ctx, RVP);                                   \\\n> +   TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);              \\\n> +   TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);              \\\n> +   TCGv dest = dest_gpr(ctx, a->rd);                        \\\n> +   gen_helper_##NAME(dest, tcg_env, src1, src2);            \\\n> +   return true;                                             \\\n> +}\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_32(NAME)                             \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a)  \\\n> +{                                                           \\\n> +    REQUIRE_32BIT(ctx);                                     \\\n> +    REQUIRE_EXT(ctx, RVP);                                  \\\n> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);             \\\n> +    TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);             \\\n> +    TCGv dest = dest_gpr(ctx, a->rd);                       \\\n> +    gen_helper_##NAME(dest, tcg_env, src1, src2);           \\\n> +    return true;                                            \\\n> +}\n\nI believe creating trans_rvp.c.inc and psimd_helper.c are definitely\nthe right thing to do, so that's nice.  We need to reduce code repetition\nas much as possible though, in particular because we're looking at\n11,000 lines to be added.\n\nOne thing we can do is re-use as much code as we can.  For instance,\nI noticed that a lot of 32 bit helpers are basically the same 64 bit\nhelper with a \"REQUIRE_32BIT(ctx);\" that precedes it, like\nGEN_SIMD_TRANS(NAME) and GEN_SIMD_TRANS_32(NAME) from above.\n\nOne thing we can do is (ps: pseudo untested code):\n\n > +#define GEN_SIMD_TRANS(NAME)                                \\\n > +static bool gen_trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n > +{                                                           \\\n > +   REQUIRE_EXT(ctx, RVP);                                   \\\n > +   TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);              \\\n > +   TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);              \\\n > +   TCGv dest = dest_gpr(ctx, a->rd);                        \\\n > +   gen_helper_##NAME(dest, tcg_env, src1, src2);            \\\n > +   return true;                                             \\\n > +}\n > +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n > +{                                                           \\\n > +   return gen_trans_##NAME(ctx, a);                         \\\n > +}\n > +\n > +#if defined(TARGET_RISCV32)\n > +#define GEN_SIMD_TRANS_32(NAME)                             \\\n > +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a)  \\\n > +{                                                           \\\n > +   REQUIRE_32BIT(ctx);                                     \\\n > +   return gen_trans_##NAME(ctx, a);                         \\\n > +}\n\n\nI.e. create a helper that contains the common logic for 32 and 64 bits,\nthen use the 32/64 bit macros to add any specific checks and then call\nthe common helper.\n\nA keen observation here would be \"your version has one less line\nthan the original\", and that's completely true.  But note that the code\nfrom gen_trans_##NAME is used in other translations like GEN_SIMD_TRANS_64\ndown below, so there's more reduction to be made.  There's also a variant\nof that that calls gen_set_gpr() at the end that can be turned into another\nhelper that can re-used in other translations too.\n\n\nThis advice applies to other patches as well.  We want to eliminate code\nrepetition as much as we can - not only because of lines of code but also\nto have fewer points of logic to take care of.\n\n\nThanks,\nDaniel\n\n\n\n\n> +#else\n> +#define GEN_SIMD_TRANS_32(NAME)                             \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a)  \\\n> +{                                                           \\\n> +    REQUIRE_32BIT(ctx);                                     \\\n> +    return true;                                            \\\n> +}\n> +#endif\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_64(NAME)                             \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a)  \\\n> +{                                                           \\\n> +   REQUIRE_64BIT(ctx);                                      \\\n> +   return true;                                             \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_64(NAME)                             \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a)  \\\n> +{                                                           \\\n> +    REQUIRE_64BIT(ctx);                                     \\\n> +    REQUIRE_EXT(ctx, RVP);                                  \\\n> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);             \\\n> +    TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);             \\\n> +    TCGv dest = dest_gpr(ctx, a->rd);                       \\\n> +    gen_helper_##NAME(dest, tcg_env, src1, src2);           \\\n> +    return true;                                            \\\n> +}\n> +#endif\n> +\n> +#define GEN_SIMD_TRANS_ACC(NAME)                            \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_EXT(ctx, RVP);                                  \\\n> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);             \\\n> +    TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);             \\\n> +    TCGv dest = dest_gpr(ctx, a->rd);                       \\\n> +    TCGv t = tcg_temp_new();                                \\\n> +    gen_helper_##NAME(t, tcg_env, src1, src2, dest);        \\\n> +    gen_set_gpr(ctx, a->rd, t);                             \\\n> +    return true;                                            \\\n> +}\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_ACC_32(NAME)                         \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_32BIT(ctx);                                     \\\n> +    REQUIRE_EXT(ctx, RVP);                                  \\\n> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);             \\\n> +    TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);             \\\n> +    TCGv dest = dest_gpr(ctx, a->rd);                       \\\n> +    TCGv t = tcg_temp_new();                                \\\n> +    gen_helper_##NAME(t, tcg_env, src1, src2, dest);        \\\n> +    gen_set_gpr(ctx, a->rd, t);                             \\\n> +    return true;                                            \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_ACC_32(NAME)                         \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_32BIT(ctx);                                     \\\n> +    return true;                                            \\\n> +}\n> +#endif\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_ACC_64(NAME)                         \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_64BIT(ctx);                                     \\\n> +    return true;                                            \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_ACC_64(NAME)                         \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_64BIT(ctx);                                     \\\n> +    REQUIRE_EXT(ctx, RVP);                                  \\\n> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);             \\\n> +    TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);             \\\n> +    TCGv dest = dest_gpr(ctx, a->rd);                       \\\n> +    TCGv t = tcg_temp_new();                                \\\n> +    gen_helper_##NAME(t, tcg_env, src1, src2, dest);        \\\n> +    gen_set_gpr(ctx, a->rd, t);                             \\\n> +    return true;                                            \\\n> +}\n> +#endif\n> +\n> +#define GEN_SIMD_TRANS_R1(NAME)                             \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_EXT(ctx, RVP);                                  \\\n> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);             \\\n> +    TCGv dest = dest_gpr(ctx, a->rd);                       \\\n> +    gen_helper_##NAME(dest, tcg_env, src1);                 \\\n> +    gen_set_gpr(ctx, a->rd, dest);                          \\\n> +    return true;                                            \\\n> +}\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_R1_64(NAME)                          \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_64BIT(ctx);                                     \\\n> +    return true;                                            \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_R1_64(NAME)                          \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_64BIT(ctx);                                     \\\n> +    REQUIRE_EXT(ctx, RVP);                                  \\\n> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);             \\\n> +    TCGv dest = dest_gpr(ctx, a->rd);                       \\\n> +    gen_helper_##NAME(dest, tcg_env, src1);                 \\\n> +    return true;                                            \\\n> +}\n> +#endif\n> +\n> +#define GEN_SIMD_TRANS_IMM(NAME)                            \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_EXT(ctx, RVP);                                  \\\n> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);             \\\n> +    TCGv imm = tcg_constant_tl(a->imm);                     \\\n> +    TCGv dest = dest_gpr(ctx, a->rd);                       \\\n> +    gen_helper_##NAME(dest, tcg_env, src1, imm);            \\\n> +    return true;                                            \\\n> +}\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_IMM_32(NAME)                         \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_32BIT(ctx);                                     \\\n> +    REQUIRE_EXT(ctx, RVP);                                   \\\n> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);             \\\n> +    TCGv imm = tcg_constant_tl(a->imm);                     \\\n> +    TCGv dest = dest_gpr(ctx, a->rd);                       \\\n> +    gen_helper_##NAME(dest, tcg_env, src1, imm);            \\\n> +    return true;                                            \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_IMM_32(NAME)                         \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_32BIT(ctx);                                     \\\n> +    return true;                                            \\\n> +}\n> +#endif\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_IMM_64(NAME)                         \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_64BIT(ctx);                                     \\\n> +    return true;                                            \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_IMM_64(NAME)                         \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_64BIT(ctx);                                     \\\n> +    REQUIRE_EXT(ctx, RVP);                                   \\\n> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);             \\\n> +    TCGv imm = tcg_constant_tl(a->imm);                     \\\n> +    TCGv dest = dest_gpr(ctx, a->rd);                       \\\n> +    gen_helper_##NAME(dest, tcg_env, src1, imm);            \\\n> +    return true;                                            \\\n> +}\n> +#endif\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_REG_PAIR_1(NAME)                     \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_32BIT(ctx);                                     \\\n> +    REQUIRE_EXT(ctx, RVP);                                  \\\n> +    TCGv_i32 src1 = get_gpr(ctx, a->rs1, EXT_NONE);         \\\n> +    TCGv_i32 src2 = get_gpr(ctx, a->rs2, EXT_NONE);         \\\n> +    TCGv_i64 t = tcg_temp_new_i64();                        \\\n> +    gen_helper_##NAME(t, tcg_env, src1, src2);              \\\n> +    set_pair_regs(ctx, (a->rd) * 2, t);                       \\\n> +    return true;                                            \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_REG_PAIR_1(NAME)                     \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_32BIT(ctx);                                     \\\n> +    return true;                                            \\\n> +}\n> +#endif\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_REG_PAIR_2(INSN, HELPER)                \\\n> +static bool trans_##INSN(DisasContext *ctx, arg_##INSN * a)    \\\n> +{                                                              \\\n> +    REQUIRE_32BIT(ctx);                                        \\\n> +    REQUIRE_EXT(ctx, RVP);                                     \\\n> +    TCGv src1_0 = get_gpr(ctx, (a->rs1) * 2, EXT_NONE);          \\\n> +    TCGv src2_0 = get_gpr(ctx, (a->rs2) * 2, EXT_NONE);          \\\n> +    TCGv dest_0 = dest_gpr(ctx, (a->rd) * 2);                    \\\n> +    TCGv src1_1 = get_gpr(ctx, (a->rs1) * 2 + 1, EXT_NONE);        \\\n> +    TCGv src2_1 = get_gpr(ctx, (a->rs2) * 2 + 1, EXT_NONE);        \\\n> +    TCGv dest_1 = dest_gpr(ctx, (a->rd) * 2 + 1);                  \\\n> +    gen_helper_##HELPER(dest_0, tcg_env, src1_0, src2_0);      \\\n> +    gen_helper_##HELPER(dest_1, tcg_env, src1_1, src2_1);      \\\n> +    return true;                                               \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_REG_PAIR_2(INSN, HELPER)                \\\n> +static bool trans_##INSN(DisasContext *ctx, arg_##INSN * a)    \\\n> +{                                                              \\\n> +    REQUIRE_32BIT(ctx);                                        \\\n> +    return true;                                               \\\n> +}\n> +#endif\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_REG_PAIR_3(INSN, HELPER)                \\\n> +static bool trans_##INSN(DisasContext *ctx, arg_##INSN * a)    \\\n> +{                                                              \\\n> +    REQUIRE_EXT(ctx, RVP);                                     \\\n> +    TCGv src1_0 = get_gpr(ctx, (a->rs1) * 2, EXT_NONE);          \\\n> +    TCGv dest_0 = dest_gpr(ctx, (a->rd) * 2);                    \\\n> +    TCGv src1_1 = get_gpr(ctx, (a->rs1) * 2 + 1, EXT_NONE);        \\\n> +    TCGv dest_1 = dest_gpr(ctx, (a->rd) * 2 + 1);                  \\\n> +    TCGv src2   = get_gpr(ctx, a->rs2, EXT_NONE);              \\\n> +    gen_helper_##HELPER(dest_0, tcg_env, src1_0, src2);        \\\n> +    gen_helper_##HELPER(dest_1, tcg_env, src1_1, src2);        \\\n> +    return true;                                               \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_REG_PAIR_3(INSN, HELPER)                \\\n> +static bool trans_##INSN(DisasContext *ctx, arg_##INSN * a)    \\\n> +{                                                              \\\n> +    REQUIRE_32BIT(ctx);                                        \\\n> +    return true;                                               \\\n> +}\n> +#endif\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_REG_PAIR_DW(INSN, HELPER)               \\\n> +static bool trans_##INSN(DisasContext *ctx, arg_##INSN * a)     \\\n> +{                                                              \\\n> +    REQUIRE_32BIT(ctx);                                        \\\n> +    REQUIRE_EXT(ctx, RVP);                                     \\\n> +    TCGv src1_0 = get_gpr(ctx, (a->rs1) * 2, EXT_NONE);          \\\n> +    TCGv src2_0 = get_gpr(ctx, (a->rs2) * 2, EXT_NONE);          \\\n> +    TCGv dest_0 = dest_gpr(ctx, (a->rd) * 2);                    \\\n> +    TCGv src1_1 = get_gpr(ctx, (a->rs1) * 2 + 1, EXT_NONE);        \\\n> +    TCGv src2_1 = get_gpr(ctx, (a->rs2) * 2 + 1, EXT_NONE);        \\\n> +    TCGv dest_1 = dest_gpr(ctx, (a->rd) * 2 + 1);                  \\\n> +    gen_helper_##HELPER(dest_0, tcg_env, src1_0, src2_0);      \\\n> +    gen_helper_##HELPER(dest_1, tcg_env, src1_1, src2_1);      \\\n> +    return true;                                               \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_REG_PAIR_DW(INSN, HELPER)               \\\n> +static bool trans_##INSN(DisasContext *ctx, arg_##INSN * a)     \\\n> +{                                                              \\\n> +    REQUIRE_32BIT(ctx);                                        \\\n> +    return true;                                               \\\n> +}\n> +#endif\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_REG_PAIR_DW_IMM(INSN, HELPER)           \\\n> +static bool trans_##INSN(DisasContext *ctx, arg_##INSN * a)     \\\n> +{                                                              \\\n> +    REQUIRE_32BIT(ctx);                                        \\\n> +    REQUIRE_EXT(ctx, RVP);                                     \\\n> +    TCGv src1_0 = get_gpr(ctx, (a->rs1) * 2, EXT_NONE);          \\\n> +    TCGv imm_0 = tcg_constant_tl(a->imm);                      \\\n> +    TCGv dest_0 = dest_gpr(ctx, (a->rd) * 2);                    \\\n> +    TCGv src1_1 = get_gpr(ctx, (a->rs1) * 2 + 1, EXT_NONE);        \\\n> +    TCGv imm_1 = tcg_constant_tl(a->imm);                      \\\n> +    TCGv dest_1 = dest_gpr(ctx, (a->rd) * 2 + 1);                  \\\n> +    gen_helper_##HELPER(dest_0, tcg_env, src1_0, imm_0);       \\\n> +    gen_helper_##HELPER(dest_1, tcg_env, src1_1, imm_1);       \\\n> +    return true;                                               \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_REG_PAIR_DW_IMM(INSN, HELPER)           \\\n> +static bool trans_##INSN(DisasContext *ctx, arg_##INSN * a)     \\\n> +{                                                              \\\n> +    REQUIRE_32BIT(ctx);                                        \\\n> +    return true;                                               \\\n> +}\n> +#endif\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_REG_PAIR_DW_IMM_2(INSN, HELPER)         \\\n> +static bool trans_##INSN(DisasContext *ctx, arg_##INSN * a)     \\\n> +{                                                              \\\n> +    REQUIRE_32BIT(ctx);                                        \\\n> +    REQUIRE_EXT(ctx, RVP);                                     \\\n> +    TCGv src1_0 = get_gpr(ctx, (a->rs1) * 2, EXT_NONE);          \\\n> +    TCGv imm_0 = tcg_constant_tl(a->imm);                      \\\n> +    TCGv dest_0 = dest_gpr(ctx, (a->rd) * 2);                    \\\n> +    TCGv src1_1 = get_gpr(ctx, (a->rs1) * 2 + 1, EXT_NONE);        \\\n> +    TCGv imm_1 = tcg_constant_tl(a->imm);                      \\\n> +    TCGv dest_1 = dest_gpr(ctx, (a->rd) * 2 + 1);                  \\\n> +    gen_helper_##HELPER##_32(dest_0, tcg_env, src1_0, imm_0);  \\\n> +    gen_helper_##HELPER##_32(dest_1, tcg_env, src1_1, imm_1);  \\\n> +    return true;                                               \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_REG_PAIR_DW_IMM_2(INSN, HELPER)         \\\n> +static bool trans_##INSN(DisasContext *ctx, arg_##INSN * a)     \\\n> +{                                                              \\\n> +    REQUIRE_32BIT(ctx);                                        \\\n> +    return true;                                               \\\n> +}\n> +#endif\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_REG_PAIR_5(INSN, HELPER)                \\\n> +static bool trans_##INSN(DisasContext *ctx, arg_##INSN * a)    \\\n> +{                                                              \\\n> +    REQUIRE_EXT(ctx, RVP);                                     \\\n> +    TCGv src1_0 = get_gpr(ctx, (a->rs1) * 2, EXT_NONE);          \\\n> +    TCGv dest_0 = dest_gpr(ctx, (a->rd) * 2);                    \\\n> +    TCGv src1_1 = get_gpr(ctx, (a->rs1) * 2 + 1, EXT_NONE);        \\\n> +    TCGv dest_1 = dest_gpr(ctx, (a->rd) * 2 + 1);                  \\\n> +    gen_helper_##HELPER(dest_0, tcg_env, src1_0);              \\\n> +    gen_helper_##HELPER(dest_1, tcg_env, src1_1);              \\\n> +    gen_set_gpr(ctx, (a->rd) * 2, dest_0);                       \\\n> +    gen_set_gpr(ctx, (a->rd) * 2 + 1, dest_1);                     \\\n> +    return true;                                               \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_REG_PAIR_5(INSN, HELPER)                \\\n> +static bool trans_##INSN(DisasContext *ctx, arg_##INSN * a)    \\\n> +{                                                              \\\n> +    REQUIRE_32BIT(ctx);                                        \\\n> +    return true;                                               \\\n> +}\n> +#endif\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_REG_PAIR_IMM(NAME)                   \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_32BIT(ctx);                                     \\\n> +    REQUIRE_EXT(ctx, RVP);                                  \\\n> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);             \\\n> +    TCGv_i32 imm = tcg_constant_i32(a->imm);                \\\n> +    TCGv_i64 t = tcg_temp_new_i64();                        \\\n> +    gen_helper_##NAME(t, tcg_env, src1, imm);               \\\n> +    set_pair_regs(ctx, (a->rd) * 2, t);                       \\\n> +    return true;                                            \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_REG_PAIR_IMM(NAME)                   \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_32BIT(ctx);                                     \\\n> +    return true;                                            \\\n> +}\n> +#endif\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_REG_PAIR_IMM_2(INSN, HELPER)          \\\n> +static bool trans_##INSN(DisasContext *ctx, arg_##INSN * a)  \\\n> +{                                                            \\\n> +    REQUIRE_32BIT(ctx);                                      \\\n> +    REQUIRE_EXT(ctx, RVP);                                   \\\n> +    TCGv src1_0 = get_gpr(ctx, (a->rs1) * 2, EXT_NONE);        \\\n> +    TCGv imm_0 = tcg_constant_tl(a->imm);                    \\\n> +    TCGv dest_0 = dest_gpr(ctx, (a->rd) * 2);                  \\\n> +    TCGv src1_1 = get_gpr(ctx, (a->rs1) * 2 + 1, EXT_NONE);      \\\n> +    TCGv imm_1 = tcg_constant_tl(a->imm);                    \\\n> +    TCGv dest_1 = dest_gpr(ctx, (a->rd) * 2 + 1);                \\\n> +    gen_helper_##HELPER(dest_0, tcg_env, src1_0, imm_0);     \\\n> +    gen_helper_##HELPER(dest_1, tcg_env, src1_1, imm_1);     \\\n> +    return true;                                             \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_REG_PAIR_IMM_2(INSN, HELPER)          \\\n> +static bool trans_##INSN(DisasContext *ctx, arg_##INSN * a)  \\\n> +{                                                            \\\n> +    REQUIRE_32BIT(ctx);                                      \\\n> +    return true;                                             \\\n> +}\n> +#endif\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_ACC_REG_PAIR_1(NAME)                 \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_32BIT(ctx);                                     \\\n> +    REQUIRE_EXT(ctx, RVP);                                  \\\n> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);             \\\n> +    TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);             \\\n> +    TCGv_i64 t = tcg_temp_new_i64();                        \\\n> +    if (a->rd == 0) {                                         \\\n> +        tcg_gen_movi_i64(t, 0);                             \\\n> +    } else {                                                  \\\n> +        get_pair_regs(ctx, t, (a->rd) * 2);                   \\\n> +    }                                                       \\\n> +    gen_helper_##NAME(t, tcg_env, src1, src2, t);           \\\n> +    set_pair_regs(ctx, (a->rd) * 2, t);                       \\\n> +    return true;                                            \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_ACC_REG_PAIR_1(NAME)                 \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_32BIT(ctx);                                     \\\n> +    return true;                                            \\\n> +}\n> +#endif\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_REG_PAIR_PREDSUM(NAME)               \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_32BIT(ctx);                                     \\\n> +    REQUIRE_EXT(ctx, RVP);                                  \\\n> +    TCGv_i32 src1_l;                                        \\\n> +    TCGv_i32 src1_h;                                        \\\n> +    TCGv_i32 src2 = get_gpr(ctx, a->rs2, EXT_NONE);         \\\n> +    TCGv_i32 dest = dest_gpr(ctx, a->rd);                   \\\n> +    if (a->rs1 == 0) {                                        \\\n> +        src1_l = tcg_temp_new_i32();                        \\\n> +        src1_h = tcg_temp_new_i32();                        \\\n> +        tcg_gen_movi_i32(src1_l, 0);                        \\\n> +        tcg_gen_movi_i32(src1_h, 0);                        \\\n> +    } else {                                                  \\\n> +        src1_l = get_gpr(ctx, (a->rs1) * 2, EXT_NONE);        \\\n> +        src1_h = get_gpr(ctx, (a->rs1) * 2 + 1, EXT_NONE);      \\\n> +    }                                                       \\\n> +    gen_helper_##NAME(dest, tcg_env, src1_l, src1_h, src2); \\\n> +    return true;                                            \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_REG_PAIR_PREDSUM(NAME)               \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                           \\\n> +    REQUIRE_32BIT(ctx);                                     \\\n> +    return true;                                            \\\n> +}\n> +#endif\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_PN_OP_IMM(NAME)                     \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                          \\\n> +    REQUIRE_32BIT(ctx);                                    \\\n> +    REQUIRE_EXT(ctx, RVP);                                 \\\n> +    TCGv_i64 s1 = tcg_temp_new_i64();                      \\\n> +    if (a->rs1 == 0) {                                     \\\n> +        tcg_gen_mov_i64(s1, 0);                            \\\n> +    } else {                                               \\\n> +        get_pair_regs(ctx, s1, a->rs1 * 2);                \\\n> +    }                                                      \\\n> +    TCGv shamt = tcg_constant_tl(a->imm);                  \\\n> +    TCGv_i32 dest = dest_gpr(ctx, a->rd);                  \\\n> +    gen_helper_##NAME(dest, tcg_env, s1, shamt);           \\\n> +    return true;                                           \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_PN_OP_IMM(NAME)                     \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                          \\\n> +    REQUIRE_32BIT(ctx);                                    \\\n> +    return true;                                           \\\n> +}\n> +#endif\n> +\n> +#if defined(TARGET_RISCV32)\n> +#define GEN_SIMD_TRANS_PN_OP_REG(NAME)                     \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                          \\\n> +    REQUIRE_32BIT(ctx);                                    \\\n> +    REQUIRE_EXT(ctx, RVP);                                 \\\n> +    TCGv_i64 s1 = tcg_temp_new_i64();                      \\\n> +    if (a->rs1 == 0) {                                     \\\n> +        tcg_gen_mov_i64(s1, 0);                            \\\n> +    } else {                                               \\\n> +        get_pair_regs(ctx, s1, a->rs1 * 2);                \\\n> +    }                                                      \\\n> +    TCGv_i32 rs2 = get_gpr(ctx, a->rs2, EXT_NONE);         \\\n> +    TCGv_i32 dest = dest_gpr(ctx, a->rd);                  \\\n> +    gen_helper_##NAME(dest, tcg_env, s1, rs2);             \\\n> +    return true;                                           \\\n> +}\n> +#else\n> +#define GEN_SIMD_TRANS_PN_OP_REG(NAME)                     \\\n> +static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \\\n> +{                                                          \\\n> +    REQUIRE_32BIT(ctx);                                    \\\n> +    return true;                                           \\\n> +}\n> +#endif\n> +\n> +GEN_SIMD_TRANS(padd_b)\n> +GEN_SIMD_TRANS(padd_h)\n> +GEN_SIMD_TRANS_64(padd_w)\n> +GEN_SIMD_TRANS(padd_bs)\n> +GEN_SIMD_TRANS(padd_hs)\n> +GEN_SIMD_TRANS_64(padd_ws)\n> +GEN_SIMD_TRANS(psub_b)\n> +GEN_SIMD_TRANS(psub_h)\n> +GEN_SIMD_TRANS_64(psub_w)\n> +GEN_SIMD_TRANS(psh1add_h)\n> +GEN_SIMD_TRANS_64(psh1add_w)\n> +GEN_SIMD_TRANS(pssh1sadd_h)\n> +GEN_SIMD_TRANS_64(pssh1sadd_w)\n> +GEN_SIMD_TRANS_32(ssh1sadd)\n> +GEN_SIMD_TRANS(psadd_b)\n> +GEN_SIMD_TRANS(psadd_h)\n> +GEN_SIMD_TRANS_64(psadd_w)\n> +GEN_SIMD_TRANS(psaddu_b)\n> +GEN_SIMD_TRANS(psaddu_h)\n> +GEN_SIMD_TRANS_64(psaddu_w)\n> +GEN_SIMD_TRANS_32(sadd)\n> +GEN_SIMD_TRANS_32(saddu)\n> +GEN_SIMD_TRANS(pssub_b)\n> +GEN_SIMD_TRANS(pssub_h)\n> +GEN_SIMD_TRANS_64(pssub_w)\n> +GEN_SIMD_TRANS(pssubu_b)\n> +GEN_SIMD_TRANS(pssubu_h)\n> +GEN_SIMD_TRANS_64(pssubu_w)\n> +GEN_SIMD_TRANS_32(ssub)\n> +GEN_SIMD_TRANS_32(ssubu)\n> +GEN_SIMD_TRANS_IMM(psati_h)\n> +GEN_SIMD_TRANS_IMM(pusati_h)\n> +GEN_SIMD_TRANS_IMM_64(psati_w)\n> +GEN_SIMD_TRANS_IMM_64(pusati_w)\n> +GEN_SIMD_TRANS_IMM_32(sati_32)\n> +GEN_SIMD_TRANS_IMM_32(usati_32)\n> +GEN_SIMD_TRANS_IMM_64(sati_64)\n> +GEN_SIMD_TRANS_IMM_64(usati_64)\n> diff --git a/target/riscv/meson.build b/target/riscv/meson.build\n> index 79f36abd63..45ed7f8d8a 100644\n> --- a/target/riscv/meson.build\n> +++ b/target/riscv/meson.build\n> @@ -28,7 +28,8 @@ riscv_ss.add(files(\n>     'm128_helper.c',\n>     'crypto_helper.c',\n>     'zce_helper.c',\n> -  'vcrypto_helper.c'\n> +  'vcrypto_helper.c',\n> +  'psimd_helper.c'\n>   ))\n>   \n>   riscv_system_ss = ss.source_set()\n> diff --git a/target/riscv/psimd_helper.c b/target/riscv/psimd_helper.c\n> new file mode 100644\n> index 0000000000..a754ee3b5e\n> --- /dev/null\n> +++ b/target/riscv/psimd_helper.c\n> @@ -0,0 +1,1069 @@\n> +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> +/* RISC-V Packed SIMD Extension Helpers for QEMU. */\n> +/* Copyright (C) 2026 ISRC ISCAS. */\n> +\n> +#include \"qemu/osdep.h\"\n> +#include \"cpu.h\"\n> +#include \"qemu/host-utils.h\"\n> +#include \"exec/helper-proto.h\"\n> +#include \"fpu/softfloat.h\"\n> +#include \"internals.h\"\n> +\n> +\n> +/* Helper macros */\n> +\n> +/* Element count calculations */\n> +#define ELEMS_B(target) (sizeof(target) * 8 / 8)    /* byte elements count */\n> +#define ELEMS_H(target) (sizeof(target) * 8 / 16)\n> +#define ELEMS_W(target) (sizeof(target) * 8 / 32)   /* word elements count */\n> +\n> +/* Element extraction macros - unsigned to avoid sign extension */\n> +#define EXTRACT8(val, idx)  (((val) >> ((idx) * 8)) & 0xFF)\n> +#define EXTRACT16(val, idx) (((val) >> ((idx) * 16)) & 0xFFFF)\n> +#define EXTRACT32(val, idx) (((val) >> ((idx) * 32)) & 0xFFFFFFFF)\n> +\n> +/* Element insertion macros */\n> +#define INSERT8(val, res, idx) \\\n> +    ((val) | ((target_ulong)(uint8_t)(res) << ((idx) * 8)))\n> +#define INSERT16(val, res, idx) \\\n> +    ((val) | ((target_ulong)(uint16_t)(res) << ((idx) * 16)))\n> +#define INSERT32(val, res, idx) \\\n> +    ((val) | ((target_ulong)(uint32_t)(res) << ((idx) * 32)))\n> +\n> +/* Saturation constants */\n> +static const int8_t   SAT_MAX_B = 127;\n> +static const int8_t   SAT_MIN_B = -128;\n> +static const int16_t  SAT_MAX_H = 32767;\n> +static const int16_t  SAT_MIN_H = -32768;\n> +static const int32_t  SAT_MAX_W = 2147483647;\n> +static const int32_t  SAT_MIN_W = -2147483648LL;\n> +static const uint8_t  USAT_MAX_B = 255;\n> +static const uint16_t USAT_MAX_H = 65535;\n> +static const uint32_t USAT_MAX_W = 4294967295U;\n> +\n> +\n> +/* Saturation helper functions */\n> +\n> +/**\n> + * Signed saturation for 8-bit elements\n> + * Returns saturated value and sets *sat if saturation occurred\n> + */\n> +static inline int8_t signed_saturate_b(int32_t val, int *sat)\n> +{\n> +    if (val > SAT_MAX_B) {\n> +        *sat = 1;\n> +        return SAT_MAX_B;\n> +    }\n> +    if (val < SAT_MIN_B) {\n> +        *sat = 1;\n> +        return SAT_MIN_B;\n> +    }\n> +    return (int8_t)val;\n> +}\n> +\n> +/**\n> + * Signed saturation for 16-bit elements\n> + */\n> +static inline int16_t signed_saturate_h(int32_t val, int *sat)\n> +{\n> +    if (val > SAT_MAX_H) {\n> +        *sat = 1;\n> +        return SAT_MAX_H;\n> +    }\n> +    if (val < SAT_MIN_H) {\n> +        *sat = 1;\n> +        return SAT_MIN_H;\n> +    }\n> +    return (int16_t)val;\n> +}\n> +\n> +/**\n> + * Signed saturation for 32-bit elements\n> + */\n> +static inline int32_t signed_saturate_w(int64_t val, int *sat)\n> +{\n> +    if (val > SAT_MAX_W) {\n> +        *sat = 1;\n> +        return SAT_MAX_W;\n> +    }\n> +    if (val < SAT_MIN_W) {\n> +        *sat = 1;\n> +        return SAT_MIN_W;\n> +    }\n> +    return (int32_t)val;\n> +}\n> +\n> +/**\n> + * Unsigned saturation for 8-bit elements\n> + */\n> +static inline uint8_t unsigned_saturate_b(uint32_t val, int *sat)\n> +{\n> +    if (val > USAT_MAX_B) {\n> +        *sat = 1;\n> +        return USAT_MAX_B;\n> +    }\n> +    return (uint8_t)val;\n> +}\n> +\n> +/**\n> + * Unsigned saturation for 16-bit elements\n> + */\n> +static inline uint16_t unsigned_saturate_h(uint32_t val, int *sat)\n> +{\n> +    if (val > USAT_MAX_H) {\n> +        *sat = 1;\n> +        return USAT_MAX_H;\n> +    }\n> +    return (uint16_t)val;\n> +}\n> +\n> +/**\n> + * Unsigned saturation for 32-bit elements\n> + */\n> +static inline uint32_t unsigned_saturate_w(uint64_t val, int *sat)\n> +{\n> +    if (val > USAT_MAX_W) {\n> +        *sat = 1;\n> +        return USAT_MAX_W;\n> +    }\n> +    return (uint32_t)val;\n> +}\n> +\n> +/* Basic addition operations (non-saturating) */\n> +\n> +/**\n> + * PADD.B - Packed 8-bit addition\n> + * For each byte: rd[i] = rs1[i] + rs2[i] (modular)\n> + */\n> +target_ulong HELPER(padd_b)(CPURISCVState *env,\n> +                          target_ulong rs1, target_ulong rs2)\n> +{\n> +    target_ulong rd = 0;\n> +    int elems = ELEMS_B(rd);\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        uint8_t e1 = EXTRACT8(rs1, i);\n> +        uint8_t e2 = EXTRACT8(rs2, i);\n> +        uint8_t res = e1 + e2;\n> +        rd = INSERT8(rd, res, i);\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PADD.H - Packed 16-bit addition\n> + * For each halfword: rd[i] = rs1[i] + rs2[i] (modular)\n> + */\n> +target_ulong HELPER(padd_h)(CPURISCVState *env,\n> +                          target_ulong rs1, target_ulong rs2)\n> +{\n> +    target_ulong rd = 0;\n> +    int elems = ELEMS_H(rd);\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        uint16_t e1 = EXTRACT16(rs1, i);\n> +        uint16_t e2 = EXTRACT16(rs2, i);\n> +        uint16_t res = e1 + e2;\n> +        rd = INSERT16(rd, res, i);\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PADD.W - Packed 32-bit addition (RV64 only)\n> + * For each word: rd[i] = rs1[i] + rs2[i] (modular)\n> + */\n> +uint64_t HELPER(padd_w)(CPURISCVState *env,\n> +                     uint64_t rs1, uint64_t rs2)\n> +{\n> +    uint64_t rd = 0;\n> +    int elems = 2;  /* 2 words in 64-bit */\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        uint32_t e1 = EXTRACT32(rs1, i);\n> +        uint32_t e2 = EXTRACT32(rs2, i);\n> +        uint32_t res = e1 + e2;\n> +        rd = INSERT32(rd, res, i);\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PADD.BS - Packed 8-bit addition with scalar second operand\n> + * For each byte: rd[i] = rs1[i] + rs2[0] (modular)\n> + */\n> +target_ulong HELPER(padd_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 e2 = EXTRACT8(rs2, 0);  /* Scalar, take least significant byte */\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        uint8_t e1 = EXTRACT8(rs1, i);\n> +        uint8_t res = e1 + e2;\n> +        rd = INSERT8(rd, res, i);\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PADD.HS - Packed 16-bit addition with scalar second operand\n> + * For each halfword: rd[i] = rs1[i] + rs2[0] (modular)\n> + */\n> +target_ulong HELPER(padd_hs)(CPURISCVState *env,\n> +                          target_ulong rs1, target_ulong rs2)\n> +{\n> +    target_ulong rd = 0;\n> +    int elems = ELEMS_H(rd);\n> +    uint16_t e2 = EXTRACT16(rs2, 0);\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        uint16_t e1 = EXTRACT16(rs1, i);\n> +        uint16_t res = e1 + e2;\n> +        rd = INSERT16(rd, res, i);\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PADD.WS - Packed 32-bit addition with scalar second operand (RV64 only)\n> + * For each word: rd[i] = rs1[i] + rs2[0] (modular)\n> + */\n> +uint64_t HELPER(padd_ws)(CPURISCVState *env,\n> +                     uint64_t rs1, uint64_t rs2)\n> +{\n> +    uint64_t rd = 0;\n> +    int elems = 2;\n> +    uint32_t e2 = EXTRACT32(rs2, 0);\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        uint32_t e1 = EXTRACT32(rs1, i);\n> +        uint32_t res = e1 + e2;\n> +        rd = INSERT32(rd, res, i);\n> +    }\n> +    return rd;\n> +}\n> +\n> +\n> +/* Basic subtraction operations (non-saturating) */\n> +\n> +/**\n> + * PSUB.B - Packed 8-bit subtraction\n> + * For each byte: rd[i] = rs1[i] - rs2[i] (modular)\n> + */\n> +target_ulong HELPER(psub_b)(CPURISCVState *env,\n> +                          target_ulong rs1, target_ulong rs2)\n> +{\n> +    target_ulong rd = 0;\n> +    int elems = ELEMS_B(rd);\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        uint8_t e1 = EXTRACT8(rs1, i);\n> +        uint8_t e2 = EXTRACT8(rs2, i);\n> +        uint8_t res = e1 - e2;\n> +        rd = INSERT8(rd, res, i);\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PSUB.H - Packed 16-bit subtraction\n> + * For each halfword: rd[i] = rs1[i] - rs2[i] (modular)\n> + */\n> +target_ulong HELPER(psub_h)(CPURISCVState *env,\n> +                          target_ulong rs1, target_ulong rs2)\n> +{\n> +    target_ulong rd = 0;\n> +    int elems = ELEMS_H(rd);\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        uint16_t e1 = EXTRACT16(rs1, i);\n> +        uint16_t e2 = EXTRACT16(rs2, i);\n> +        uint16_t res = e1 - e2;\n> +        rd = INSERT16(rd, res, i);\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PSUB.W - Packed 32-bit subtraction (RV64 only)\n> + * For each word: rd[i] = rs1[i] - rs2[i] (modular)\n> + */\n> +uint64_t HELPER(psub_w)(CPURISCVState *env,\n> +                     uint64_t rs1, uint64_t rs2)\n> +{\n> +    uint64_t rd = 0;\n> +    int elems = 2;\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        uint32_t e1 = EXTRACT32(rs1, i);\n> +        uint32_t e2 = EXTRACT32(rs2, i);\n> +        uint32_t res = e1 - e2;\n> +        rd = INSERT32(rd, res, i);\n> +    }\n> +    return rd;\n> +}\n> +\n> +/* Shift-left-by-one and add operations */\n> +\n> +/**\n> + * PSH1ADD.H - Shift left by 1 and add (16-bit)\n> + * For each halfword: rd[i] = (rs1[i] << 1) + rs2[i]\n> + */\n> +target_ulong HELPER(psh1add_h)(CPURISCVState *env,\n> +                          target_ulong rs1, target_ulong rs2)\n> +{\n> +    target_ulong rd = 0;\n> +    int elems = ELEMS_H(rd);\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        uint16_t e1 = EXTRACT16(rs1, i);\n> +        uint16_t e2 = EXTRACT16(rs2, i);\n> +        uint16_t res = (e1 << 1) + e2;\n> +        rd = INSERT16(rd, res, i);\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PSH1ADD.W - Shift left by 1 and add (32-bit, RV64 only)\n> + * For each word: rd[i] = (rs1[i] << 1) + rs2[i]\n> + */\n> +uint64_t HELPER(psh1add_w)(CPURISCVState *env,\n> +                     uint64_t rs1, uint64_t rs2)\n> +{\n> +    uint64_t rd = 0;\n> +    int elems = 2;\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        uint32_t e1 = EXTRACT32(rs1, i);\n> +        uint32_t e2 = EXTRACT32(rs2, i);\n> +        uint32_t res = (e1 << 1) + e2;\n> +        rd = INSERT32(rd, res, i);\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PSSH1SADD.H - Saturating shift left by 1 and saturating add (16-bit)\n> + * For each halfword: rd[i] = sat16(sat16(rs1[i] << 1) + rs2[i])\n> + */\n> +target_ulong HELPER(pssh1sadd_h)(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> +\n> +    for (int i = 0; i < elems; i++) {\n> +        int16_t e1 = (int16_t)EXTRACT16(rs1, i);\n> +        int16_t e2 = (int16_t)EXTRACT16(rs2, i);\n> +        int32_t shifted;\n> +\n> +        /* Check if shift-left-1 would overflow */\n> +        if (e1 > 0x3FFF || e1 < -0x4000) {\n> +            shifted = (e1 < 0) ? 0xFFFF8000LL : 0x7FFF;\n> +            sat = 1;\n> +        } else {\n> +            shifted = e1 << 1;\n> +        }\n> +\n> +        int32_t sum = shifted + e2;\n> +        int16_t res = signed_saturate_h(sum, &sat);\n> +        rd = INSERT16(rd, res, i);\n> +    }\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PSSH1SADD.W - Saturating shift left by 1 and add\n> + * with saturation (32-bit, RV64 only)\n> + * For each word: rd[i] = sat32(sat32(rs1[i] << 1) + rs2[i])\n> + */\n> +uint64_t HELPER(pssh1sadd_w)(CPURISCVState *env,\n> +                     uint64_t rs1, uint64_t rs2)\n> +{\n> +    uint64_t rd = 0;\n> +    int elems = 2;\n> +    int sat = 0;\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        int32_t e1 = (int32_t)EXTRACT32(rs1, i);\n> +        int32_t e2 = (int32_t)EXTRACT32(rs2, i);\n> +        int64_t shifted;\n> +\n> +        /* Check if shift-left-1 would overflow */\n> +        if (e1 > 0x3FFFFFFF || e1 < -0x40000000) {\n> +            shifted = (e1 < 0) ? 0xFFFFFFFF80000000LL : 0x7FFFFFFF;\n> +            sat = 1;\n> +        } else {\n> +            shifted = (int64_t)e1 << 1;\n> +        }\n> +\n> +        int64_t sum = shifted + e2;\n> +        int32_t res = signed_saturate_w(sum, &sat);\n> +        rd = INSERT32(rd, res, i);\n> +    }\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * SSH1SADD - 32-bit scalar saturating shift left by 1 and saturating add\n> + */\n> +uint32_t HELPER(ssh1sadd)(CPURISCVState *env,\n> +                     uint32_t rs1, uint32_t rs2)\n> +{\n> +    int32_t a = (int32_t)rs1;\n> +    int32_t b = (int32_t)rs2;\n> +    int64_t shifted;\n> +    int sat = 0;\n> +\n> +    /* Check if shift-left-1 would overflow */\n> +    if (a > 0x3FFFFFFF || a < -0x40000000) {\n> +        shifted = (a < 0) ? 0xFFFFFFFF80000000LL : 0x7FFFFFFF;\n> +        sat = 1;\n> +    } else {\n> +        shifted = (int64_t)a << 1;\n> +    }\n> +\n> +    int64_t sum = shifted + b;\n> +    int32_t res = signed_saturate_w(sum, &sat);\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return (uint32_t)res;\n> +}\n> +\n> +/* Saturating addition operations */\n> +\n> +/**\n> + * PSADD.B - Packed 8-bit signed saturating addition\n> + * For each byte: rd[i] = sat8(rs1[i] + rs2[i])\n> + */\n> +target_ulong HELPER(psadd_b)(CPURISCVState *env,\n> +                          target_ulong rs1, target_ulong rs2)\n> +{\n> +    target_ulong rd = 0;\n> +    int elems = ELEMS_B(rd);\n> +    int sat = 0;\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        int8_t e1 = (int8_t)EXTRACT8(rs1, i);\n> +        int8_t e2 = (int8_t)EXTRACT8(rs2, i);\n> +        int32_t sum = (int32_t)e1 + (int32_t)e2;\n> +        int8_t res = signed_saturate_b(sum, &sat);\n> +        rd = INSERT8(rd, res, i);\n> +    }\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PSADD.H - Packed 16-bit signed saturating addition\n> + * For each halfword: rd[i] = sat16(rs1[i] + rs2[i])\n> + */\n> +target_ulong HELPER(psadd_h)(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> +\n> +    for (int i = 0; i < elems; i++) {\n> +        int16_t e1 = (int16_t)EXTRACT16(rs1, i);\n> +        int16_t e2 = (int16_t)EXTRACT16(rs2, i);\n> +        int32_t sum = (int32_t)e1 + (int32_t)e2;\n> +        int16_t res = signed_saturate_h(sum, &sat);\n> +        rd = INSERT16(rd, res, i);\n> +    }\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PSADD.W - Packed 32-bit signed saturating addition (RV64 only)\n> + * For each word: rd[i] = sat32(rs1[i] + rs2[i])\n> + */\n> +uint64_t HELPER(psadd_w)(CPURISCVState *env,\n> +                     uint64_t rs1, uint64_t rs2)\n> +{\n> +    uint64_t rd = 0;\n> +    int elems = 2;\n> +    int sat = 0;\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        int32_t e1 = (int32_t)EXTRACT32(rs1, i);\n> +        int32_t e2 = (int32_t)EXTRACT32(rs2, i);\n> +        int64_t sum = (int64_t)e1 + (int64_t)e2;\n> +        int32_t res = signed_saturate_w(sum, &sat);\n> +        rd = INSERT32(rd, res, i);\n> +    }\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PSADDU.B - Packed 8-bit unsigned saturating addition\n> + * For each byte: rd[i] = usat8(rs1[i] + rs2[i])\n> + */\n> +target_ulong HELPER(psaddu_b)(CPURISCVState *env,\n> +                          target_ulong rs1, target_ulong rs2)\n> +{\n> +    target_ulong rd = 0;\n> +    int elems = ELEMS_B(rd);\n> +    int sat = 0;\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        uint8_t e1 = EXTRACT8(rs1, i);\n> +        uint8_t e2 = EXTRACT8(rs2, i);\n> +        uint32_t sum = (uint32_t)e1 + (uint32_t)e2;\n> +        uint8_t res = unsigned_saturate_b(sum, &sat);\n> +        rd = INSERT8(rd, res, i);\n> +    }\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PSADDU.H - Packed 16-bit unsigned saturating addition\n> + * For each halfword: rd[i] = usat16(rs1[i] + rs2[i])\n> + */\n> +target_ulong HELPER(psaddu_h)(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> +\n> +    for (int i = 0; i < elems; i++) {\n> +        uint16_t e1 = EXTRACT16(rs1, i);\n> +        uint16_t e2 = EXTRACT16(rs2, i);\n> +        uint32_t sum = (uint32_t)e1 + (uint32_t)e2;\n> +        uint16_t res = unsigned_saturate_h(sum, &sat);\n> +        rd = INSERT16(rd, res, i);\n> +    }\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PSADDU.W - Packed 32-bit unsigned saturating addition (RV64 only)\n> + * For each word: rd[i] = usat32(rs1[i] + rs2[i])\n> + */\n> +uint64_t HELPER(psaddu_w)(CPURISCVState *env,\n> +                     uint64_t rs1, uint64_t rs2)\n> +{\n> +    uint64_t rd = 0;\n> +    int elems = 2;\n> +    int sat = 0;\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        uint32_t e1 = EXTRACT32(rs1, i);\n> +        uint32_t e2 = EXTRACT32(rs2, i);\n> +        uint64_t sum = (uint64_t)e1 + (uint64_t)e2;\n> +        uint32_t res = unsigned_saturate_w(sum, &sat);\n> +        rd = INSERT32(rd, res, i);\n> +    }\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * SADD - 32-bit signed saturating addition\n> + */\n> +uint32_t HELPER(sadd)(CPURISCVState *env,\n> +                     uint32_t rs1, uint32_t rs2)\n> +{\n> +    int32_t a = (int32_t)rs1;\n> +    int32_t b = (int32_t)rs2;\n> +    int64_t sum = (int64_t)a + (int64_t)b;\n> +    int sat = 0;\n> +    int32_t res = signed_saturate_w(sum, &sat);\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return (uint32_t)res;\n> +}\n> +\n> +/**\n> + * SADDU - 32-bit unsigned saturating addition\n> + */\n> +uint32_t HELPER(saddu)(CPURISCVState *env,\n> +                     uint32_t rs1, uint32_t rs2)\n> +{\n> +    uint32_t a = rs1;\n> +    uint32_t b = rs2;\n> +    uint64_t sum = (uint64_t)a + (uint64_t)b;\n> +    int sat = 0;\n> +    uint32_t res = unsigned_saturate_w(sum, &sat);\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return res;\n> +}\n> +\n> +/* Saturating subtraction operations */\n> +\n> +/**\n> + * PSSUB.B - Packed 8-bit signed saturating subtraction\n> + * For each byte: rd[i] = sat8(rs1[i] - rs2[i])\n> + */\n> +target_ulong HELPER(pssub_b)(CPURISCVState *env,\n> +                          target_ulong rs1, target_ulong rs2)\n> +{\n> +    target_ulong rd = 0;\n> +    int elems = ELEMS_B(rd);\n> +    int sat = 0;\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        int8_t e1 = (int8_t)EXTRACT8(rs1, i);\n> +        int8_t e2 = (int8_t)EXTRACT8(rs2, i);\n> +        int32_t diff = (int32_t)e1 - (int32_t)e2;\n> +        int8_t res = signed_saturate_b(diff, &sat);\n> +        rd = INSERT8(rd, res, i);\n> +    }\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PSSUB.H - Packed 16-bit signed saturating subtraction\n> + * For each halfword: rd[i] = sat16(rs1[i] - rs2[i])\n> + */\n> +target_ulong HELPER(pssub_h)(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> +\n> +    for (int i = 0; i < elems; i++) {\n> +        int16_t e1 = (int16_t)EXTRACT16(rs1, i);\n> +        int16_t e2 = (int16_t)EXTRACT16(rs2, i);\n> +        int32_t diff = (int32_t)e1 - (int32_t)e2;\n> +        int16_t res = signed_saturate_h(diff, &sat);\n> +        rd = INSERT16(rd, res, i);\n> +    }\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PSSUB.W - Packed 32-bit signed saturating subtraction (RV64 only)\n> + * For each word: rd[i] = sat32(rs1[i] - rs2[i])\n> + */\n> +uint64_t HELPER(pssub_w)(CPURISCVState *env,\n> +                     uint64_t rs1, uint64_t rs2)\n> +{\n> +    uint64_t rd = 0;\n> +    int elems = 2;\n> +    int sat = 0;\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        int32_t e1 = (int32_t)EXTRACT32(rs1, i);\n> +        int32_t e2 = (int32_t)EXTRACT32(rs2, i);\n> +        int64_t diff = (int64_t)e1 - (int64_t)e2;\n> +        int32_t res = signed_saturate_w(diff, &sat);\n> +        rd = INSERT32(rd, res, i);\n> +    }\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PSSUBU.B - Packed 8-bit unsigned saturating subtraction\n> + * For each byte: rd[i] = usat8(rs1[i] - rs2[i])\n> + */\n> +target_ulong HELPER(pssubu_b)(CPURISCVState *env,\n> +                          target_ulong rs1, target_ulong rs2)\n> +{\n> +    target_ulong rd = 0;\n> +    int elems = ELEMS_B(rd);\n> +    int sat = 0;\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        uint8_t e1 = EXTRACT8(rs1, i);\n> +        uint8_t e2 = EXTRACT8(rs2, i);\n> +        uint32_t diff = e1 - e2;  /* Unsigned subtraction may underflow */\n> +        uint8_t res = unsigned_saturate_b(diff, &sat);\n> +        rd = INSERT8(rd, res, i);\n> +    }\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PSSUBU.H - Packed 16-bit unsigned saturating subtraction\n> + * For each halfword: rd[i] = usat16(rs1[i] - rs2[i])\n> + */\n> +target_ulong HELPER(pssubu_h)(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> +\n> +    for (int i = 0; i < elems; i++) {\n> +        uint16_t e1 = EXTRACT16(rs1, i);\n> +        uint16_t e2 = EXTRACT16(rs2, i);\n> +        uint32_t diff = e1 - e2;\n> +        uint16_t res = unsigned_saturate_h(diff, &sat);\n> +        rd = INSERT16(rd, res, i);\n> +    }\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * PSSUBU.W - Packed 32-bit unsigned saturating subtraction (RV64 only)\n> + * For each word: rd[i] = usat32(rs1[i] - rs2[i])\n> + */\n> +uint64_t HELPER(pssubu_w)(CPURISCVState *env,\n> +                     uint64_t rs1, uint64_t rs2)\n> +{\n> +    uint64_t rd = 0;\n> +    int elems = 2;\n> +    int sat = 0;\n> +\n> +    for (int i = 0; i < elems; i++) {\n> +        uint32_t e1 = EXTRACT32(rs1, i);\n> +        uint32_t e2 = EXTRACT32(rs2, i);\n> +        uint32_t res = (e1 >= e2) ? (e1 - e2) : 0;\n> +        if (e1 < e2) {\n> +            sat = 1;\n> +        }\n> +        rd = INSERT32(rd, res, i);\n> +    }\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return rd;\n> +}\n> +\n> +/**\n> + * SSUB - 32-bit signed saturating subtraction\n> + */\n> +uint32_t HELPER(ssub)(CPURISCVState *env,\n> +                     uint32_t rs1, uint32_t rs2)\n> +{\n> +    int32_t a = (int32_t)rs1;\n> +    int32_t b = (int32_t)rs2;\n> +    int64_t diff = (int64_t)a - (int64_t)b;\n> +    int sat = 0;\n> +    int32_t res = signed_saturate_w(diff, &sat);\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return (uint32_t)res;\n> +}\n> +\n> +/**\n> + * SSUBU - 32-bit unsigned saturating subtraction\n> + */\n> +uint32_t HELPER(ssubu)(CPURISCVState *env,\n> +                     uint32_t rs1, uint32_t rs2)\n> +{\n> +    uint32_t a = rs1;\n> +    uint32_t b = rs2;\n> +    uint64_t diff = (uint64_t)a - (uint64_t)b;\n> +    int sat = 0;\n> +    uint32_t res = unsigned_saturate_w(diff, &sat);\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return res;\n> +}\n> +\n> +/* Saturation instructions (SAT, USAT) */\n> +\n> +/**\n> + * PSATI.H - Packed 16-bit signed saturate to immediate bit-width\n> + * For each halfword: rd[i] = sat(rs1[i], imm+1 bits)\n> + */\n> +target_ulong HELPER(psati_h)(CPURISCVState *env,\n> +                          target_ulong rs1, target_ulong imm)\n> +{\n> +    target_ulong rd = 0;\n> +    int elems = ELEMS_H(rd);\n> +    int range = (imm & 0x0F) + 1;  /* imm specifies bits-1 */\n> +    int64_t max = (1LL << (range - 1)) - 1;\n> +    int64_t min = -(1LL << (range - 1));\n> +    int sat = 0;\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 (e1 > max) {\n> +            res = max;\n> +            sat = 1;\n> +        } else if (e1 < min) {\n> +            res = min;\n> +            sat = 1;\n> +        } else {\n> +            res = e1;\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> + * PUSATI.H - Packed 16-bit unsigned saturate to immediate bit-width\n> + * For each halfword: rd[i] = usat(rs1[i], imm bits)\n> + */\n> +target_ulong HELPER(pusati_h)(CPURISCVState *env,\n> +                          target_ulong rs1, target_ulong imm)\n> +{\n> +    target_ulong rd = 0;\n> +    int elems = ELEMS_H(rd);\n> +    uint32_t max = (1U << imm) - 1;\n> +    int sat = 0;\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 (e1 < 0) {\n> +            res = 0;\n> +            sat = 1;\n> +        } else if ((uint16_t)e1 > max) {\n> +            res = max;\n> +            sat = 1;\n> +        } else {\n> +            res = e1;\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> + * PSATI.W - Packed 32-bit signed saturate to immediate bit-width (RV64 only)\n> + * For each word: rd[i] = sat(rs1[i], imm+1 bits)\n> + */\n> +uint64_t HELPER(psati_w)(CPURISCVState *env,\n> +                     uint64_t rs1, uint64_t imm)\n> +{\n> +    uint64_t rd = 0;\n> +    int elems = 2;\n> +    int range = (imm & 0x1F) + 1;\n> +    int64_t max = (1LL << (range - 1)) - 1;\n> +    int64_t min = -(1LL << (range - 1));\n> +    int sat = 0;\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 (e1 > max) {\n> +            res = max;\n> +            sat = 1;\n> +        } else if (e1 < min) {\n> +            res = min;\n> +            sat = 1;\n> +        } else {\n> +            res = e1;\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> + * PUSATI.W - Packed 32-bit unsigned saturate to immediate bit-width (RV64 only)\n> + * For each word: rd[i] = usat(rs1[i], imm bits)\n> + */\n> +uint64_t HELPER(pusati_w)(CPURISCVState *env,\n> +                     uint64_t rs1, uint64_t imm)\n> +{\n> +    uint64_t rd = 0;\n> +    int elems = 2;\n> +    uint64_t max = (1ULL << imm) - 1;\n> +    int sat = 0;\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 (e1 < 0) {\n> +            res = 0;\n> +            sat = 1;\n> +        } else if ((uint32_t)e1 > max) {\n> +            res = max;\n> +            sat = 1;\n> +        } else {\n> +            res = e1;\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> + * SATI_32 - 32-bit scalar signed saturation with immediate range\n> + */\n> +uint32_t HELPER(sati_32)(CPURISCVState *env,\n> +                         uint32_t rs1, uint32_t imm)\n> +{\n> +    int32_t a = (int32_t)rs1;\n> +    int range = (imm & 0x1F) + 1;  /* imm specifies bits-1 */\n> +    int64_t max = (1LL << (range - 1)) - 1;\n> +    int64_t min = -(1LL << (range - 1));\n> +    int sat = 0;\n> +\n> +    if (a > max) {\n> +        a = max;\n> +        sat = 1;\n> +    } else if (a < min) {\n> +        a = min;\n> +        sat = 1;\n> +    }\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return (uint32_t)a;\n> +}\n> +\n> +/**\n> + * USATI_32 - 32-bit scalar unsigned saturation with immediate range\n> + */\n> +uint32_t HELPER(usati_32)(CPURISCVState *env,\n> +                          uint32_t rs1, uint32_t imm)\n> +{\n> +    int32_t a = (int32_t)rs1;\n> +    uint32_t max = (1U << imm) - 1;\n> +    int sat = 0;\n> +\n> +    if (a < 0) {\n> +        a = 0;\n> +        sat = 1;\n> +    } else if ((uint32_t)a > max) {\n> +        a = max;\n> +        sat = 1;\n> +    }\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return (uint32_t)a;\n> +}\n> +\n> +/**\n> + * SATI_64 - 64-bit scalar signed saturation with immediate range\n> + */\n> +uint64_t HELPER(sati_64)(CPURISCVState *env,\n> +                     uint64_t rs1, uint64_t imm)\n> +{\n> +    int64_t a = (int64_t)rs1;\n> +    int range = (imm & 0x3F) + 1;\n> +    int64_t max = (1LL << (range - 1)) - 1;\n> +    int64_t min = -(1LL << (range - 1));\n> +    int sat = 0;\n> +\n> +    if (a > max) {\n> +        a = max;\n> +        sat = 1;\n> +    } else if (a < min) {\n> +        a = min;\n> +        sat = 1;\n> +    }\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return (uint64_t)a;\n> +}\n> +\n> +/**\n> + * USATI_64 - 64-bit scalar unsigned saturation with immediate range\n> + */\n> +uint64_t HELPER(usati_64)(CPURISCVState *env,\n> +                     uint64_t rs1, uint64_t imm)\n> +{\n> +    int64_t a = (int64_t)rs1;\n> +    uint64_t max = (1ULL << imm) - 1;\n> +    int sat = 0;\n> +\n> +    if (a < 0) {\n> +        a = 0;\n> +        sat = 1;\n> +    } else if ((uint64_t)a > max) {\n> +        a = max;\n> +        sat = 1;\n> +    }\n> +\n> +    if (sat) {\n> +        env->vxsat = 1;\n> +    }\n> +    return (uint64_t)a;\n> +}\n> diff --git a/target/riscv/translate.c b/target/riscv/translate.c\n> index 81087e0a5d..de3ec7a7ec 100644\n> --- a/target/riscv/translate.c\n> +++ b/target/riscv/translate.c\n> @@ -1206,6 +1206,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)\n>   #include \"insn_trans/trans_rvh.c.inc\"\n>   #include \"insn_trans/trans_rvv.c.inc\"\n>   #include \"insn_trans/trans_rvb.c.inc\"\n> +#include \"insn_trans/trans_rvp.c.inc\"\n>   #include \"insn_trans/trans_rvzicond.c.inc\"\n>   #include \"insn_trans/trans_rvzacas.c.inc\"\n>   #include \"insn_trans/trans_rvzabha.c.inc\"","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\tdkim=pass (2048-bit key;\n unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.a=rsa-sha256\n header.s=qcppdkim1 header.b=L7QPTp5j;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com\n header.a=rsa-sha256 header.s=google header.b=EzYrfIf2;\n\tdkim-atps=neutral","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 4g0z2s5bD1z1yCv\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 22:25:41 +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 1wFWdc-00064n-Ei; Wed, 22 Apr 2026 08:25:04 -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 <daniel.barboza@oss.qualcomm.com>)\n id 1wFWda-00063v-8Z\n for qemu-devel@nongnu.org; Wed, 22 Apr 2026 08:25:02 -0400","from mx0a-0031df01.pphosted.com ([205.220.168.131])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <daniel.barboza@oss.qualcomm.com>)\n id 1wFWdV-0006Jw-8U\n for qemu-devel@nongnu.org; Wed, 22 Apr 2026 08:25:01 -0400","from pps.filterd (m0279864.ppops.net [127.0.0.1])\n by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id\n 63M96HtJ664335\n for <qemu-devel@nongnu.org>; Wed, 22 Apr 2026 12:24:55 GMT","from mail-qv1-f70.google.com (mail-qv1-f70.google.com\n [209.85.219.70])\n by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4dpudgrp2s-1\n (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT)\n for <qemu-devel@nongnu.org>; Wed, 22 Apr 2026 12:24:55 +0000 (GMT)","by mail-qv1-f70.google.com with SMTP id\n 6a1803df08f44-8acafc224a8so138970876d6.1\n for <qemu-devel@nongnu.org>; Wed, 22 Apr 2026 05:24:55 -0700 (PDT)","from [192.168.68.106] ([191.202.238.222])\n by smtp.gmail.com with ESMTPSA id\n 6a1803df08f44-8b02ae5c300sm126868356d6.26.2026.04.22.05.24.50\n (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n Wed, 22 Apr 2026 05:24:51 -0700 (PDT)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h=\n cc:content-transfer-encoding:content-type:date:from:in-reply-to\n :message-id:mime-version:references:subject:to; s=qcppdkim1; bh=\n piRCtZDP4qbAcGfqKfENd0GvCArolimiylnVVvBDQoc=; b=L7QPTp5jkUmEvXMf\n XbqOHqI+SGmW5Hl8tiM19yAEPlXgjbZTViKRJrmbSnLO1RZEutEB/eFVpZlCaAlC\n X6aMWqjKlpOkHshkPXHYiJyXDfdl407LY4igLrBxfhHKD7podTgmsVUi9QJ7NkTO\n YaUzhsS2RY+ciD2a3baOsLB7Xvryy2NlGgieg0uBuqx4oXLoVZ9zFKYTgL7gEDd7\n LHCXZzhSdbhzn3QFirXgvkFyj0rM66kJjiTHvX80t82i1ZeSBL09fvHCm4HMG8kb\n hEDbenXBZ6SfZGr+HENun4gX8lxy8ieq55PZqfmiaECoU/7IM6XSRMxXFlm4KRgG\n Om/23w==","v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=oss.qualcomm.com; s=google; t=1776860694; x=1777465494; darn=nongnu.org;\n h=content-transfer-encoding:in-reply-to:content-language:from\n :references:cc:to:subject:user-agent:mime-version:date:message-id\n :from:to:cc:subject:date:message-id:reply-to;\n bh=piRCtZDP4qbAcGfqKfENd0GvCArolimiylnVVvBDQoc=;\n b=EzYrfIf2mdha1eaQi/Mw17C0zo8b6loZrzQf0APr/zs6OGWwJSx6RpRb66n5IMS+fg\n zbDWB5I2UBi3UqYKtW82s817MciT7zbENiJPjp1iTbkIrJMqoNTk7SOBf8QrWzMg64mE\n ai/Md3XTFY7+XJMNIzUu6Dzg96aN01q7ndfysvEwjs8a6h8DbR2p93x7fXAq6JR3LXcr\n 6VYjpEhnTumUkLYndLwMIR1iBQvs2mhGgwqojyj7nFF1rEpuTFFeGWR7kiSkmYOxkVs2\n fpFqGCaD7BtauSomQxVEL0gi9sPubkctnS2Gtr7lm0cRgWeTLh4g6zgwilToLKBJslmj\n 0Rfg=="],"X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776860694; x=1777465494;\n h=content-transfer-encoding:in-reply-to:content-language:from\n :references:cc:to:subject:user-agent:mime-version:date:message-id\n :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id\n :reply-to;\n bh=piRCtZDP4qbAcGfqKfENd0GvCArolimiylnVVvBDQoc=;\n b=CtvjX3S7HN876ssRe3CTkC7g7nyWKw2eJoEJ38S/oh+lsxXeiUWEwil4XTn7tR44EW\n ZbiZc1k3zTUtFxGzu4CXac7BJwWBj8nzpxubm4D71vdTlKFTtUrS6WQinBfDfVyl6fr7\n JP/WyALmbWKJal7L3tswjFX7GPrCCQ4jkfSnE5/eN1K4ZEq3qFxLRG+Fke6CpWMNwjKJ\n IKgnCKiIecS1vc1PwM+bMf5ujWKEmdCJiQBr3GvngLkkV5XN5Xzo8Q4t+Qj6MD12hp8g\n oZA5SyiiVip3EIA4yFB5WFk92J0K6oqyaTE6aOLXBXktGez3DDz/O3haE+SSfIwK6xmi\n a/iQ==","X-Forwarded-Encrypted":"i=1;\n AFNElJ9hIw+kSrIJeaQe6AmM573N+EU+hx8oBfQefGeLi2XRKtvVcSW0aXsz2/MrBv3/2mUTSJGLkXEgAmVT@nongnu.org","X-Gm-Message-State":"AOJu0YyRYxMJ+2ZMPJn6lLO/Q0wcQJSlnKVAEdaizOl3lwyqx3+egSbO\n 0DOyBE7CvG5h8vtZm0iiRY/yxq3cdA40FfYl1KAw0OfilMs6Jrd+3ABJo1zXaLYfRXGLoYQ+vSm\n YeP+AQbS/xI9D/ZA2OTJeeRhGOXxH4jHUhVyob/YHvBsUDnq3TNWzdXc9xA==","X-Gm-Gg":"AeBDietnXSreSz3RF0G3wCjzdLmEszHQNZL2ymlI6D9W67fxaOyCSSDXEEs4Du6913C\n v5CM0rq1jtatC+8JkX0QF8HJDwV3IG8fTSJU5iGdAW4494lD1rJSqOQ7dh9z/26WiWpRpP7ccWC\n ITPDPNhq9jr7iroTIlcIsb9YNR2UvMLVeoh3ubmE2fj5Do27UVfmEUcKCHF35BZYmSgIuVY88EY\n p5TND6crCJnszZnw1OzHJ4cUCzoSH+KjZWTd6ARqaj6UKx2OM/ll0/bfZf6+UhBfdzceWldXGsC\n 17VJyQ3P9kPUM9pLROX+41nOxUprhRYzgH6ea3tSgeZUZ/lSw/p9UyNljJeTVv2pCxw3ey04Xcd\n JDALSlbmPVF7f4+uYc/0+joot44xHU5VyjTCgQmkDl6gaREOH42GDF7TKMSbGSF2nnrkC8Q==","X-Received":["by 2002:a05:6214:4a06:b0:8ae:5f0f:cc80 with SMTP id\n 6a1803df08f44-8b02812b2d6mr333483396d6.38.1776860693263;\n Wed, 22 Apr 2026 05:24:53 -0700 (PDT)","by 2002:a05:6214:4a06:b0:8ae:5f0f:cc80 with SMTP id\n 6a1803df08f44-8b02812b2d6mr333482396d6.38.1776860692361;\n Wed, 22 Apr 2026 05:24:52 -0700 (PDT)"],"Message-ID":"<87b09e01-c988-4b7f-ad38-7a5196992bd2@oss.qualcomm.com>","Date":"Wed, 22 Apr 2026 09:24:48 -0300","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH 02/14] target/riscv: rvp: add arithmetic\n instructions,including saturating and non-saturating operations","To":"Molly Chen <xiaoou@iscas.ac.cn>, palmer@dabbelt.com,\n alistair.francis@wdc.com, liwei1518@gmail.com,\n zhiwei_liu@linux.alibaba.com, chao.liu.zevorn@gmail.com","Cc":"qemu-riscv@nongnu.org, qemu-devel@nongnu.org","References":"<20260417104652.17857-1-xiaoou@iscas.ac.cn>\n <20260417104652.17857-3-xiaoou@iscas.ac.cn>","From":"Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>","Content-Language":"en-US","In-Reply-To":"<20260417104652.17857-3-xiaoou@iscas.ac.cn>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","X-Proofpoint-ORIG-GUID":"C2ITZ-CH3FlXyCy6dh8fPC6-GwK26Qmf","X-Authority-Analysis":"v=2.4 cv=c5ibhx9l c=1 sm=1 tr=0 ts=69e8be17 cx=c_pps\n a=oc9J++0uMp73DTRD5QyR2A==:117 a=etEqFfc6qwXwpI8uT8rzbw==:17\n a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10\n a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=DJpcGTmdVt4CTyJn9g5Z:22\n a=-Iy_nziMAAAA:8 a=SD849BU-OWIPLwrtSDcA:9 a=QEXdDO2ut3YA:10\n a=iYH6xdkBrDN1Jqds4HTS:22 a=YglNLBNtcWVit6QT_GIP:22","X-Proofpoint-GUID":"C2ITZ-CH3FlXyCy6dh8fPC6-GwK26Qmf","X-Proofpoint-Spam-Details-Enc":"AW1haW4tMjYwNDIyMDExOSBTYWx0ZWRfX32whZRFaNLKr\n M21ptf9UfRRlTXhh5XtDOHvfnJqKaWhr7QCL8O1W9yQgd4jU6Miu8uhdhyftwH1yStGC/RmKkV1\n cCNf1Uo2/gOhWlGGFp/ROVK2Yzd+aiK7miwu3mh1xrzM1Rv0Azs3Ry/g3y3YvAaOhSIHijg9AZL\n vha8Zstk1EtZe/11uMhwlIH4+31sq3WkQsDXaS3L5P7pNNpkeC3vmudah5LsRV/4+H5XuNLWk98\n /q8CO+BEJDrVMVwmWOtd4gIKlDmD/TCmonXY5N6f4BGilQ6NvT5NYxITaWW8XtT3D8FFXmbVG29\n pF0FH5Ul03NiDjvzJMrKji4rqT7oAafvPXbNnEcWQF1qhn2cZ88SkkrS9k0cG/GpscMgqpyvdXk\n fh8vmy77FT1eeXYNB2bSb51WL2vDF67kRQ2yhBcsvwhAwDFtJnndR9XwnQCt+SvJYsg+ub7MJpN\n ZX0kgQoHoMr6n0feNSg==","X-Proofpoint-Virus-Version":"vendor=baseguard\n engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49\n definitions=2026-04-22_01,2026-04-21_02,2025-10-01_01","X-Proofpoint-Spam-Details":"rule=outbound_notspam policy=outbound score=0\n bulkscore=0 malwarescore=0 spamscore=0 lowpriorityscore=0 suspectscore=0\n adultscore=0 impostorscore=0 phishscore=0 clxscore=1015 priorityscore=1501\n classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0\n reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604220119","Received-SPF":"pass client-ip=205.220.168.131;\n envelope-from=daniel.barboza@oss.qualcomm.com;\n helo=mx0a-0031df01.pphosted.com","X-Spam_score_int":"-27","X-Spam_score":"-2.8","X-Spam_bar":"--","X-Spam_report":"(-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001,\n 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"}}]