From nobody Tue Feb 10 02:28:06 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1568184227; cv=none; d=zoho.com; s=zohoarc; b=nssIeH45AncEJKkzunTrdhKvs+YFexOO/iZfHYgIa9BuKcJ0c52n9noeWyZc3xniB5Obb6Qkz/BOMB0nYv18zYDUIBx1E7rhoz7YVymZltKLezgiVEjG8UT0CVj/G+/VpC4AE8j7wTJSxLYyWMt1j89DL7jM2ziY7iUmEH2/li8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1568184227; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=Q2m3HAeF067sPEMZek0S1qa8uJtfbs/rtIRxn/ZdVn0=; b=Xn1kJfZP7pNWyfFDTTuzRwGzMXErsRnVriUzGlHYQBwSbaRa86CmITr/0PctIRzQbPLvaWqo2mT1CwazpFrv0j/xazWlzKxjtgAtmrRFm1yUi15lC3ZOhKHgDxp80F4bls5zxER3sw+2F2gX0Qjnp0Cd4Plv70pse3i+fbkhYAc= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1568184227711856.2119371198249; Tue, 10 Sep 2019 23:43:47 -0700 (PDT) Received: from localhost ([::1]:46918 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i7wLv-0007w4-Sn for importer@patchew.org; Wed, 11 Sep 2019 02:43:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38407) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i7wDW-0006xh-VH for qemu-devel@nongnu.org; Wed, 11 Sep 2019 02:35:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i7wDT-0007mZ-Rc for qemu-devel@nongnu.org; Wed, 11 Sep 2019 02:35:02 -0400 Received: from smtp2200-217.mail.aliyun.com ([121.197.200.217]:43584) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i7wDT-0007k2-5P; Wed, 11 Sep 2019 02:34:59 -0400 Received: from localhost(mailfrom:zhiwei_liu@c-sky.com fp:SMTPD_---.FSRUTgl_1568183693) by smtp.aliyun-inc.com(10.147.42.22); Wed, 11 Sep 2019 14:34:53 +0800 X-Alimail-AntiSpam: AC=CONTINUE; BC=0.03883426|-1; CH=green; DM=CONTINUE|CONTINUE|true|0.480035-0.00505187-0.514913; FP=0|0|0|0|0|-1|-1|-1; HT=e01a16368; MF=zhiwei_liu@c-sky.com; NM=1; PH=DS; RN=11; RT=11; SR=0; TI=SMTPD_---.FSRUTgl_1568183693; From: liuzhiwei To: Alistair.Francis@wdc.com, palmer@sifive.com, sagark@eecs.berkeley.edu, kbastian@mail.uni-paderborn.de, riku.voipio@iki.fi, laurent@vivier.eu, wenmeng_zhang@c-sky.com Date: Wed, 11 Sep 2019 14:25:30 +0800 Message-Id: <1568183141-67641-7-git-send-email-zhiwei_liu@c-sky.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1568183141-67641-1-git-send-email-zhiwei_liu@c-sky.com> References: <1568183141-67641-1-git-send-email-zhiwei_liu@c-sky.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] X-Received-From: 121.197.200.217 Subject: [Qemu-devel] [PATCH v2 06/17] RISC-V: add vector extension fault-only-first implementation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, qemu-devel@nongnu.org, wxy194768@alibaba-inc.com, LIU Zhiwei Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: LIU Zhiwei Signed-off-by: LIU Zhiwei --- linux-user/riscv/cpu_loop.c | 7 + target/riscv/cpu_helper.c | 7 + target/riscv/helper.h | 7 + target/riscv/insn32.decode | 7 + target/riscv/insn_trans/trans_rvv.inc.c | 7 + target/riscv/vector_helper.c | 567 ++++++++++++++++++++++++++++= ++++ 6 files changed, 602 insertions(+) diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c index 12aa3c0..d673fa5 100644 --- a/linux-user/riscv/cpu_loop.c +++ b/linux-user/riscv/cpu_loop.c @@ -41,6 +41,13 @@ void cpu_loop(CPURISCVState *env) sigcode =3D 0; sigaddr =3D 0; =20 + if (env->foflag) { + if (env->vfp.vl !=3D 0) { + env->foflag =3D false; + env->pc +=3D 4; + continue; + } + } switch (trapnr) { case EXCP_INTERRUPT: /* just indicate that signals should be handled asap */ diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index e32b612..405caf6 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -521,6 +521,13 @@ void riscv_cpu_do_interrupt(CPUState *cs) [PRV_H] =3D RISCV_EXCP_H_ECALL, [PRV_M] =3D RISCV_EXCP_M_ECALL }; + if (env->foflag) { + if (env->vfp.vl !=3D 0) { + env->foflag =3D false; + env->pc +=3D 4; + return; + } + } =20 if (!async) { /* set tval to badaddr for traps with address information */ diff --git a/target/riscv/helper.h b/target/riscv/helper.h index f77c392..973342f 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -84,6 +84,13 @@ DEF_HELPER_5(vector_vle_v, void, env, i32, i32, i32, i32) DEF_HELPER_5(vector_vlbu_v, void, env, i32, i32, i32, i32) DEF_HELPER_5(vector_vlhu_v, void, env, i32, i32, i32, i32) DEF_HELPER_5(vector_vlwu_v, void, env, i32, i32, i32, i32) +DEF_HELPER_5(vector_vlbff_v, void, env, i32, i32, i32, i32) +DEF_HELPER_5(vector_vlhff_v, void, env, i32, i32, i32, i32) +DEF_HELPER_5(vector_vlwff_v, void, env, i32, i32, i32, i32) +DEF_HELPER_5(vector_vleff_v, void, env, i32, i32, i32, i32) +DEF_HELPER_5(vector_vlbuff_v, void, env, i32, i32, i32, i32) +DEF_HELPER_5(vector_vlhuff_v, void, env, i32, i32, i32, i32) +DEF_HELPER_5(vector_vlwuff_v, void, env, i32, i32, i32, i32) DEF_HELPER_5(vector_vsb_v, void, env, i32, i32, i32, i32) DEF_HELPER_5(vector_vsh_v, void, env, i32, i32, i32, i32) DEF_HELPER_5(vector_vsw_v, void, env, i32, i32, i32, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index b8a3d8a..b286997 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -218,6 +218,13 @@ vle_v ... 000 . 00000 ..... 111 ..... 0000111 @r2= _nfvm vlbu_v ... 000 . 00000 ..... 000 ..... 0000111 @r2_nfvm vlhu_v ... 000 . 00000 ..... 101 ..... 0000111 @r2_nfvm vlwu_v ... 000 . 00000 ..... 110 ..... 0000111 @r2_nfvm +vlbff_v ... 100 . 10000 ..... 000 ..... 0000111 @r2_nfvm +vlhff_v ... 100 . 10000 ..... 101 ..... 0000111 @r2_nfvm +vlwff_v ... 100 . 10000 ..... 110 ..... 0000111 @r2_nfvm +vleff_v ... 000 . 10000 ..... 111 ..... 0000111 @r2_nfvm +vlbuff_v ... 000 . 10000 ..... 000 ..... 0000111 @r2_nfvm +vlhuff_v ... 000 . 10000 ..... 101 ..... 0000111 @r2_nfvm +vlwuff_v ... 000 . 10000 ..... 110 ..... 0000111 @r2_nfvm vsb_v ... 000 . 00000 ..... 000 ..... 0100111 @r2_nfvm vsh_v ... 000 . 00000 ..... 101 ..... 0100111 @r2_nfvm vsw_v ... 000 . 00000 ..... 110 ..... 0100111 @r2_nfvm diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_tr= ans/trans_rvv.inc.c index 16b1f90..bd83885 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -80,6 +80,13 @@ GEN_VECTOR_R2_NFVM(vle_v) GEN_VECTOR_R2_NFVM(vlbu_v) GEN_VECTOR_R2_NFVM(vlhu_v) GEN_VECTOR_R2_NFVM(vlwu_v) +GEN_VECTOR_R2_NFVM(vlbff_v) +GEN_VECTOR_R2_NFVM(vlhff_v) +GEN_VECTOR_R2_NFVM(vlwff_v) +GEN_VECTOR_R2_NFVM(vleff_v) +GEN_VECTOR_R2_NFVM(vlbuff_v) +GEN_VECTOR_R2_NFVM(vlhuff_v) +GEN_VECTOR_R2_NFVM(vlwuff_v) GEN_VECTOR_R2_NFVM(vsb_v) GEN_VECTOR_R2_NFVM(vsh_v) GEN_VECTOR_R2_NFVM(vsw_v) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 62e4d2e..0ac8c74 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -2762,3 +2762,570 @@ void VECTOR_HELPER(vsuxe_v)(CPURISCVState *env, uin= t32_t nf, uint32_t vm, env->vfp.vstart =3D 0; } =20 +void VECTOR_HELPER(vlbuff_v)(CPURISCVState *env, uint32_t nf, uint32_t vm, + uint32_t rs1, uint32_t rd) +{ + int i, j, k, vl, vlmax, lmul, width, dest, read; + + vl =3D env->vfp.vl; + + lmul =3D vector_get_lmul(env); + width =3D vector_get_width(env); + vlmax =3D vector_get_vlmax(env); + + if (vector_vtype_ill(env) || vector_overlap_vm_common(lmul, vm, rd)) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + return; + } + if (lmul * (nf + 1) > 32) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + return; + } + + vector_lmul_check_reg(env, lmul, rd, false); + + env->foflag =3D true; + env->vfp.vl =3D 0; + for (i =3D 0; i < vlmax; i++) { + dest =3D rd + (i / (VLEN / width)); + j =3D i % (VLEN / width); + k =3D nf; + if (i < env->vfp.vstart) { + continue; + } else if (i < vl) { + switch (width) { + case 8: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D i * (nf + 1) + k; + env->vfp.vreg[dest + k * lmul].u8[j] =3D + cpu_ldub_data(env, env->gpr[rs1] + read); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + case 16: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D i * (nf + 1) + k; + env->vfp.vreg[dest + k * lmul].u16[j] =3D + cpu_ldub_data(env, env->gpr[rs1] + read); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + case 32: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D i * (nf + 1) + k; + env->vfp.vreg[dest + k * lmul].u32[j] =3D + cpu_ldub_data(env, env->gpr[rs1] + read); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + case 64: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D i * (nf + 1) + k; + env->vfp.vreg[dest + k * lmul].u64[j] =3D + cpu_ldub_data(env, env->gpr[rs1] + read); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + default: + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC(= )); + return; + } + } else { + vector_tail_segment(env, dest, j, width, k, lmul); + } + } + env->foflag =3D false; + env->vfp.vl =3D vl; + env->vfp.vstart =3D 0; +} + +void VECTOR_HELPER(vlbff_v)(CPURISCVState *env, uint32_t nf, uint32_t vm, + uint32_t rs1, uint32_t rd) +{ + int i, j, k, vl, vlmax, lmul, width, dest, read; + + vl =3D env->vfp.vl; + + lmul =3D vector_get_lmul(env); + width =3D vector_get_width(env); + vlmax =3D vector_get_vlmax(env); + + if (vector_vtype_ill(env) || vector_overlap_vm_common(lmul, vm, rd)) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + return; + } + if (lmul * (nf + 1) > 32) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + return; + } + + vector_lmul_check_reg(env, lmul, rd, false); + env->foflag =3D true; + env->vfp.vl =3D 0; + for (i =3D 0; i < vlmax; i++) { + dest =3D rd + (i / (VLEN / width)); + j =3D i % (VLEN / width); + k =3D nf; + if (i < env->vfp.vstart) { + continue; + } else if (i < vl) { + switch (width) { + case 8: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D i * (nf + 1) + k; + env->vfp.vreg[dest + k * lmul].s8[j] =3D + cpu_ldsb_data(env, env->gpr[rs1] + read); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + case 16: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D i * (nf + 1) + k; + env->vfp.vreg[dest + k * lmul].s16[j] =3D sign_ext= end( + cpu_ldsb_data(env, env->gpr[rs1] + read), 8); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + case 32: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D i * (nf + 1) + k; + env->vfp.vreg[dest + k * lmul].s32[j] =3D sign_ext= end( + cpu_ldsb_data(env, env->gpr[rs1] + read), 8); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + case 64: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D i * (nf + 1) + k; + env->vfp.vreg[dest + k * lmul].s64[j] =3D sign_ext= end( + cpu_ldsb_data(env, env->gpr[rs1] + read), 8); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + default: + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC(= )); + return; + } + } else { + vector_tail_segment(env, dest, j, width, k, lmul); + } + } + env->foflag =3D false; + env->vfp.vl =3D vl; + env->vfp.vstart =3D 0; +} + +void VECTOR_HELPER(vlhuff_v)(CPURISCVState *env, uint32_t nf, uint32_t vm, + uint32_t rs1, uint32_t rd) +{ + int i, j, k, vl, vlmax, lmul, width, dest, read; + + vl =3D env->vfp.vl; + + lmul =3D vector_get_lmul(env); + width =3D vector_get_width(env); + vlmax =3D vector_get_vlmax(env); + + if (vector_vtype_ill(env) || vector_overlap_vm_common(lmul, vm, rd)) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + return; + } + if (lmul * (nf + 1) > 32) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + return; + } + vector_lmul_check_reg(env, lmul, rd, false); + env->foflag =3D true; + env->vfp.vl =3D 0; + for (i =3D 0; i < vlmax; i++) { + dest =3D rd + (i / (VLEN / width)); + j =3D i % (VLEN / width); + k =3D nf; + if (i < env->vfp.vstart) { + continue; + } else if (i < vl) { + switch (width) { + case 16: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D (i * (nf + 1) + k) * 2; + env->vfp.vreg[dest + k * lmul].u16[j] =3D + cpu_lduw_data(env, env->gpr[rs1] + read); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + case 32: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D (i * (nf + 1) + k) * 2; + env->vfp.vreg[dest + k * lmul].u32[j] =3D + cpu_lduw_data(env, env->gpr[rs1] + read); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + case 64: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D (i * (nf + 1) + k) * 2; + env->vfp.vreg[dest + k * lmul].u64[j] =3D + cpu_lduw_data(env, env->gpr[rs1] + read); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + default: + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC(= )); + return; + } + } else { + vector_tail_segment(env, dest, j, width, k, lmul); + } + } + env->foflag =3D false; + env->vfp.vl =3D vl; + env->vfp.vstart =3D 0; +} + +void VECTOR_HELPER(vlhff_v)(CPURISCVState *env, uint32_t nf, uint32_t vm, + uint32_t rs1, uint32_t rd) +{ + int i, j, k, vl, vlmax, lmul, width, dest, read; + + vl =3D env->vfp.vl; + + lmul =3D vector_get_lmul(env); + width =3D vector_get_width(env); + vlmax =3D vector_get_vlmax(env); + + if (vector_vtype_ill(env) || vector_overlap_vm_common(lmul, vm, rd)) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + return; + } + if (lmul * (nf + 1) > 32) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + return; + } + vector_lmul_check_reg(env, lmul, rd, false); + env->foflag =3D true; + env->vfp.vl =3D 0; + for (i =3D 0; i < vlmax; i++) { + dest =3D rd + (i / (VLEN / width)); + j =3D i % (VLEN / width); + k =3D nf; + if (i < env->vfp.vstart) { + continue; + } else if (i < vl) { + switch (width) { + case 16: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D (i * (nf + 1) + k) * 2; + env->vfp.vreg[dest + k * lmul].s16[j] =3D + cpu_ldsw_data(env, env->gpr[rs1] + read); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + case 32: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D (i * (nf + 1) + k) * 2; + env->vfp.vreg[dest + k * lmul].s32[j] =3D sign_ext= end( + cpu_ldsw_data(env, env->gpr[rs1] + read), 16); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + case 64: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D (i * (nf + 1) + k) * 2; + env->vfp.vreg[dest + k * lmul].s64[j] =3D sign_ext= end( + cpu_ldsw_data(env, env->gpr[rs1] + read), 16); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + default: + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC(= )); + return; + } + } else { + vector_tail_segment(env, dest, j, width, k, lmul); + } + } + env->vfp.vl =3D vl; + env->foflag =3D false; + env->vfp.vstart =3D 0; +} + +void VECTOR_HELPER(vlwuff_v)(CPURISCVState *env, uint32_t nf, uint32_t vm, + uint32_t rs1, uint32_t rd) +{ + int i, j, k, vl, vlmax, lmul, width, dest, read; + + vl =3D env->vfp.vl; + + lmul =3D vector_get_lmul(env); + width =3D vector_get_width(env); + vlmax =3D vector_get_vlmax(env); + + if (vector_vtype_ill(env) || vector_overlap_vm_common(lmul, vm, rd)) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + return; + } + if (lmul * (nf + 1) > 32) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + return; + } + vector_lmul_check_reg(env, lmul, rd, false); + env->foflag =3D true; + env->vfp.vl =3D 0; + for (i =3D 0; i < vlmax; i++) { + dest =3D rd + (i / (VLEN / width)); + j =3D i % (VLEN / width); + k =3D nf; + if (i < env->vfp.vstart) { + continue; + } else if (i < vl) { + switch (width) { + case 32: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D (i * (nf + 1) + k) * 4; + env->vfp.vreg[dest + k * lmul].u32[j] =3D + cpu_ldl_data(env, env->gpr[rs1] + read); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + case 64: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D (i * (nf + 1) + k) * 4; + env->vfp.vreg[dest + k * lmul].u64[j] =3D + cpu_ldl_data(env, env->gpr[rs1] + read); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + default: + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC(= )); + return; + } + } else { + vector_tail_segment(env, dest, j, width, k, lmul); + } + } + env->foflag =3D false; + env->vfp.vl =3D vl; + env->vfp.vstart =3D 0; +} + +void VECTOR_HELPER(vlwff_v)(CPURISCVState *env, uint32_t nf, uint32_t vm, + uint32_t rs1, uint32_t rd) +{ + int i, j, k, vl, vlmax, lmul, width, dest, read; + + vl =3D env->vfp.vl; + + lmul =3D vector_get_lmul(env); + width =3D vector_get_width(env); + vlmax =3D vector_get_vlmax(env); + + if (vector_vtype_ill(env) || vector_overlap_vm_common(lmul, vm, rd)) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + return; + } + if (lmul * (nf + 1) > 32) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + return; + } + vector_lmul_check_reg(env, lmul, rd, false); + env->foflag =3D true; + env->vfp.vl =3D 0; + for (i =3D 0; i < vlmax; i++) { + dest =3D rd + (i / (VLEN / width)); + j =3D i % (VLEN / width); + k =3D nf; + if (i < env->vfp.vstart) { + continue; + } else if (i < vl) { + switch (width) { + case 32: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D (i * (nf + 1) + k) * 4; + env->vfp.vreg[dest + k * lmul].s32[j] =3D + cpu_ldl_data(env, env->gpr[rs1] + read); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + case 64: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D (i * (nf + 1) + k) * 4; + env->vfp.vreg[dest + k * lmul].s64[j] =3D sign_ext= end( + cpu_ldl_data(env, env->gpr[rs1] + read), 32); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + default: + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC(= )); + return; + } + } else { + vector_tail_segment(env, dest, j, width, k, lmul); + } + } + env->foflag =3D false; + env->vfp.vl =3D vl; + env->vfp.vstart =3D 0; +} + +void VECTOR_HELPER(vleff_v)(CPURISCVState *env, uint32_t nf, uint32_t vm, + uint32_t rs1, uint32_t rd) +{ + int i, j, k, vl, vlmax, lmul, width, dest, read; + + vl =3D env->vfp.vl; + lmul =3D vector_get_lmul(env); + width =3D vector_get_width(env); + vlmax =3D vector_get_vlmax(env); + + if (vector_vtype_ill(env) || vector_overlap_vm_common(lmul, vm, rd)) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + return; + } + if (lmul * (nf + 1) > 32) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + return; + } + + vector_lmul_check_reg(env, lmul, rd, false); + env->vfp.vl =3D 0; + env->foflag =3D true; + for (i =3D 0; i < vlmax; i++) { + dest =3D rd + (i / (VLEN / width)); + j =3D i % (VLEN / width); + k =3D nf; + if (i < env->vfp.vstart) { + continue; + } else if (i < vl) { + switch (width) { + case 8: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D i * (nf + 1) + k; + env->vfp.vreg[dest + k * lmul].u8[j] =3D + cpu_ldub_data(env, env->gpr[rs1] + read); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + case 16: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D (i * (nf + 1) + k) * 2; + env->vfp.vreg[dest + k * lmul].u16[j] =3D + cpu_lduw_data(env, env->gpr[rs1] + read); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + case 32: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D (i * (nf + 1) + k) * 4; + env->vfp.vreg[dest + k * lmul].u32[j] =3D + cpu_ldl_data(env, env->gpr[rs1] + read); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + case 64: + if (vector_elem_mask(env, vm, width, lmul, i)) { + while (k >=3D 0) { + read =3D (i * (nf + 1) + k) * 8; + env->vfp.vreg[dest + k * lmul].u64[j] =3D + cpu_ldq_data(env, env->gpr[rs1] + read); + k--; + } + env->vfp.vstart++; + } + env->vfp.vl++; + break; + default: + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC(= )); + return; + } + } else { + vector_tail_segment(env, dest, j, width, k, lmul); + } + } + env->foflag =3D false; + env->vfp.vl =3D vl; + env->vfp.vstart =3D 0; +} --=20 2.7.4