/* VECTOR.C (c) Copyright Jan Jaeger, 1999-2012 */ /* (c) Copyright Roger Bowler, 1999-2012 */ /* 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. */ /* Interpretive Execution - (c) Copyright Jan Jaeger, 1999-2012 */ /* z/Architecture support - (c) Copyright Jan Jaeger, 1999-2012 */ /*-------------------------------------------------------------------*/ /* 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 */ /*-------------------------------------------------------------------*/ #include "hstdinc.h" #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; RRE(inst, regs, unused1, unused2); 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) { regs->psw.cc = 0; return; } /* Preset condition code according to first bit */ regs->psw.cc = VMR_SET(0, regs) ? 3 : 0; /* Check VMR bit to be equal to the first, exit with cc1 if an unequal bit found */ for(n1 = 1; n1 < n; n1++) if((regs->psw.cc == 0) != (VMR_SET(n1, regs) == 0)) { regs->psw.cc = 1; return; } } /*-------------------------------------------------------------------*/ /* A641 VCVM - Complement VMR [RRE] */ /*-------------------------------------------------------------------*/ DEF_INST(v_complement_vmr) { int unused1, unused2; U32 n, n1, n2; RRE(inst, regs, unused1, unused2); 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; RRE(inst, regs, gr1, unused2); 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) { regs->psw.cc = 0; return; } /* Preset condition code according to first bit */ regs->psw.cc = VMR_SET(0, regs) ? 3 : 0; /* 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 { regs->psw.cc = 1; return; } } } /*-------------------------------------------------------------------*/ /* A643 VCOVM - Count Ones In VMR [RRE] */ /*-------------------------------------------------------------------*/ DEF_INST(v_count_ones_in_vmr) { int gr1, unused2; U32 n, n1; RRE(inst, regs, gr1, unused2); 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) { regs->psw.cc = 0; return; } /* Preset condition code according to first bit */ regs->psw.cc = VMR_SET(0, regs) ? 3 : 0; /* 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)) regs->psw.cc = 1; } else if(VMR_SET(0, regs)) regs->psw.cc = 1; } } /*-------------------------------------------------------------------*/ /* A644 VXVC - Exctract VCT [RRE] */ /*-------------------------------------------------------------------*/ DEF_INST(v_extract_vct) { int gr1, unused2; RRE(inst, regs, gr1, unused2); 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; RRE(inst, regs, gr1, unused2); 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; RRE(inst, regs, gr1, unused2); 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 */ if( PROBSTATE(®s->psw) ) 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 */ UPD_PSW_IA(regs, PSW_IA(regs, -4)); return; #endif } /* Indicate vr pair restored */ regs->psw.cc = 2; } else { regs->GR_L(gr1) += 8 * (VECTOR_SECTION_SIZE - n1); /* indicate v2 pair not restored */ regs->psw.cc = 0; } /* Set 2 if vr 14 is restored, 0 if not restored, 3 and 1 for other VR's respectively */ 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; RRE(inst, regs, gr1, unused2); 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 */ UPD_PSW_IA(regs, PSW_IA(regs, -4)); return; #endif } /* Indicate vr pair saved */ regs->psw.cc = 2; /* Reset the VR changed bit */ RESET_VR_CHANGED(n2, regs); } else { regs->GR_L(gr1) += 8 * (VECTOR_SECTION_SIZE - n1); /* vr pair not saved */ regs->psw.cc = 0; } /* Set 2 if vr 14 is restored, 0 if not restored, 3 and 1 for other VR's respectively */ 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; RRE(inst, regs, gr1, unused2); 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 */ UPD_PSW_IA(regs, PSW_IA(regs, -4)); return; #endif } /* Indicate vr pair restored */ regs->psw.cc = 2; } else { regs->GR_L(gr1) += 8 * (VECTOR_SECTION_SIZE - n1); /* Indicate vr pair not restored */ regs->psw.cc = 0; } /* Set 2 if vr 14 is restored, 0 if not restored, 3 and 1 for other VR's respectively */ 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; VS(inst, regs, rs2); 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; VS(inst, regs, rs2); 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; VS(inst, regs, rs2); 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]; VS(inst, regs, rs2); 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]; VS(inst, regs, rs2); 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]; VS(inst, regs, rs2); 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 */ VADR effective_addr2; /* Effective address */ S(inst, regs, b2, effective_addr2); 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 */ VADR effective_addr2; /* Effective address */ S(inst, regs, b2, effective_addr2); 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 */ VADR effective_addr2; /* Effective address */ U32 n1, n2; U64 d; S(inst, regs, b2, effective_addr2); 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 */ if(PROBSTATE(®s->psw)) { 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 */ VADR effective_addr2; /* Effective address */ S(inst, regs, b2, effective_addr2); 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 */ VADR effective_addr2; /* Effective address */ U32 n; S_NW(inst, regs, b2, effective_addr2); VOP_CHECK(regs); regs->psw.cc = ((S32)effective_addr2 == 0) ? 0 : ((S32)effective_addr2 < 0) ? 1 : ((S32)effective_addr2 > VECTOR_SECTION_SIZE) ? 2 : 3; 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 */ VADR effective_addr2; /* Effective address */ U32 n, n1, n2; S(inst, regs, b2, effective_addr2); 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 */ VADR effective_addr2; /* Effective address */ S(inst, regs, b2, effective_addr2); 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 */ VADR effective_addr2; /* Effective address */ U32 n; S_NW(inst, regs, b2, effective_addr2); VOP_CHECK(regs); regs->psw.cc = ((S32)effective_addr2 == 0) ? 0 : ((S32)effective_addr2 < 0) ? 1 : ((S32)effective_addr2 < VECTOR_COUNT(regs)) ? 2 : 3; 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 */ VADR effective_addr2; /* Effective address */ S(inst, regs, b2, effective_addr2); 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 */ VADR effective_addr2; /* Effective address */ S(inst, regs, b2, effective_addr2); VOP_CHECK(regs); PRIV_CHECK(regs); DW_CHECK(effective_addr2, regs); #if defined(_FEATURE_SIE) if(SIE_STATB(regs, IC3, VACSV)) 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 */ VADR effective_addr2; /* Effective address */ S(inst, regs, b2, effective_addr2); VOP_CHECK(regs); PRIV_CHECK(regs); DW_CHECK(effective_addr2, regs); #if defined(_FEATURE_SIE) if(SIE_STATB(regs, IC3, VACRS)) 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) #if defined(_ARCHMODE2) #define _GEN_ARCH _ARCHMODE2 #include "vector.c" #endif #if defined(_ARCHMODE3) #undef _GEN_ARCH #define _GEN_ARCH _ARCHMODE3 #include "vector.c" #endif #endif /*!defined(_GEN_ARCH)*/