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 */ 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 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*e8384531SChao 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 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*e8384531SChao 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