198f40dd2SKiran Ostrolenk /*
298f40dd2SKiran Ostrolenk * RISC-V Vector Extension Internals
398f40dd2SKiran Ostrolenk *
498f40dd2SKiran Ostrolenk * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved.
598f40dd2SKiran Ostrolenk *
698f40dd2SKiran Ostrolenk * This program is free software; you can redistribute it and/or modify it
798f40dd2SKiran Ostrolenk * under the terms and conditions of the GNU General Public License,
898f40dd2SKiran Ostrolenk * version 2 or later, as published by the Free Software Foundation.
998f40dd2SKiran Ostrolenk *
1098f40dd2SKiran Ostrolenk * This program is distributed in the hope it will be useful, but WITHOUT
1198f40dd2SKiran Ostrolenk * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1298f40dd2SKiran Ostrolenk * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
1398f40dd2SKiran Ostrolenk * more details.
1498f40dd2SKiran Ostrolenk *
1598f40dd2SKiran Ostrolenk * You should have received a copy of the GNU General Public License along with
1698f40dd2SKiran Ostrolenk * this program. If not, see <http://www.gnu.org/licenses/>.
1798f40dd2SKiran Ostrolenk */
1898f40dd2SKiran Ostrolenk
19be355a44SPeter Maydell #include "qemu/osdep.h"
2098f40dd2SKiran Ostrolenk #include "vector_internals.h"
2198f40dd2SKiran Ostrolenk
2298f40dd2SKiran Ostrolenk /* set agnostic elements to 1s */
vext_set_elems_1s(void * base,uint32_t is_agnostic,uint32_t cnt,uint32_t tot)2398f40dd2SKiran Ostrolenk void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
2498f40dd2SKiran Ostrolenk uint32_t tot)
2598f40dd2SKiran Ostrolenk {
2698f40dd2SKiran Ostrolenk if (is_agnostic == 0) {
2798f40dd2SKiran Ostrolenk /* policy undisturbed */
2898f40dd2SKiran Ostrolenk return;
2998f40dd2SKiran Ostrolenk }
3098f40dd2SKiran Ostrolenk if (tot - cnt == 0) {
3198f40dd2SKiran Ostrolenk return ;
3298f40dd2SKiran Ostrolenk }
3375115d88SHuang Tao
3475115d88SHuang Tao if (HOST_BIG_ENDIAN) {
3575115d88SHuang Tao /*
3675115d88SHuang Tao * Deal the situation when the elements are insdie
3775115d88SHuang Tao * only one uint64 block including setting the
3875115d88SHuang Tao * masked-off element.
3975115d88SHuang Tao */
4075115d88SHuang Tao if (((tot - 1) ^ cnt) < 8) {
4175115d88SHuang Tao memset(base + H1(tot - 1), -1, tot - cnt);
4275115d88SHuang Tao return;
4375115d88SHuang Tao }
4475115d88SHuang Tao /*
4575115d88SHuang Tao * Otherwise, at least cross two uint64_t blocks.
4675115d88SHuang Tao * Set first unaligned block.
4775115d88SHuang Tao */
4875115d88SHuang Tao if (cnt % 8 != 0) {
4975115d88SHuang Tao uint32_t j = ROUND_UP(cnt, 8);
5075115d88SHuang Tao memset(base + H1(j - 1), -1, j - cnt);
5175115d88SHuang Tao cnt = j;
5275115d88SHuang Tao }
5375115d88SHuang Tao /* Set other 64bit aligend blocks */
5475115d88SHuang Tao }
5598f40dd2SKiran Ostrolenk memset(base + cnt, -1, tot - cnt);
5698f40dd2SKiran Ostrolenk }
5798f40dd2SKiran Ostrolenk
do_vext_vv(void * vd,void * v0,void * vs1,void * vs2,CPURISCVState * env,uint32_t desc,opivv2_fn * fn,uint32_t esz)5898f40dd2SKiran Ostrolenk void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
5998f40dd2SKiran Ostrolenk CPURISCVState *env, uint32_t desc,
6098f40dd2SKiran Ostrolenk opivv2_fn *fn, uint32_t esz)
6198f40dd2SKiran Ostrolenk {
6298f40dd2SKiran Ostrolenk uint32_t vm = vext_vm(desc);
6398f40dd2SKiran Ostrolenk uint32_t vl = env->vl;
6498f40dd2SKiran Ostrolenk uint32_t total_elems = vext_get_total_elems(env, desc, esz);
6598f40dd2SKiran Ostrolenk uint32_t vta = vext_vta(desc);
6698f40dd2SKiran Ostrolenk uint32_t vma = vext_vma(desc);
6798f40dd2SKiran Ostrolenk uint32_t i;
6898f40dd2SKiran Ostrolenk
69*7f5f3e5aSChao Liu VSTART_CHECK_EARLY_EXIT(env, vl);
70df4252b2SDaniel Henrique Barboza
7198f40dd2SKiran Ostrolenk for (i = env->vstart; i < vl; i++) {
7298f40dd2SKiran Ostrolenk if (!vm && !vext_elem_mask(v0, i)) {
7398f40dd2SKiran Ostrolenk /* set masked-off elements to 1s */
7498f40dd2SKiran Ostrolenk vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
7598f40dd2SKiran Ostrolenk continue;
7698f40dd2SKiran Ostrolenk }
7798f40dd2SKiran Ostrolenk fn(vd, vs1, vs2, i);
7898f40dd2SKiran Ostrolenk }
7998f40dd2SKiran Ostrolenk env->vstart = 0;
8098f40dd2SKiran Ostrolenk /* set tail elements to 1s */
8198f40dd2SKiran Ostrolenk vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
8298f40dd2SKiran Ostrolenk }
8398f40dd2SKiran Ostrolenk
do_vext_vx(void * vd,void * v0,target_long s1,void * vs2,CPURISCVState * env,uint32_t desc,opivx2_fn fn,uint32_t esz)8498f40dd2SKiran Ostrolenk void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
8598f40dd2SKiran Ostrolenk CPURISCVState *env, uint32_t desc,
8698f40dd2SKiran Ostrolenk opivx2_fn fn, uint32_t esz)
8798f40dd2SKiran Ostrolenk {
8898f40dd2SKiran Ostrolenk uint32_t vm = vext_vm(desc);
8998f40dd2SKiran Ostrolenk uint32_t vl = env->vl;
9098f40dd2SKiran Ostrolenk uint32_t total_elems = vext_get_total_elems(env, desc, esz);
9198f40dd2SKiran Ostrolenk uint32_t vta = vext_vta(desc);
9298f40dd2SKiran Ostrolenk uint32_t vma = vext_vma(desc);
9398f40dd2SKiran Ostrolenk uint32_t i;
9498f40dd2SKiran Ostrolenk
95*7f5f3e5aSChao Liu VSTART_CHECK_EARLY_EXIT(env, vl);
96df4252b2SDaniel Henrique Barboza
9798f40dd2SKiran Ostrolenk for (i = env->vstart; i < vl; i++) {
9898f40dd2SKiran Ostrolenk if (!vm && !vext_elem_mask(v0, i)) {
9998f40dd2SKiran Ostrolenk /* set masked-off elements to 1s */
10098f40dd2SKiran Ostrolenk vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
10198f40dd2SKiran Ostrolenk continue;
10298f40dd2SKiran Ostrolenk }
10398f40dd2SKiran Ostrolenk fn(vd, s1, vs2, i);
10498f40dd2SKiran Ostrolenk }
10598f40dd2SKiran Ostrolenk env->vstart = 0;
10698f40dd2SKiran Ostrolenk /* set tail elements to 1s */
10798f40dd2SKiran Ostrolenk vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
10898f40dd2SKiran Ostrolenk }
109