forked from mirror/qemu
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
843 lines
19 KiB
Modula-2
843 lines
19 KiB
Modula-2
/*
|
|
* Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
DEF_MACRO(fDUMPQ,
|
|
do {
|
|
printf(STR ":" #REG ": 0x%016llx\n",REG.ud[0]);
|
|
} while (0),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fUSE_LOOKUP_ADDRESS_BY_REV,
|
|
PROC->arch_proc_options->mmvec_use_full_va_for_lookup,
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fUSE_LOOKUP_ADDRESS,
|
|
1,
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fNOTQ,
|
|
({mmqreg_t _ret = {0}; int _i_; for (_i_ = 0; _i_ < fVECSIZE()/64; _i_++) _ret.ud[_i_] = ~VAL.ud[_i_]; _ret;}),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fGETQBITS,
|
|
((MASK) & (REG.w[(BITNO)>>5] >> ((BITNO) & 0x1f))),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fGETQBIT,
|
|
fGETQBITS(REG,1,1,BITNO),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fGENMASKW,
|
|
(((fGETQBIT(QREG,(IDX*4+0)) ? 0xFF : 0x0) << 0)
|
|
|((fGETQBIT(QREG,(IDX*4+1)) ? 0xFF : 0x0) << 8)
|
|
|((fGETQBIT(QREG,(IDX*4+2)) ? 0xFF : 0x0) << 16)
|
|
|((fGETQBIT(QREG,(IDX*4+3)) ? 0xFF : 0x0) << 24)),
|
|
()
|
|
)
|
|
DEF_MACRO(fGET10BIT,
|
|
{
|
|
COE = (((((fGETUBYTE(3,VAL) >> (2 * POS)) & 3) << 8) | fGETUBYTE(POS,VAL)) << 6);
|
|
COE >>= 6;
|
|
},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fVMAX,
|
|
(X>Y) ? X : Y,
|
|
()
|
|
)
|
|
|
|
|
|
DEF_MACRO(fGETNIBBLE,
|
|
( fSXTN(4,8,(SRC >> (4*IDX)) & 0xF) ),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fGETCRUMB,
|
|
( fSXTN(2,8,(SRC >> (2*IDX)) & 0x3) ),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fGETCRUMB_SYMMETRIC,
|
|
( (fGETCRUMB(IDX,SRC)>=0 ? (2-fGETCRUMB(IDX,SRC)) : fGETCRUMB(IDX,SRC) ) ),
|
|
()
|
|
)
|
|
|
|
#define ZERO_OFFSET_2B +
|
|
|
|
DEF_MACRO(fGENMASKH,
|
|
(((fGETQBIT(QREG,(IDX*2+0)) ? 0xFF : 0x0) << 0)
|
|
|((fGETQBIT(QREG,(IDX*2+1)) ? 0xFF : 0x0) << 8)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fGETMASKW,
|
|
(VREG.w[IDX] & fGENMASKW((QREG),IDX)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fGETMASKH,
|
|
(VREG.h[IDX] & fGENMASKH((QREG),IDX)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fCONDMASK8,
|
|
(fGETQBIT(QREG,IDX) ? (YESVAL) : (NOVAL)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fCONDMASK16,
|
|
((fGENMASKH(QREG,IDX) & (YESVAL)) | (fGENMASKH(fNOTQ(QREG),IDX) & (NOVAL))),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fCONDMASK32,
|
|
((fGENMASKW(QREG,IDX) & (YESVAL)) | (fGENMASKW(fNOTQ(QREG),IDX) & (NOVAL))),
|
|
()
|
|
)
|
|
|
|
|
|
DEF_MACRO(fSETQBITS,
|
|
do {
|
|
size4u_t __TMP = (VAL);
|
|
REG.w[(BITNO)>>5] &= ~((MASK) << ((BITNO) & 0x1f));
|
|
REG.w[(BITNO)>>5] |= (((__TMP) & (MASK)) << ((BITNO) & 0x1f));
|
|
} while (0),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fSETQBIT,
|
|
fSETQBITS(REG,1,1,BITNO,VAL),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fVBYTES,
|
|
(fVECSIZE()),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fVHALVES,
|
|
(fVECSIZE()/2),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fVWORDS,
|
|
(fVECSIZE()/4),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fVDWORDS,
|
|
(fVECSIZE()/8),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fVALIGN,
|
|
( ADDR = ADDR & ~(LOG2_ALIGNMENT-1)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fVLASTBYTE,
|
|
( ADDR = ADDR | (LOG2_ALIGNMENT-1)),
|
|
()
|
|
)
|
|
|
|
|
|
DEF_MACRO(fVELEM,
|
|
((fVECSIZE()*8)/WIDTH),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fVECLOGSIZE,
|
|
(mmvec_current_veclogsize(thread)),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fVECSIZE,
|
|
(1<<fVECLOGSIZE()),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fSWAPB,
|
|
{
|
|
size1u_t tmp = A;
|
|
A = B;
|
|
B = tmp;
|
|
},
|
|
/* NOTHING */
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fVZERO,
|
|
mmvec_zero_vector(),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fNEWVREG,
|
|
((THREAD2STRUCT->VRegs_updated & (((VRegMask)1)<<VNUM)) ? THREAD2STRUCT->future_VRegs[VNUM] : mmvec_zero_vector()),
|
|
(A_DOTNEWVALUE,A_RESTRICT_SLOT0ONLY)
|
|
)
|
|
|
|
DEF_MACRO(
|
|
fV_AL_CHECK,
|
|
if ((EA) & (MASK)) {
|
|
warn("aligning misaligned vector. PC=%08x EA=%08x",thread->Regs[REG_PC],(EA));
|
|
},
|
|
()
|
|
)
|
|
DEF_MACRO(fSCATTER_INIT,
|
|
{
|
|
mem_vector_scatter_init(thread, insn, REGION_START, LENGTH, ELEMENT_SIZE);
|
|
if (EXCEPTION_DETECTED) return;
|
|
},
|
|
(A_STORE,A_MEMLIKE,A_RESTRICT_SLOT0ONLY)
|
|
)
|
|
|
|
DEF_MACRO(fGATHER_INIT,
|
|
{
|
|
mem_vector_gather_init(thread, insn, REGION_START, LENGTH, ELEMENT_SIZE);
|
|
if (EXCEPTION_DETECTED) return;
|
|
},
|
|
(A_LOAD,A_MEMLIKE,A_RESTRICT_SLOT1ONLY)
|
|
)
|
|
|
|
DEF_MACRO(fSCATTER_FINISH,
|
|
{
|
|
if (EXCEPTION_DETECTED) return;
|
|
mem_vector_scatter_finish(thread, insn, OP);
|
|
},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fGATHER_FINISH,
|
|
{
|
|
if (EXCEPTION_DETECTED) return;
|
|
mem_vector_gather_finish(thread, insn);
|
|
},
|
|
()
|
|
)
|
|
|
|
|
|
DEF_MACRO(CHECK_VTCM_PAGE,
|
|
{
|
|
int slot = insn->slot;
|
|
paddr_t pa = thread->mem_access[slot].paddr+OFFSET;
|
|
pa = pa & ~(ALIGNMENT-1);
|
|
FLAG = (pa < (thread->mem_access[slot].paddr+LENGTH));
|
|
},
|
|
()
|
|
)
|
|
DEF_MACRO(COUNT_OUT_OF_BOUNDS,
|
|
{
|
|
if (!FLAG)
|
|
{
|
|
THREAD2STRUCT->vtcm_log.oob_access += SIZE;
|
|
warn("Scatter/Gather out of bounds of region");
|
|
}
|
|
},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fLOG_SCATTER_OP,
|
|
{
|
|
// Log the size and indicate that the extension ext.c file needs to increment right before memory write
|
|
THREAD2STRUCT->vtcm_log.op = 1;
|
|
THREAD2STRUCT->vtcm_log.op_size = SIZE;
|
|
},
|
|
()
|
|
)
|
|
|
|
|
|
|
|
DEF_MACRO(fVLOG_VTCM_WORD_INCREMENT,
|
|
{
|
|
int slot = insn->slot;
|
|
int log_bank = 0;
|
|
int log_byte =0;
|
|
paddr_t pa = thread->mem_access[slot].paddr+(OFFSET & ~(ALIGNMENT-1));
|
|
paddr_t pa_high = thread->mem_access[slot].paddr+LEN;
|
|
for(int i0 = 0; i0 < 4; i0++)
|
|
{
|
|
log_byte = ((OFFSET>=0)&&((pa+i0)<=pa_high));
|
|
log_bank |= (log_byte<<i0);
|
|
LOG_VTCM_BYTE(pa+i0,log_byte,INC.ub[4*IDX+i0],4*IDX+i0);
|
|
}
|
|
{ LOG_VTCM_BANK(pa, log_bank, IDX); }
|
|
},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fVLOG_VTCM_HALFWORD_INCREMENT,
|
|
{
|
|
int slot = insn->slot;
|
|
int log_bank = 0;
|
|
int log_byte = 0;
|
|
paddr_t pa = thread->mem_access[slot].paddr+(OFFSET & ~(ALIGNMENT-1));
|
|
paddr_t pa_high = thread->mem_access[slot].paddr+LEN;
|
|
for(int i0 = 0; i0 < 2; i0++) {
|
|
log_byte = ((OFFSET>=0)&&((pa+i0)<=pa_high));
|
|
log_bank |= (log_byte<<i0);
|
|
LOG_VTCM_BYTE(pa+i0,log_byte,INC.ub[2*IDX+i0],2*IDX+i0);
|
|
}
|
|
{ LOG_VTCM_BANK(pa, log_bank,IDX); }
|
|
},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fVLOG_VTCM_HALFWORD_INCREMENT_DV,
|
|
{
|
|
int slot = insn->slot;
|
|
int log_bank = 0;
|
|
int log_byte = 0;
|
|
paddr_t pa = thread->mem_access[slot].paddr+(OFFSET & ~(ALIGNMENT-1));
|
|
paddr_t pa_high = thread->mem_access[slot].paddr+LEN;
|
|
for(int i0 = 0; i0 < 2; i0++) {
|
|
log_byte = ((OFFSET>=0)&&((pa+i0)<=pa_high));
|
|
log_bank |= (log_byte<<i0);
|
|
LOG_VTCM_BYTE(pa+i0,log_byte,INC.ub[2*IDX+i0],2*IDX+i0);
|
|
}
|
|
{ LOG_VTCM_BANK(pa, log_bank,(2*IDX2+IDX_H));}
|
|
},
|
|
()
|
|
)
|
|
|
|
|
|
|
|
DEF_MACRO(GATHER_FUNCTION,
|
|
{
|
|
int slot = insn->slot;
|
|
int i0;
|
|
paddr_t pa = thread->mem_access[slot].paddr+OFFSET;
|
|
paddr_t pa_high = thread->mem_access[slot].paddr+LEN;
|
|
int log_bank = 0;
|
|
int log_byte = 0;
|
|
for(i0 = 0; i0 < ELEMENT_SIZE; i0++)
|
|
{
|
|
log_byte = ((OFFSET>=0)&&((pa+i0)<=pa_high)) && QVAL;
|
|
log_bank |= (log_byte<<i0);
|
|
size1u_t B = sim_mem_read1(thread->system_ptr, thread->threadId, thread->mem_access[slot].paddr+OFFSET+i0);
|
|
THREAD2STRUCT->tmp_VRegs[0].ub[ELEMENT_SIZE*IDX+i0] = B;
|
|
LOG_VTCM_BYTE(pa+i0,log_byte,B,ELEMENT_SIZE*IDX+i0);
|
|
}
|
|
LOG_VTCM_BANK(pa, log_bank,BANK_IDX);
|
|
},
|
|
()
|
|
)
|
|
|
|
|
|
|
|
DEF_MACRO(fVLOG_VTCM_GATHER_WORD,
|
|
{
|
|
GATHER_FUNCTION(EA,OFFSET,IDX, LEN, 4, IDX, 1);
|
|
},
|
|
()
|
|
)
|
|
DEF_MACRO(fVLOG_VTCM_GATHER_HALFWORD,
|
|
{
|
|
GATHER_FUNCTION(EA,OFFSET,IDX, LEN, 2, IDX, 1);
|
|
},
|
|
()
|
|
)
|
|
DEF_MACRO(fVLOG_VTCM_GATHER_HALFWORD_DV,
|
|
{
|
|
GATHER_FUNCTION(EA,OFFSET,IDX, LEN, 2, (2*IDX2+IDX_H), 1);
|
|
},
|
|
()
|
|
)
|
|
DEF_MACRO(fVLOG_VTCM_GATHER_WORDQ,
|
|
{
|
|
GATHER_FUNCTION(EA,OFFSET,IDX, LEN, 4, IDX, fGETQBIT(QsV,4*IDX+i0));
|
|
},
|
|
()
|
|
)
|
|
DEF_MACRO(fVLOG_VTCM_GATHER_HALFWORDQ,
|
|
{
|
|
GATHER_FUNCTION(EA,OFFSET,IDX, LEN, 2, IDX, fGETQBIT(QsV,2*IDX+i0));
|
|
},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fVLOG_VTCM_GATHER_HALFWORDQ_DV,
|
|
{
|
|
GATHER_FUNCTION(EA,OFFSET,IDX, LEN, 2, (2*IDX2+IDX_H), fGETQBIT(QsV,2*IDX+i0));
|
|
},
|
|
()
|
|
)
|
|
|
|
|
|
DEF_MACRO(DEBUG_LOG_ADDR,
|
|
{
|
|
|
|
if (thread->processor_ptr->arch_proc_options->mmvec_network_addr_log2)
|
|
{
|
|
|
|
int slot = insn->slot;
|
|
paddr_t pa = thread->mem_access[slot].paddr+OFFSET;
|
|
}
|
|
},
|
|
()
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DEF_MACRO(SCATTER_OP_WRITE_TO_MEM,
|
|
{
|
|
for (int i = 0; i < mmvecx->vtcm_log.size; i+=sizeof(TYPE))
|
|
{
|
|
if ( mmvecx->vtcm_log.mask.ub[i] != 0) {
|
|
TYPE dst = 0;
|
|
TYPE inc = 0;
|
|
for(int j = 0; j < sizeof(TYPE); j++) {
|
|
dst |= (sim_mem_read1(thread->system_ptr, thread->threadId, mmvecx->vtcm_log.pa[i+j]) << (8*j));
|
|
inc |= mmvecx->vtcm_log.data.ub[j+i] << (8*j);
|
|
|
|
mmvecx->vtcm_log.mask.ub[j+i] = 0;
|
|
mmvecx->vtcm_log.data.ub[j+i] = 0;
|
|
mmvecx->vtcm_log.offsets.ub[j+i] = 0;
|
|
}
|
|
dst += inc;
|
|
for(int j = 0; j < sizeof(TYPE); j++) {
|
|
sim_mem_write1(thread->system_ptr,thread->threadId, mmvecx->vtcm_log.pa[i+j], (dst >> (8*j))& 0xFF );
|
|
}
|
|
}
|
|
|
|
}
|
|
},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(SCATTER_FUNCTION,
|
|
{
|
|
int slot = insn->slot;
|
|
int i0;
|
|
paddr_t pa = thread->mem_access[slot].paddr+OFFSET;
|
|
paddr_t pa_high = thread->mem_access[slot].paddr+LEN;
|
|
int log_bank = 0;
|
|
int log_byte = 0;
|
|
for(i0 = 0; i0 < ELEMENT_SIZE; i0++) {
|
|
log_byte = ((OFFSET>=0)&&((pa+i0)<=pa_high)) && QVAL;
|
|
log_bank |= (log_byte<<i0);
|
|
LOG_VTCM_BYTE(pa+i0,log_byte,IN.ub[ELEMENT_SIZE*IDX+i0],ELEMENT_SIZE*IDX+i0);
|
|
}
|
|
LOG_VTCM_BANK(pa, log_bank,BANK_IDX);
|
|
|
|
},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fVLOG_VTCM_HALFWORD,
|
|
{
|
|
SCATTER_FUNCTION (EA,OFFSET,IDX, LEN, 2, IDX, 1, IN);
|
|
},
|
|
()
|
|
)
|
|
DEF_MACRO(fVLOG_VTCM_WORD,
|
|
{
|
|
SCATTER_FUNCTION (EA,OFFSET,IDX, LEN, 4, IDX, 1, IN);
|
|
},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fVLOG_VTCM_HALFWORDQ,
|
|
{
|
|
SCATTER_FUNCTION (EA,OFFSET,IDX, LEN, 2, IDX, fGETQBIT(QsV,2*IDX+i0), IN);
|
|
},
|
|
()
|
|
)
|
|
DEF_MACRO(fVLOG_VTCM_WORDQ,
|
|
{
|
|
SCATTER_FUNCTION (EA,OFFSET,IDX, LEN, 4, IDX, fGETQBIT(QsV,4*IDX+i0), IN);
|
|
},
|
|
()
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
DEF_MACRO(fVLOG_VTCM_HALFWORD_DV,
|
|
{
|
|
SCATTER_FUNCTION (EA,OFFSET,IDX, LEN, 2, (2*IDX2+IDX_H), 1, IN);
|
|
},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fVLOG_VTCM_HALFWORDQ_DV,
|
|
{
|
|
SCATTER_FUNCTION (EA,OFFSET,IDX, LEN, 2, (2*IDX2+IDX_H), fGETQBIT(QsV,2*IDX+i0), IN);
|
|
},
|
|
()
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DEF_MACRO(fSTORERELEASE,
|
|
{
|
|
fV_AL_CHECK(EA,fVECSIZE()-1);
|
|
|
|
mem_store_release(thread, insn, fVECSIZE(), EA&~(fVECSIZE()-1), EA, TYPE, fUSE_LOOKUP_ADDRESS_BY_REV(thread->processor_ptr));
|
|
},
|
|
(A_STORE,A_MEMLIKE)
|
|
)
|
|
|
|
DEF_MACRO(fVFETCH_AL,
|
|
{
|
|
fV_AL_CHECK(EA,fVECSIZE()-1);
|
|
mem_fetch_vector(thread, insn, EA&~(fVECSIZE()-1), insn->slot, fVECSIZE());
|
|
},
|
|
(A_LOAD,A_MEMLIKE)
|
|
)
|
|
|
|
|
|
DEF_MACRO(fLOADMMV_AL,
|
|
{
|
|
fV_AL_CHECK(EA,ALIGNMENT-1);
|
|
thread->last_pkt->double_access_vec = 0;
|
|
mem_load_vector_oddva(thread, insn, EA&~(ALIGNMENT-1), EA, insn->slot, LEN, &DST.ub[0], LEN, fUSE_LOOKUP_ADDRESS_BY_REV(thread->processor_ptr));
|
|
},
|
|
(A_LOAD,A_MEMLIKE)
|
|
)
|
|
|
|
DEF_MACRO(fLOADMMV,
|
|
fLOADMMV_AL(EA,fVECSIZE(),fVECSIZE(),DST),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fLOADMMVQ,
|
|
do {
|
|
int __i;
|
|
fLOADMMV_AL(EA,fVECSIZE(),fVECSIZE(),DST);
|
|
fVFOREACH(8,__i) if (!fGETQBIT(QVAL,__i)) DST.b[__i] = 0;
|
|
} while (0),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fLOADMMVNQ,
|
|
do {
|
|
int __i;
|
|
fLOADMMV_AL(EA,fVECSIZE(),fVECSIZE(),DST);
|
|
fVFOREACH(8,__i) if (fGETQBIT(QVAL,__i)) DST.b[__i] = 0;
|
|
} while (0),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fLOADMMVU_AL,
|
|
{
|
|
size4u_t size2 = (EA)&(ALIGNMENT-1);
|
|
size4u_t size1 = LEN-size2;
|
|
thread->last_pkt->double_access_vec = 1;
|
|
mem_load_vector_oddva(thread, insn, EA+size1, EA+fVECSIZE(), /* slot */ 1, size2, &DST.ub[size1], size2, fUSE_LOOKUP_ADDRESS());
|
|
mem_load_vector_oddva(thread, insn, EA, EA,/* slot */ 0, size1, &DST.ub[0], size1, fUSE_LOOKUP_ADDRESS_BY_REV(thread->processor_ptr));
|
|
},
|
|
(A_LOAD,A_MEMLIKE)
|
|
)
|
|
|
|
DEF_MACRO(fLOADMMVU,
|
|
{
|
|
/* if address happens to be aligned, only do aligned load */
|
|
thread->last_pkt->pkt_has_vtcm_access = 0;
|
|
thread->last_pkt->pkt_access_count = 0;
|
|
if ( (EA & (fVECSIZE()-1)) == 0) {
|
|
thread->last_pkt->pkt_has_vmemu_access = 0;
|
|
thread->last_pkt->double_access = 0;
|
|
|
|
fLOADMMV_AL(EA,fVECSIZE(),fVECSIZE(),DST);
|
|
} else {
|
|
thread->last_pkt->pkt_has_vmemu_access = 1;
|
|
thread->last_pkt->double_access = 1;
|
|
|
|
fLOADMMVU_AL(EA,fVECSIZE(),fVECSIZE(),DST);
|
|
}
|
|
},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fSTOREMMV_AL,
|
|
{
|
|
fV_AL_CHECK(EA,ALIGNMENT-1);
|
|
mem_store_vector_oddva(thread, insn, EA&~(ALIGNMENT-1), EA, insn->slot, LEN, &SRC.ub[0], 0, 0, fUSE_LOOKUP_ADDRESS_BY_REV(thread->processor_ptr));
|
|
},
|
|
(A_STORE,A_MEMLIKE)
|
|
)
|
|
|
|
DEF_MACRO(fSTOREMMV,
|
|
fSTOREMMV_AL(EA,fVECSIZE(),fVECSIZE(),SRC),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fSTOREMMVQ_AL,
|
|
do {
|
|
mmvector_t maskvec;
|
|
int i;
|
|
for (i = 0; i < fVECSIZE(); i++) maskvec.ub[i] = fGETQBIT(MASK,i);
|
|
mem_store_vector_oddva(thread, insn, EA&~(ALIGNMENT-1), EA, insn->slot, LEN, &SRC.ub[0], &maskvec.ub[0], 0, fUSE_LOOKUP_ADDRESS_BY_REV(thread->processor_ptr));
|
|
} while (0),
|
|
(A_STORE,A_MEMLIKE)
|
|
)
|
|
|
|
DEF_MACRO(fSTOREMMVQ,
|
|
fSTOREMMVQ_AL(EA,fVECSIZE(),fVECSIZE(),SRC,MASK),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fSTOREMMVNQ_AL,
|
|
{
|
|
mmvector_t maskvec;
|
|
int i;
|
|
for (i = 0; i < fVECSIZE(); i++) maskvec.ub[i] = fGETQBIT(MASK,i);
|
|
fV_AL_CHECK(EA,ALIGNMENT-1);
|
|
mem_store_vector_oddva(thread, insn, EA&~(ALIGNMENT-1), EA, insn->slot, LEN, &SRC.ub[0], &maskvec.ub[0], 1, fUSE_LOOKUP_ADDRESS_BY_REV(thread->processor_ptr));
|
|
},
|
|
(A_STORE,A_MEMLIKE)
|
|
)
|
|
|
|
DEF_MACRO(fSTOREMMVNQ,
|
|
fSTOREMMVNQ_AL(EA,fVECSIZE(),fVECSIZE(),SRC,MASK),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fSTOREMMVU_AL,
|
|
{
|
|
size4u_t size1 = ALIGNMENT-((EA)&(ALIGNMENT-1));
|
|
size4u_t size2;
|
|
if (size1>LEN) size1 = LEN;
|
|
size2 = LEN-size1;
|
|
mem_store_vector_oddva(thread, insn, EA+size1, EA+fVECSIZE(), /* slot */ 1, size2, &SRC.ub[size1], 0, 0, fUSE_LOOKUP_ADDRESS());
|
|
mem_store_vector_oddva(thread, insn, EA, EA, /* slot */ 0, size1, &SRC.ub[0], 0, 0, fUSE_LOOKUP_ADDRESS_BY_REV(thread->processor_ptr));
|
|
},
|
|
(A_STORE,A_MEMLIKE)
|
|
)
|
|
|
|
DEF_MACRO(fSTOREMMVU,
|
|
{
|
|
thread->last_pkt->pkt_has_vtcm_access = 0;
|
|
thread->last_pkt->pkt_access_count = 0;
|
|
if ( (EA & (fVECSIZE()-1)) == 0) {
|
|
thread->last_pkt->double_access = 0;
|
|
fSTOREMMV_AL(EA,fVECSIZE(),fVECSIZE(),SRC);
|
|
} else {
|
|
thread->last_pkt->double_access = 1;
|
|
thread->last_pkt->pkt_has_vmemu_access = 1;
|
|
fSTOREMMVU_AL(EA,fVECSIZE(),fVECSIZE(),SRC);
|
|
}
|
|
},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fSTOREMMVQU_AL,
|
|
{
|
|
size4u_t size1 = ALIGNMENT-((EA)&(ALIGNMENT-1));
|
|
size4u_t size2;
|
|
mmvector_t maskvec;
|
|
int i;
|
|
for (i = 0; i < fVECSIZE(); i++) maskvec.ub[i] = fGETQBIT(MASK,i);
|
|
if (size1>LEN) size1 = LEN;
|
|
size2 = LEN-size1;
|
|
mem_store_vector_oddva(thread, insn, EA+size1, EA+fVECSIZE(),/* slot */ 1, size2, &SRC.ub[size1], &maskvec.ub[size1], 0, fUSE_LOOKUP_ADDRESS());
|
|
mem_store_vector_oddva(thread, insn, EA, /* slot */ 0, size1, &SRC.ub[0], &maskvec.ub[0], 0, fUSE_LOOKUP_ADDRESS_BY_REV(thread->processor_ptr));
|
|
},
|
|
(A_STORE,A_MEMLIKE)
|
|
)
|
|
|
|
DEF_MACRO(fSTOREMMVQU,
|
|
{
|
|
thread->last_pkt->pkt_has_vtcm_access = 0;
|
|
thread->last_pkt->pkt_access_count = 0;
|
|
if ( (EA & (fVECSIZE()-1)) == 0) {
|
|
thread->last_pkt->double_access = 0;
|
|
fSTOREMMVQ_AL(EA,fVECSIZE(),fVECSIZE(),SRC,MASK);
|
|
} else {
|
|
thread->last_pkt->double_access = 1;
|
|
thread->last_pkt->pkt_has_vmemu_access = 1;
|
|
fSTOREMMVQU_AL(EA,fVECSIZE(),fVECSIZE(),SRC,MASK);
|
|
}
|
|
},
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fSTOREMMVNQU_AL,
|
|
{
|
|
size4u_t size1 = ALIGNMENT-((EA)&(ALIGNMENT-1));
|
|
size4u_t size2;
|
|
mmvector_t maskvec;
|
|
int i;
|
|
for (i = 0; i < fVECSIZE(); i++) maskvec.ub[i] = fGETQBIT(MASK,i);
|
|
if (size1>LEN) size1 = LEN;
|
|
size2 = LEN-size1;
|
|
mem_store_vector_oddva(thread, insn, EA+size1, EA+fVECSIZE(), /* slot */ 1, size2, &SRC.ub[size1], &maskvec.ub[size1], 1, fUSE_LOOKUP_ADDRESS());
|
|
mem_store_vector_oddva(thread, insn, EA, EA, /* slot */ 0, size1, &SRC.ub[0], &maskvec.ub[0], 1, fUSE_LOOKUP_ADDRESS_BY_REV(thread->processor_ptr));
|
|
},
|
|
(A_STORE,A_MEMLIKE)
|
|
)
|
|
|
|
DEF_MACRO(fSTOREMMVNQU,
|
|
{
|
|
thread->last_pkt->pkt_has_vtcm_access = 0;
|
|
thread->last_pkt->pkt_access_count = 0;
|
|
if ( (EA & (fVECSIZE()-1)) == 0) {
|
|
thread->last_pkt->double_access = 0;
|
|
fSTOREMMVNQ_AL(EA,fVECSIZE(),fVECSIZE(),SRC,MASK);
|
|
} else {
|
|
thread->last_pkt->double_access = 1;
|
|
thread->last_pkt->pkt_has_vmemu_access = 1;
|
|
fSTOREMMVNQU_AL(EA,fVECSIZE(),fVECSIZE(),SRC,MASK);
|
|
}
|
|
},
|
|
()
|
|
)
|
|
|
|
|
|
|
|
|
|
DEF_MACRO(fVFOREACH,
|
|
for (VAR = 0; VAR < fVELEM(WIDTH); VAR++),
|
|
/* NOTHING */
|
|
)
|
|
|
|
DEF_MACRO(fVARRAY_ELEMENT_ACCESS,
|
|
ARRAY.v[(INDEX) / (fVECSIZE()/(sizeof(ARRAY.TYPE[0])))].TYPE[(INDEX) % (fVECSIZE()/(sizeof(ARRAY.TYPE[0])))],
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fVNEWCANCEL,
|
|
do { THREAD2STRUCT->VRegs_select &= ~(1<<(REGNUM)); } while (0),
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fTMPVDATA,
|
|
mmvec_vtmp_data(thread),
|
|
(A_CVI)
|
|
)
|
|
|
|
DEF_MACRO(fVSATDW,
|
|
fVSATW( ( ( ((long long)U)<<32 ) | fZXTN(32,64,V) ) ),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(fVASL_SATHI,
|
|
fVSATW(((U)<<1) | ((V)>>31)),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(fVUADDSAT,
|
|
fVSATUN( WIDTH, fZXTN(WIDTH, 2*WIDTH, U) + fZXTN(WIDTH, 2*WIDTH, V)),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(fVSADDSAT,
|
|
fVSATN( WIDTH, fSXTN(WIDTH, 2*WIDTH, U) + fSXTN(WIDTH, 2*WIDTH, V)),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(fVUSUBSAT,
|
|
fVSATUN( WIDTH, fZXTN(WIDTH, 2*WIDTH, U) - fZXTN(WIDTH, 2*WIDTH, V)),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(fVSSUBSAT,
|
|
fVSATN( WIDTH, fSXTN(WIDTH, 2*WIDTH, U) - fSXTN(WIDTH, 2*WIDTH, V)),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(fVAVGU,
|
|
((fZXTN(WIDTH, 2*WIDTH, U) + fZXTN(WIDTH, 2*WIDTH, V))>>1),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(fVAVGURND,
|
|
((fZXTN(WIDTH, 2*WIDTH, U) + fZXTN(WIDTH, 2*WIDTH, V)+1)>>1),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(fVNAVGU,
|
|
((fZXTN(WIDTH, 2*WIDTH, U) - fZXTN(WIDTH, 2*WIDTH, V))>>1),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(fVNAVGURNDSAT,
|
|
fVSATUN(WIDTH,((fZXTN(WIDTH, 2*WIDTH, U) - fZXTN(WIDTH, 2*WIDTH, V)+1)>>1)),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(fVAVGS,
|
|
((fSXTN(WIDTH, 2*WIDTH, U) + fSXTN(WIDTH, 2*WIDTH, V))>>1),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(fVAVGSRND,
|
|
((fSXTN(WIDTH, 2*WIDTH, U) + fSXTN(WIDTH, 2*WIDTH, V)+1)>>1),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(fVNAVGS,
|
|
((fSXTN(WIDTH, 2*WIDTH, U) - fSXTN(WIDTH, 2*WIDTH, V))>>1),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(fVNAVGSRND,
|
|
((fSXTN(WIDTH, 2*WIDTH, U) - fSXTN(WIDTH, 2*WIDTH, V)+1)>>1),
|
|
/* attribs */
|
|
)
|
|
|
|
DEF_MACRO(fVNAVGSRNDSAT,
|
|
fVSATN(WIDTH,((fSXTN(WIDTH, 2*WIDTH, U) - fSXTN(WIDTH, 2*WIDTH, V)+1)>>1)),
|
|
/* attribs */
|
|
)
|
|
|
|
|
|
DEF_MACRO(fVNOROUND,
|
|
VAL,
|
|
/* NOTHING */
|
|
)
|
|
DEF_MACRO(fVNOSAT,
|
|
VAL,
|
|
/* NOTHING */
|
|
)
|
|
|
|
DEF_MACRO(fVROUND,
|
|
((VAL) + (((SHAMT)>0)?(1LL<<((SHAMT)-1)):0)),
|
|
/* NOTHING */
|
|
)
|
|
|
|
DEF_MACRO(fCARRY_FROM_ADD32,
|
|
(((fZXTN(32,64,A)+fZXTN(32,64,B)+C) >> 32) & 1),
|
|
/* NOTHING */
|
|
)
|
|
|
|
DEF_MACRO(fUARCH_NOTE_PUMP_4X,
|
|
,
|
|
()
|
|
)
|
|
|
|
DEF_MACRO(fUARCH_NOTE_PUMP_2X,
|
|
,
|
|
()
|
|
)
|