xref: /qemu/target/riscv/vector_internals.c (revision be355a44ca69e119278dd5212886aaeac560ae59)
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 
19*be355a44SPeter Maydell #include "qemu/osdep.h"
2098f40dd2SKiran Ostrolenk #include "vector_internals.h"
2198f40dd2SKiran Ostrolenk 
2298f40dd2SKiran Ostrolenk /* set agnostic elements to 1s */
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     }
3398f40dd2SKiran Ostrolenk     memset(base + cnt, -1, tot - cnt);
3498f40dd2SKiran Ostrolenk }
3598f40dd2SKiran Ostrolenk 
3698f40dd2SKiran Ostrolenk void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
3798f40dd2SKiran Ostrolenk                 CPURISCVState *env, uint32_t desc,
3898f40dd2SKiran Ostrolenk                 opivv2_fn *fn, uint32_t esz)
3998f40dd2SKiran Ostrolenk {
4098f40dd2SKiran Ostrolenk     uint32_t vm = vext_vm(desc);
4198f40dd2SKiran Ostrolenk     uint32_t vl = env->vl;
4298f40dd2SKiran Ostrolenk     uint32_t total_elems = vext_get_total_elems(env, desc, esz);
4398f40dd2SKiran Ostrolenk     uint32_t vta = vext_vta(desc);
4498f40dd2SKiran Ostrolenk     uint32_t vma = vext_vma(desc);
4598f40dd2SKiran Ostrolenk     uint32_t i;
4698f40dd2SKiran Ostrolenk 
4798f40dd2SKiran Ostrolenk     for (i = env->vstart; i < vl; i++) {
4898f40dd2SKiran Ostrolenk         if (!vm && !vext_elem_mask(v0, i)) {
4998f40dd2SKiran Ostrolenk             /* set masked-off elements to 1s */
5098f40dd2SKiran Ostrolenk             vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
5198f40dd2SKiran Ostrolenk             continue;
5298f40dd2SKiran Ostrolenk         }
5398f40dd2SKiran Ostrolenk         fn(vd, vs1, vs2, i);
5498f40dd2SKiran Ostrolenk     }
5598f40dd2SKiran Ostrolenk     env->vstart = 0;
5698f40dd2SKiran Ostrolenk     /* set tail elements to 1s */
5798f40dd2SKiran Ostrolenk     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
5898f40dd2SKiran Ostrolenk }
5998f40dd2SKiran Ostrolenk 
6098f40dd2SKiran Ostrolenk void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
6198f40dd2SKiran Ostrolenk                 CPURISCVState *env, uint32_t desc,
6298f40dd2SKiran Ostrolenk                 opivx2_fn fn, uint32_t esz)
6398f40dd2SKiran Ostrolenk {
6498f40dd2SKiran Ostrolenk     uint32_t vm = vext_vm(desc);
6598f40dd2SKiran Ostrolenk     uint32_t vl = env->vl;
6698f40dd2SKiran Ostrolenk     uint32_t total_elems = vext_get_total_elems(env, desc, esz);
6798f40dd2SKiran Ostrolenk     uint32_t vta = vext_vta(desc);
6898f40dd2SKiran Ostrolenk     uint32_t vma = vext_vma(desc);
6998f40dd2SKiran Ostrolenk     uint32_t i;
7098f40dd2SKiran Ostrolenk 
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, s1, 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 }
83