2012-03-24 18:41:51 +11:00
|
|
|
/* VECTOR.C (c) Copyright Jan Jaeger, 1999-2012 */
|
|
|
|
|
/* (c) Copyright Roger Bowler, 1999-2012 */
|
2010-05-25 03:55:37 +00:00
|
|
|
/* S/370 and ESA/390 Vector Operations */
|
|
|
|
|
/* */
|
|
|
|
|
/* Released under "The Q Public License Version 1" */
|
|
|
|
|
/* (http://www.hercules-390.org/herclic.html) as modifications to */
|
|
|
|
|
/* Hercules. */
|
2001-02-23 20:49:19 +00:00
|
|
|
|
2012-03-24 18:41:51 +11:00
|
|
|
/* Interpretive Execution - (c) Copyright Jan Jaeger, 1999-2012 */
|
|
|
|
|
/* z/Architecture support - (c) Copyright Jan Jaeger, 1999-2012 */
|
2006-12-08 09:43:35 +00:00
|
|
|
|
2001-02-23 20:49:19 +00:00
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* This module implements the Vector Facility instruction execution */
|
|
|
|
|
/* function of the S/370 and ESA/390 architectures, as described in */
|
|
|
|
|
/* SA22-7125-03 Vector Operations (S/370 & ESA/370) */
|
|
|
|
|
/* SA22-7207-00 Vector Operations (ESA/390) */
|
|
|
|
|
/* 28/05/2000 Jan Jaeger */
|
|
|
|
|
/* */
|
|
|
|
|
/* Instruction decoding rework 09/07/2000 Jan Jaeger */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
|
2005-09-24 16:17:46 +00:00
|
|
|
#include "hstdinc.h"
|
|
|
|
|
|
2001-02-23 20:49:19 +00:00
|
|
|
#include "hercules.h"
|
|
|
|
|
|
|
|
|
|
#include "opcode.h"
|
|
|
|
|
|
|
|
|
|
#include "inline.h"
|
|
|
|
|
|
|
|
|
|
#if defined(FEATURE_VECTOR_FACILITY)
|
|
|
|
|
|
|
|
|
|
/* The vector save area must be aligned on a boundary 8 times the
|
|
|
|
|
section size, however VM stores at 4 times the section size.
|
|
|
|
|
I do not know if the book or VM is wrong. *JJ */
|
|
|
|
|
#define VSA_ALIGN 4
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A640 VTVM - Test VMR [RRE] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_test_vmr)
|
|
|
|
|
{
|
|
|
|
|
int unused1, unused2;
|
|
|
|
|
U32 n, n1;
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
RRE(inst, regs, unused1, unused2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
/* Extract vector count (number of active bits in vmr) */
|
|
|
|
|
n = VECTOR_COUNT(regs);
|
|
|
|
|
|
|
|
|
|
/* cc0 when the vector count is zero */
|
|
|
|
|
if( n == 0)
|
|
|
|
|
{
|
2007-01-13 07:30:02 +00:00
|
|
|
regs->psw.cc = 0;
|
2001-02-23 20:49:19 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Preset condition code according to first bit */
|
2007-01-13 07:30:02 +00:00
|
|
|
regs->psw.cc = VMR_SET(0, regs) ? 3 : 0;
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
/* Check VMR bit to be equal to the first,
|
|
|
|
|
exit with cc1 if an unequal bit found */
|
|
|
|
|
for(n1 = 1; n1 < n; n1++)
|
2007-01-13 07:30:02 +00:00
|
|
|
if((regs->psw.cc == 0) != (VMR_SET(n1, regs) == 0))
|
2001-02-23 20:49:19 +00:00
|
|
|
{
|
2007-01-13 07:30:02 +00:00
|
|
|
regs->psw.cc = 1;
|
2001-02-23 20:49:19 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A641 VCVM - Complement VMR [RRE] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_complement_vmr)
|
|
|
|
|
{
|
|
|
|
|
int unused1, unused2;
|
|
|
|
|
U32 n, n1, n2;
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
RRE(inst, regs, unused1, unused2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
/* Extract vector count (number of active bits in vmr) */
|
|
|
|
|
n = VECTOR_COUNT(regs);
|
|
|
|
|
|
|
|
|
|
/* Bytes - 1 */
|
|
|
|
|
n1 = n >> 3;
|
|
|
|
|
|
|
|
|
|
/* Complement VMR */
|
|
|
|
|
for(n2 = 0; n2 <= n1; n2++)
|
|
|
|
|
regs->vf->vmr[n2] ^= 0xFF;
|
|
|
|
|
|
|
|
|
|
/* zeroize remainder */
|
|
|
|
|
regs->vf->vmr[n1] &= 0x7F00 >> (n & 7);
|
|
|
|
|
for(n1++; n1 < sizeof(regs->vf->vmr); n1++)
|
|
|
|
|
regs->vf->vmr[n1] = 0;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A642 VCZVM - Count Left Zeros in VMR [RRE] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_count_left_zeros_in_vmr)
|
|
|
|
|
{
|
|
|
|
|
int gr1, unused2;
|
|
|
|
|
U32 n, n1;
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
RRE(inst, regs, gr1, unused2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
/* Extract vector count (number of active bits in vmr) */
|
|
|
|
|
n = VECTOR_COUNT(regs);
|
|
|
|
|
|
|
|
|
|
/* cc0 when the vector count is zero */
|
|
|
|
|
if( n == 0)
|
|
|
|
|
{
|
2007-01-13 07:30:02 +00:00
|
|
|
regs->psw.cc = 0;
|
2001-02-23 20:49:19 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Preset condition code according to first bit */
|
2007-01-13 07:30:02 +00:00
|
|
|
regs->psw.cc = VMR_SET(0, regs) ? 3 : 0;
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
/* If the VCT is 1 and the first bit is one
|
|
|
|
|
then exit wirh gr1 set to zero */
|
|
|
|
|
regs->GR_L(gr1) = 0;
|
|
|
|
|
if(n == 1 && VMR_SET(0, regs))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* Count left zeros, set cc1 and exit if a one is found */
|
|
|
|
|
regs->GR_L(gr1) = 1;
|
|
|
|
|
for(n1 = 1; n1 < n; n1++)
|
|
|
|
|
{
|
|
|
|
|
if(!VMR_SET(n1, regs))
|
|
|
|
|
regs->GR_L(gr1)++;
|
|
|
|
|
else
|
|
|
|
|
{
|
2007-01-13 07:30:02 +00:00
|
|
|
regs->psw.cc = 1;
|
2001-02-23 20:49:19 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A643 VCOVM - Count Ones In VMR [RRE] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_count_ones_in_vmr)
|
|
|
|
|
{
|
|
|
|
|
int gr1, unused2;
|
|
|
|
|
U32 n, n1;
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
RRE(inst, regs, gr1, unused2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
/* Extract vector count (number of active bits in vmr) */
|
|
|
|
|
n = VECTOR_COUNT(regs);
|
|
|
|
|
|
|
|
|
|
/* cc0 when the vector count is zero */
|
|
|
|
|
if( n == 0)
|
|
|
|
|
{
|
2007-01-13 07:30:02 +00:00
|
|
|
regs->psw.cc = 0;
|
2001-02-23 20:49:19 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Preset condition code according to first bit */
|
2007-01-13 07:30:02 +00:00
|
|
|
regs->psw.cc = VMR_SET(0, regs) ? 3 : 0;
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
/* Check VMR bit to be equal to the first,
|
|
|
|
|
Count all ones, set cc1 if a bit is unequal */
|
|
|
|
|
regs->GR_L(gr1) = 0;
|
|
|
|
|
for(n1 = 0; n1 < n; n1++)
|
|
|
|
|
{
|
|
|
|
|
if(VMR_SET(n1, regs))
|
|
|
|
|
{
|
|
|
|
|
regs->GR_L(gr1)++;
|
|
|
|
|
if(!VMR_SET(0, regs))
|
2007-01-13 07:30:02 +00:00
|
|
|
regs->psw.cc = 1;
|
2001-02-23 20:49:19 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if(VMR_SET(0, regs))
|
2007-01-13 07:30:02 +00:00
|
|
|
regs->psw.cc = 1;
|
2001-02-23 20:49:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A644 VXVC - Exctract VCT [RRE] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_extract_vct)
|
|
|
|
|
{
|
|
|
|
|
int gr1, unused2;
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
RRE(inst, regs, gr1, unused2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
regs->GR_L(gr1) = VECTOR_COUNT(regs);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A646 VXVMM - Extract Vector Modes [RRE] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_extract_vector_modes)
|
|
|
|
|
{
|
|
|
|
|
int gr1, unused2;
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
RRE(inst, regs, gr1, unused2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
regs->GR_L(gr1) = (regs->vf->vsr >> 48);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A648 VRRS - Restore VR [RRE] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_restore_vr)
|
|
|
|
|
{
|
|
|
|
|
int gr1, unused2;
|
|
|
|
|
U32 n, n1, n2;
|
|
|
|
|
U64 d;
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
RRE(inst, regs, gr1, unused2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
ODD_CHECK(gr1, regs);
|
|
|
|
|
|
|
|
|
|
/* n contrains the current save area address */
|
|
|
|
|
n = regs->GR_L(gr1) & ADDRESS_MAXWRAP(regs);
|
|
|
|
|
|
|
|
|
|
/* n1 contains the starting element number */
|
|
|
|
|
if((n1 = regs->GR_L(gr1 + 1) >> 16) >= VECTOR_SECTION_SIZE)
|
|
|
|
|
ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
|
|
|
|
|
|
|
|
|
|
/* Starting address must be eight times the section size aligned */
|
|
|
|
|
if((n - (8 * n1)) & ((VECTOR_SECTION_SIZE * VSA_ALIGN) - 1) )
|
|
|
|
|
ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
|
|
|
|
|
|
|
|
|
|
/* n2 contains VR pair, which must be an even reg */
|
|
|
|
|
if((n2 = regs->GR_L(gr1 + 1) & 0x0000FFFF) & 0x0000FFF1)
|
|
|
|
|
ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
|
|
|
|
|
|
|
|
|
|
if( VR_INUSE(n2, regs) )
|
|
|
|
|
{
|
|
|
|
|
/* Set the vector changed bit if in problem state */
|
2004-02-17 22:38:48 +00:00
|
|
|
if( PROBSTATE(®s->psw) )
|
2001-02-23 20:49:19 +00:00
|
|
|
SET_VR_CHANGED(n2, regs);
|
|
|
|
|
|
|
|
|
|
for(; n1 < VECTOR_SECTION_SIZE; n1++)
|
|
|
|
|
{
|
|
|
|
|
/* Fetch vr pair from central storage */
|
|
|
|
|
d = ARCH_DEP(vfetch8)(n, gr1, regs);
|
|
|
|
|
regs->vf->vr[n2][n1] = d >> 32;
|
|
|
|
|
regs->vf->vr[n2+1][n1] = d;
|
|
|
|
|
|
|
|
|
|
/* Increment element number */
|
|
|
|
|
n1++;
|
|
|
|
|
regs->GR_L(gr1 + 1) &= 0x0000FFFF;
|
|
|
|
|
regs->GR_L(gr1 + 1) |= n1 << 16;
|
|
|
|
|
/* Update savearea address */
|
|
|
|
|
regs->GR_L(gr1) += 8;
|
|
|
|
|
#if 0
|
|
|
|
|
/* This is where the instruction may be interrupted */
|
2006-12-20 04:26:20 +00:00
|
|
|
UPD_PSW_IA(regs, PSW_IA(regs, -4));
|
2001-02-23 20:49:19 +00:00
|
|
|
return;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Indicate vr pair restored */
|
2007-01-13 07:30:02 +00:00
|
|
|
regs->psw.cc = 2;
|
2001-02-23 20:49:19 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
regs->GR_L(gr1) += 8 * (VECTOR_SECTION_SIZE - n1);
|
|
|
|
|
/* indicate v2 pair not restored */
|
2007-01-13 07:30:02 +00:00
|
|
|
regs->psw.cc = 0;
|
2001-02-23 20:49:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-01-13 07:30:02 +00:00
|
|
|
/* Set 2 if vr 14 is restored, 0 if not restored,
|
|
|
|
|
3 and 1 for other VR's respectively */
|
2001-02-23 20:49:19 +00:00
|
|
|
if(n2 != 14) regs->psw.cc++;
|
|
|
|
|
|
|
|
|
|
/* Update the vector pair number, and zero element number */
|
|
|
|
|
n2 += 2;
|
|
|
|
|
regs->GR_L(gr1 + 1) = n2;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A649 VRSVC - Save Changed VR [RRE] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_save_changed_vr)
|
|
|
|
|
{
|
|
|
|
|
int gr1, unused2;
|
|
|
|
|
U32 n, n1, n2;
|
|
|
|
|
U64 d;
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
RRE(inst, regs, gr1, unused2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
PRIV_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
ODD_CHECK(gr1, regs);
|
|
|
|
|
|
|
|
|
|
/* n contrains the current save area address */
|
|
|
|
|
n = regs->GR_L(gr1) & ADDRESS_MAXWRAP(regs);
|
|
|
|
|
|
|
|
|
|
/* n1 contains the starting element number */
|
|
|
|
|
if((n1 = regs->GR_L(gr1 + 1) >> 16) >= VECTOR_SECTION_SIZE)
|
|
|
|
|
ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
|
|
|
|
|
|
|
|
|
|
/* Starting address must be eight times the section size aligned */
|
|
|
|
|
if((n - (8 * n1)) & ((VECTOR_SECTION_SIZE * VSA_ALIGN) - 1) )
|
|
|
|
|
ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
|
|
|
|
|
|
|
|
|
|
/* n2 contains VR pair, which must be an even reg */
|
|
|
|
|
if((n2 = regs->GR_L(gr1 + 1) & 0x0000FFFF) & 0x0000FFF1)
|
|
|
|
|
ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
|
|
|
|
|
|
|
|
|
|
if( VR_CHANGED(n2, regs) )
|
|
|
|
|
{
|
|
|
|
|
for(; n1 < VECTOR_SECTION_SIZE; n1++)
|
|
|
|
|
{
|
|
|
|
|
/* Store vr pair in savearea */
|
|
|
|
|
d = ((U64)regs->vf->vr[n2][n1] << 32)
|
|
|
|
|
| regs->vf->vr[n2+1][n1];
|
|
|
|
|
ARCH_DEP(vstore8)(d, n, gr1, regs);
|
|
|
|
|
|
|
|
|
|
/* Update element number */
|
|
|
|
|
n1++;
|
|
|
|
|
regs->GR_L(gr1 + 1) &= 0x0000FFFF;
|
|
|
|
|
regs->GR_L(gr1 + 1) |= n1 << 16;
|
|
|
|
|
regs->GR_L(gr1) += 8;
|
|
|
|
|
#if 0
|
|
|
|
|
/* This is where the instruction may be interrupted */
|
2006-12-20 04:26:20 +00:00
|
|
|
UPD_PSW_IA(regs, PSW_IA(regs, -4));
|
2001-02-23 20:49:19 +00:00
|
|
|
return;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Indicate vr pair saved */
|
2007-01-13 07:30:02 +00:00
|
|
|
regs->psw.cc = 2;
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
/* Reset the VR changed bit */
|
|
|
|
|
RESET_VR_CHANGED(n2, regs);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
regs->GR_L(gr1) += 8 * (VECTOR_SECTION_SIZE - n1);
|
|
|
|
|
/* vr pair not saved */
|
2007-01-13 07:30:02 +00:00
|
|
|
regs->psw.cc = 0;
|
2001-02-23 20:49:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-01-13 07:30:02 +00:00
|
|
|
/* Set 2 if vr 14 is restored, 0 if not restored,
|
|
|
|
|
3 and 1 for other VR's respectively */
|
2001-02-23 20:49:19 +00:00
|
|
|
if(n2 != 14) regs->psw.cc++;
|
|
|
|
|
|
|
|
|
|
/* Update the vector pair number, and zero element number */
|
|
|
|
|
n2 += 2;
|
|
|
|
|
regs->GR_L(gr1 + 1) = n2;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A64A VRSV - Save VR [RRE] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_save_vr)
|
|
|
|
|
{
|
|
|
|
|
int gr1, unused2;
|
|
|
|
|
U32 n, n1, n2;
|
|
|
|
|
U64 d;
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
RRE(inst, regs, gr1, unused2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
ODD_CHECK(gr1, regs);
|
|
|
|
|
|
|
|
|
|
/* n contrains the current save area address */
|
|
|
|
|
n = regs->GR_L(gr1) & ADDRESS_MAXWRAP(regs);
|
|
|
|
|
|
|
|
|
|
/* n1 contains the starting element number */
|
|
|
|
|
if((n1 = regs->GR_L(gr1 + 1) >> 16) >= VECTOR_SECTION_SIZE)
|
|
|
|
|
ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
|
|
|
|
|
|
|
|
|
|
/* Starting address must be eight times the section size aligned */
|
|
|
|
|
if((n - (8 * n1)) & ((VECTOR_SECTION_SIZE * VSA_ALIGN) - 1) )
|
|
|
|
|
ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
|
|
|
|
|
|
|
|
|
|
/* n2 contains VR pair, which must be an even reg */
|
|
|
|
|
if((n2 = regs->GR_L(gr1 + 1) & 0x0000FFFF) & 0x0000FFF1)
|
|
|
|
|
ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
|
|
|
|
|
|
|
|
|
|
if( VR_INUSE(n2, regs) )
|
|
|
|
|
{
|
|
|
|
|
for(; n1 < VECTOR_SECTION_SIZE; n1++)
|
|
|
|
|
{
|
|
|
|
|
/* Store vr pair in savearea */
|
|
|
|
|
d = ((U64)regs->vf->vr[n2][n1] << 32)
|
|
|
|
|
| regs->vf->vr[n2+1][n1];
|
|
|
|
|
ARCH_DEP(vstore8)(d, n, gr1, regs);
|
|
|
|
|
|
|
|
|
|
/* Update element number */
|
|
|
|
|
n1++;
|
|
|
|
|
regs->GR_L(gr1 + 1) &= 0x0000FFFF;
|
|
|
|
|
regs->GR_L(gr1 + 1) |= n1 << 16;
|
|
|
|
|
regs->GR_L(gr1) += 8;
|
|
|
|
|
#if 0
|
|
|
|
|
/* This is where the instruction may be interrupted */
|
2006-12-20 04:26:20 +00:00
|
|
|
UPD_PSW_IA(regs, PSW_IA(regs, -4));
|
2001-02-23 20:49:19 +00:00
|
|
|
return;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Indicate vr pair restored */
|
2007-01-13 07:30:02 +00:00
|
|
|
regs->psw.cc = 2;
|
2001-02-23 20:49:19 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
regs->GR_L(gr1) += 8 * (VECTOR_SECTION_SIZE - n1);
|
|
|
|
|
/* Indicate vr pair not restored */
|
2007-01-13 07:30:02 +00:00
|
|
|
regs->psw.cc = 0;
|
2001-02-23 20:49:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-01-13 07:30:02 +00:00
|
|
|
/* Set 2 if vr 14 is restored, 0 if not restored,
|
|
|
|
|
3 and 1 for other VR's respectively */
|
2001-02-23 20:49:19 +00:00
|
|
|
if(n2 != 14) regs->psw.cc++;
|
|
|
|
|
|
|
|
|
|
/* Update the vector pair number, and zero element number */
|
|
|
|
|
n2 += 2;
|
|
|
|
|
regs->GR_L(gr1 + 1) = n2;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A680 VLVM - Load VMR [VS] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_load_vmr)
|
|
|
|
|
{
|
|
|
|
|
int rs2;
|
|
|
|
|
U32 n, n1;
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
VS(inst, regs, rs2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
/* Extract vector count (number of active bits in vmr) */
|
|
|
|
|
n = VECTOR_COUNT(regs);
|
|
|
|
|
n1 = n >> 3;
|
|
|
|
|
|
|
|
|
|
ARCH_DEP(vfetchc)(regs->vf->vmr, n1,
|
|
|
|
|
regs->GR_L(rs2) & ADDRESS_MAXWRAP(regs), rs2, regs);
|
|
|
|
|
|
|
|
|
|
/* Set the inactive bits to zero */
|
|
|
|
|
regs->vf->vmr[n1] &= 0x7F00 >> (n & 7);
|
|
|
|
|
for(n1++; n1 < sizeof(regs->vf->vmr); n1++)
|
|
|
|
|
regs->vf->vmr[n1] = 0;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A681 VLCVM - Load VMR Complement [VS] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_load_vmr_complement)
|
|
|
|
|
{
|
|
|
|
|
int rs2;
|
|
|
|
|
U32 n, n1, n2;
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
VS(inst, regs, rs2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
/* Extract vector count (number of active bits in vmr) */
|
|
|
|
|
n = VECTOR_COUNT(regs);
|
|
|
|
|
|
|
|
|
|
/* Number of bytes - 1 */
|
|
|
|
|
n1 = n >> 3;
|
|
|
|
|
|
|
|
|
|
ARCH_DEP(vfetchc)(regs->vf->vmr, n1,
|
|
|
|
|
regs->GR_L(rs2) & ADDRESS_MAXWRAP(regs), rs2, regs);
|
|
|
|
|
|
|
|
|
|
/* Complement all bits loaded */
|
|
|
|
|
for(n2 = 0; n2 <= n1; n2++)
|
|
|
|
|
regs->vf->vmr[n2] ^= 0xFF;
|
|
|
|
|
|
|
|
|
|
/* Set the inactive bits to zero */
|
|
|
|
|
regs->vf->vmr[n1] &= 0x7F00 >> (n & 7);
|
|
|
|
|
for(n1++; n1 < sizeof(regs->vf->vmr); n1++)
|
|
|
|
|
regs->vf->vmr[n1] = 0;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A682 VSTVM - Store VMR [VS] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_store_vmr)
|
|
|
|
|
{
|
|
|
|
|
int rs2;
|
|
|
|
|
U32 n;
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
VS(inst, regs, rs2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
/* Extract vector count (number of active bits in vmr) */
|
|
|
|
|
n = VECTOR_COUNT(regs);
|
|
|
|
|
|
|
|
|
|
ARCH_DEP(vstorec)(regs->vf->vmr, n >> 3,
|
|
|
|
|
regs->GR_L(rs2) & ADDRESS_MAXWRAP(regs), rs2, regs);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A684 VNVM - AND To VMR [VS] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_and_to_vmr)
|
|
|
|
|
{
|
|
|
|
|
int rs2;
|
|
|
|
|
U32 n, n1, n2;
|
|
|
|
|
BYTE workvmr[VECTOR_SECTION_SIZE/8];
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
VS(inst, regs, rs2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
/* Extract vector count (number of active bits in vmr) */
|
|
|
|
|
n = VECTOR_COUNT(regs);
|
|
|
|
|
|
|
|
|
|
/* Number of bytes - 1 */
|
|
|
|
|
n1 = n >> 3;
|
|
|
|
|
|
|
|
|
|
ARCH_DEP(vfetchc)(workvmr, n1,
|
|
|
|
|
regs->GR_L(rs2) & ADDRESS_MAXWRAP(regs), rs2, regs);
|
|
|
|
|
|
|
|
|
|
/* And VMR with workvmr */
|
|
|
|
|
for(n2 = 0; n2 <= n1; n2++)
|
|
|
|
|
regs->vf->vmr[n2] &= workvmr[n2];
|
|
|
|
|
|
|
|
|
|
/* zeroize remainder */
|
|
|
|
|
regs->vf->vmr[n1] &= 0x7F00 >> (n & 7);
|
|
|
|
|
for(n1++; n1 < sizeof(regs->vf->vmr); n1++)
|
|
|
|
|
regs->vf->vmr[n1] = 0;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A685 VOVM - OR To VMR [VS] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_or_to_vmr)
|
|
|
|
|
{
|
|
|
|
|
int rs2;
|
|
|
|
|
U32 n, n1, n2;
|
|
|
|
|
BYTE workvmr[VECTOR_SECTION_SIZE/8];
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
VS(inst, regs, rs2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
/* Extract vector count (number of active bits in vmr) */
|
|
|
|
|
n = VECTOR_COUNT(regs);
|
|
|
|
|
|
|
|
|
|
/* Number of bytes - 1 */
|
|
|
|
|
n1 = n >> 3;
|
|
|
|
|
|
|
|
|
|
ARCH_DEP(vfetchc)(workvmr, n1,
|
|
|
|
|
regs->GR_L(rs2) & ADDRESS_MAXWRAP(regs), rs2, regs);
|
|
|
|
|
|
|
|
|
|
/* OR VMR with workvmr */
|
|
|
|
|
for(n2 = 0; n2 <= n1; n2++)
|
|
|
|
|
regs->vf->vmr[n2] |= workvmr[n2];
|
|
|
|
|
|
|
|
|
|
/* zeroize remainder */
|
|
|
|
|
regs->vf->vmr[n1] &= 0x7F00 >> (n & 7);
|
|
|
|
|
for(n1++; n1 < sizeof(regs->vf->vmr); n1++)
|
|
|
|
|
regs->vf->vmr[n1] = 0;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A686 VXVM - Exclusive OR To VMR [VS] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_exclusive_or_to_vmr)
|
|
|
|
|
{
|
|
|
|
|
int rs2;
|
|
|
|
|
U32 n, n1, n2;
|
|
|
|
|
BYTE workvmr[VECTOR_SECTION_SIZE/8];
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
VS(inst, regs, rs2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
/* Extract vector count (number of active bits in vmr) */
|
|
|
|
|
n = VECTOR_COUNT(regs);
|
|
|
|
|
|
|
|
|
|
/* Number of bytes - 1 */
|
|
|
|
|
n1 = n >> 3;
|
|
|
|
|
|
|
|
|
|
ARCH_DEP(vfetchc)(workvmr, n1,
|
|
|
|
|
regs->GR_L(rs2) & ADDRESS_MAXWRAP(regs), rs2, regs);
|
|
|
|
|
|
|
|
|
|
/* OR VMR with workvmr */
|
|
|
|
|
for(n2 = 0; n2 <= n1; n2++)
|
|
|
|
|
regs->vf->vmr[n2] ^= workvmr[n2];
|
|
|
|
|
|
|
|
|
|
/* zeroize remainder */
|
|
|
|
|
regs->vf->vmr[n1] &= 0x7F00 >> (n & 7);
|
|
|
|
|
for(n1++; n1 < sizeof(regs->vf->vmr); n1++)
|
|
|
|
|
regs->vf->vmr[n1] = 0;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A6C0 VSRSV - Save VSR [S] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_save_vsr)
|
|
|
|
|
{
|
|
|
|
|
int b2; /* Base of effective addr */
|
2001-03-13 20:37:18 +00:00
|
|
|
VADR effective_addr2; /* Effective address */
|
2001-02-23 20:49:19 +00:00
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
S(inst, regs, b2, effective_addr2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
DW_CHECK(effective_addr2, regs);
|
|
|
|
|
|
|
|
|
|
ARCH_DEP(vstore8)(regs->vf->vsr, effective_addr2, b2, regs);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A6C1 VMRSV - Save VMR [S] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_save_vmr)
|
|
|
|
|
{
|
|
|
|
|
int b2; /* Base of effective addr */
|
2001-03-13 20:37:18 +00:00
|
|
|
VADR effective_addr2; /* Effective address */
|
2001-02-23 20:49:19 +00:00
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
S(inst, regs, b2, effective_addr2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
ARCH_DEP(vstorec)(regs->vf->vmr, sizeof(regs->vf->vmr) - 1,
|
|
|
|
|
effective_addr2, b2, regs);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A6C2 VSRRS - Restore VSR [S] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_restore_vsr)
|
|
|
|
|
{
|
|
|
|
|
int b2; /* Base of effective addr */
|
2001-03-13 20:37:18 +00:00
|
|
|
VADR effective_addr2; /* Effective address */
|
2001-02-23 20:49:19 +00:00
|
|
|
U32 n1, n2;
|
|
|
|
|
U64 d;
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
S(inst, regs, b2, effective_addr2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
DW_CHECK(effective_addr2, regs);
|
|
|
|
|
|
|
|
|
|
/* Fetch operand */
|
|
|
|
|
d = ARCH_DEP(vfetch8)(effective_addr2, b2, regs);
|
|
|
|
|
|
|
|
|
|
/* Check for reserved bits nonzero,
|
|
|
|
|
vector count not greater then section size and
|
|
|
|
|
vector interruption index not greater then section size */
|
|
|
|
|
if((d & VSR_RESV)
|
|
|
|
|
|| ((d & VSR_VCT) >> 32) > VECTOR_SECTION_SIZE
|
|
|
|
|
|| ((d & VSR_VIX) >> 16) >= VECTOR_SECTION_SIZE)
|
|
|
|
|
ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
|
|
|
|
|
|
|
|
|
|
/* In problem state the change bit are set corresponding
|
|
|
|
|
the inuse bits */
|
2004-02-17 22:38:48 +00:00
|
|
|
if(PROBSTATE(®s->psw))
|
2001-02-23 20:49:19 +00:00
|
|
|
{
|
|
|
|
|
d &= ~VSR_VCH;
|
|
|
|
|
d |= (d & VSR_VIU) >> 8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Clear any VRs whose inuse bits are being set to zero */
|
|
|
|
|
for(n1 = 0; n1 < 16; n1 += 2)
|
|
|
|
|
{
|
|
|
|
|
if( VR_INUSE(n1, regs)
|
|
|
|
|
&& !((d & VSR_VIU) & (VSR_VCH0 >> (n1 >> 1))) )
|
|
|
|
|
for(n2 = 0; n2 < VECTOR_SECTION_SIZE; n2++)
|
|
|
|
|
{
|
|
|
|
|
regs->vf->vr[n1][n2] = 0;
|
|
|
|
|
regs->vf->vr[n1+1][n2] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Update the vector status register */
|
|
|
|
|
regs->vf->vsr = d;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A6C3 VMRRS - Restore VMR [S] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_restore_vmr)
|
|
|
|
|
{
|
|
|
|
|
int b2; /* Base of effective addr */
|
2001-03-13 20:37:18 +00:00
|
|
|
VADR effective_addr2; /* Effective address */
|
2001-02-23 20:49:19 +00:00
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
S(inst, regs, b2, effective_addr2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
ARCH_DEP(vfetchc)(regs->vf->vmr, sizeof(regs->vf->vmr) - 1,
|
|
|
|
|
effective_addr2, b2, regs);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A6C4 VLVCA - Load VCT from Address [S] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_load_vct_from_address)
|
|
|
|
|
{
|
|
|
|
|
int b2; /* Base of effective addr */
|
2001-03-13 20:37:18 +00:00
|
|
|
VADR effective_addr2; /* Effective address */
|
2001-02-23 20:49:19 +00:00
|
|
|
U32 n;
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
S_NW(inst, regs, b2, effective_addr2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
2007-01-13 07:30:02 +00:00
|
|
|
regs->psw.cc = ((S32)effective_addr2 == 0) ? 0 :
|
|
|
|
|
((S32)effective_addr2 < 0) ? 1 :
|
|
|
|
|
((S32)effective_addr2 > VECTOR_SECTION_SIZE) ? 2 : 3;
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
n = (S32)effective_addr2 < 0 ? 0 :
|
|
|
|
|
(S32)effective_addr2 > VECTOR_SECTION_SIZE ?
|
|
|
|
|
VECTOR_SECTION_SIZE : (S32)effective_addr2;
|
|
|
|
|
|
|
|
|
|
regs->vf->vsr &= ~VSR_VCT;
|
|
|
|
|
regs->vf->vsr |= (U64)n << 32;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A6C5 VRCL - Clear VR [S] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_clear_vr)
|
|
|
|
|
{
|
|
|
|
|
int b2; /* Base of effective addr */
|
2001-03-13 20:37:18 +00:00
|
|
|
VADR effective_addr2; /* Effective address */
|
2001-02-23 20:49:19 +00:00
|
|
|
U32 n, n1, n2;
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
S(inst, regs, b2, effective_addr2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
/* Set vector interruption index to zero */
|
|
|
|
|
regs->vf->vsr &= ~VSR_VIX;
|
|
|
|
|
|
|
|
|
|
/* Clear vr's identified in the bit mask
|
|
|
|
|
n1 contains the vr number
|
|
|
|
|
n2 contains the bitmask identifying the vr number
|
|
|
|
|
n contains the element number */
|
|
|
|
|
for(n1 = 0, n2 = 0x80; n1 <= 14; n1 += 2, n2 >>= 1)
|
|
|
|
|
if(effective_addr2 & n2)
|
|
|
|
|
{
|
|
|
|
|
for(n = 0; n < VECTOR_SECTION_SIZE; n++)
|
|
|
|
|
{
|
|
|
|
|
regs->vf->vr[n1][n] = 0;
|
|
|
|
|
regs->vf->vr[n1+1][n] = 0;
|
|
|
|
|
}
|
|
|
|
|
RESET_VR_INUSE(n1, regs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A6C6 VSVMM - Set Vector Mask Mode [S] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_set_vector_mask_mode)
|
|
|
|
|
{
|
|
|
|
|
int b2; /* Base of effective addr */
|
2001-03-13 20:37:18 +00:00
|
|
|
VADR effective_addr2; /* Effective address */
|
2001-02-23 20:49:19 +00:00
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
S(inst, regs, b2, effective_addr2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
if(effective_addr2 & 1)
|
|
|
|
|
regs->vf->vsr |= VSR_M;
|
|
|
|
|
else
|
|
|
|
|
regs->vf->vsr &= ~VSR_M;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A6C7 VLVXA - Load VIX from Address [S] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_load_vix_from_address)
|
|
|
|
|
{
|
|
|
|
|
int b2; /* Base of effective addr */
|
2001-03-13 20:37:18 +00:00
|
|
|
VADR effective_addr2; /* Effective address */
|
2001-02-23 20:49:19 +00:00
|
|
|
U32 n;
|
|
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
S_NW(inst, regs, b2, effective_addr2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
2007-01-13 07:30:02 +00:00
|
|
|
regs->psw.cc = ((S32)effective_addr2 == 0) ? 0 :
|
|
|
|
|
((S32)effective_addr2 < 0) ? 1 :
|
|
|
|
|
((S32)effective_addr2 < VECTOR_COUNT(regs)) ? 2 : 3;
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
n = (S32)effective_addr2 < 0 ? 0 :
|
|
|
|
|
(S32)effective_addr2 > VECTOR_SECTION_SIZE ?
|
|
|
|
|
VECTOR_SECTION_SIZE : (S32)effective_addr2;
|
|
|
|
|
|
|
|
|
|
regs->vf->vsr &= ~VSR_VIX;
|
|
|
|
|
regs->vf->vsr |= (U64)n << 16;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A6C8 VSTVP - Store Vector Parameters [S] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_store_vector_parameters)
|
|
|
|
|
{
|
|
|
|
|
int b2; /* Base of effective addr */
|
2001-03-13 20:37:18 +00:00
|
|
|
VADR effective_addr2; /* Effective address */
|
2001-02-23 20:49:19 +00:00
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
S(inst, regs, b2, effective_addr2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
FW_CHECK(effective_addr2, regs);
|
|
|
|
|
|
|
|
|
|
/* Store the section size and partial sum number */
|
|
|
|
|
ARCH_DEP(vstore4)(VECTOR_SECTION_SIZE << 16 | VECTOR_PARTIAL_SUM_NUMBER,
|
|
|
|
|
effective_addr2, b2, regs);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A6CA VACSV - Save VAC [S] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_save_vac)
|
|
|
|
|
{
|
|
|
|
|
int b2; /* Base of effective addr */
|
2001-03-13 20:37:18 +00:00
|
|
|
VADR effective_addr2; /* Effective address */
|
2001-02-23 20:49:19 +00:00
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
S(inst, regs, b2, effective_addr2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
PRIV_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
DW_CHECK(effective_addr2, regs);
|
|
|
|
|
|
|
|
|
|
#if defined(_FEATURE_SIE)
|
2004-02-04 11:49:48 +00:00
|
|
|
if(SIE_STATB(regs, IC3, VACSV))
|
2001-02-23 20:49:19 +00:00
|
|
|
longjmp(regs->progjmp, SIE_INTERCEPT_INST);
|
|
|
|
|
#endif /*defined(_FEATURE_SIE)*/
|
|
|
|
|
|
|
|
|
|
ARCH_DEP(vstore8)(regs->vf->vac, effective_addr2, b2, regs);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
/* A6CB VACRS - Restore VAC [S] */
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
|
DEF_INST(v_restore_vac)
|
|
|
|
|
{
|
|
|
|
|
int b2; /* Base of effective addr */
|
2001-03-13 20:37:18 +00:00
|
|
|
VADR effective_addr2; /* Effective address */
|
2001-02-23 20:49:19 +00:00
|
|
|
|
2004-02-17 22:38:48 +00:00
|
|
|
S(inst, regs, b2, effective_addr2);
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
VOP_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
PRIV_CHECK(regs);
|
|
|
|
|
|
|
|
|
|
DW_CHECK(effective_addr2, regs);
|
|
|
|
|
|
|
|
|
|
#if defined(_FEATURE_SIE)
|
2004-02-04 11:49:48 +00:00
|
|
|
if(SIE_STATB(regs, IC3, VACRS))
|
2001-02-23 20:49:19 +00:00
|
|
|
longjmp(regs->progjmp, SIE_INTERCEPT_INST);
|
|
|
|
|
#endif /*defined(_FEATURE_SIE)*/
|
|
|
|
|
|
|
|
|
|
regs->vf->vac = ARCH_DEP(vfetch8)(effective_addr2, b2, regs) & VAC_MASK;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif /*defined(FEATURE_VECTOR_FACILITY)*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if !defined(_GEN_ARCH)
|
|
|
|
|
|
2001-12-28 09:00:31 +00:00
|
|
|
#if defined(_ARCHMODE2)
|
|
|
|
|
#define _GEN_ARCH _ARCHMODE2
|
|
|
|
|
#include "vector.c"
|
|
|
|
|
#endif
|
2001-02-23 20:49:19 +00:00
|
|
|
|
2001-12-28 09:00:31 +00:00
|
|
|
#if defined(_ARCHMODE3)
|
|
|
|
|
#undef _GEN_ARCH
|
|
|
|
|
#define _GEN_ARCH _ARCHMODE3
|
|
|
|
|
#include "vector.c"
|
|
|
|
|
#endif
|
2001-02-23 20:49:19 +00:00
|
|
|
|
|
|
|
|
#endif /*!defined(_GEN_ARCH)*/
|