/* CMPSCMEM.C (c) Copyright "Fish" (David B. Trout), 2012-2014 */ /* Compression Call Memory Access Functions */ /* */ /* Released under "The Q Public License Version 1" */ /* (http://www.hercules-390.org/herclic.html) as modifications to */ /* Hercules. */ #include "hstdinc.h" // (MUST be first #include in EVERY source file) #if !defined(_HENGINE_DLL_) #define _HENGINE_DLL_ #endif #if !defined(_CMPSCMEM_C_) #define _CMPSCMEM_C_ #endif #if !defined( NOT_HERC ) // (building Hercules?) #include "hercules.h" #include "opcode.h" #include "inline.h" #endif #include "cmpsc.h" // (Master header) #ifdef FEATURE_COMPRESSION /*-------------------------------------------------------------------*/ /* Fetch a one byte value from operand virtual storage */ /*-------------------------------------------------------------------*/ U8 (CMPSC_FASTCALL ARCH_DEP( cmpsc_vfetchb ))( VADR addr, MEMBLK* pMEMBLK ) { addr &= ADDRESS_MAXWRAP( pMEMBLK->regs ); if (unlikely(!pMEMBLK->maddr[0] || addr < pMEMBLK->vpagebeg)) { pMEMBLK->vpagebeg = (addr & PAGEFRAME_PAGEMASK); pMEMBLK->maddr[1] = 0; pMEMBLK->maddr[0] = MADDR ( pMEMBLK->vpagebeg, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_READ, // (fetch) pMEMBLK->pkey ); } if (MEMBLK_FIRSTPAGE( pMEMBLK, addr )) { return pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK]; } else { if (unlikely(!pMEMBLK->maddr[1])) { pMEMBLK->maddr[1] = MADDR ( pMEMBLK->vpagebeg + PAGEFRAME_PAGESIZE, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_READ, // (fetch) pMEMBLK->pkey ); } return pMEMBLK->maddr[1][addr & PAGEFRAME_BYTEMASK]; } } /*-------------------------------------------------------------------*/ /* Store a one byte value into operand virtual storage */ /*-------------------------------------------------------------------*/ void (CMPSC_FASTCALL ARCH_DEP( cmpsc_vstoreb ))( U8 byt, VADR addr, MEMBLK* pMEMBLK ) { addr &= ADDRESS_MAXWRAP( pMEMBLK->regs ); if (unlikely(!pMEMBLK->maddr[0] || addr < pMEMBLK->vpagebeg)) { pMEMBLK->vpagebeg = (addr & PAGEFRAME_PAGEMASK); pMEMBLK->maddr[1] = 0; pMEMBLK->maddr[0] = MADDR ( pMEMBLK->vpagebeg, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_WRITE, // (store) pMEMBLK->pkey ); } if (MEMBLK_FIRSTPAGE( pMEMBLK, addr )) { pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK] = byt; } else { if (unlikely(!pMEMBLK->maddr[1])) { pMEMBLK->maddr[1] = MADDR ( pMEMBLK->vpagebeg + PAGEFRAME_PAGESIZE, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_WRITE, // (store) pMEMBLK->pkey ); } pMEMBLK->maddr[1][addr & PAGEFRAME_BYTEMASK] = byt; } } /*-------------------------------------------------------------------*/ /* Fetch a two-byte halfword value from operand virtual storage */ /*-------------------------------------------------------------------*/ U16 (CMPSC_FASTCALL ARCH_DEP( cmpsc_vfetch2 ))( VADR addr, MEMBLK* pMEMBLK ) { addr &= ADDRESS_MAXWRAP( pMEMBLK->regs ); if (unlikely(!pMEMBLK->maddr[0] || addr < pMEMBLK->vpagebeg)) { pMEMBLK->vpagebeg = (addr & PAGEFRAME_PAGEMASK); pMEMBLK->maddr[1] = 0; pMEMBLK->maddr[0] = MADDR ( pMEMBLK->vpagebeg, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_READ, // (fetch) pMEMBLK->pkey ); } if (!LASTBYTEOFPAGE( addr )) { if (MEMBLK_FIRSTPAGE( pMEMBLK, addr )) { if (U16_ALIGNED( addr )) return CSWAP16( *(U16*) &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK] ); return fetch_hw( &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK] ); } else { if (unlikely(!pMEMBLK->maddr[1])) { pMEMBLK->maddr[1] = MADDR ( pMEMBLK->vpagebeg + PAGEFRAME_PAGESIZE, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_READ, // (fetch) pMEMBLK->pkey ); } if (U16_ALIGNED( addr )) return CSWAP16( *(U16*) &pMEMBLK->maddr[1][addr & PAGEFRAME_BYTEMASK] ); return fetch_hw( &pMEMBLK->maddr[1][addr & PAGEFRAME_BYTEMASK] ); } } else { if (likely(!pMEMBLK->maddr[1])) { pMEMBLK->maddr[1] = MADDR ( pMEMBLK->vpagebeg + PAGEFRAME_PAGESIZE, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_READ, // (fetch) pMEMBLK->pkey ); } return (((U16) pMEMBLK->maddr[0][PAGEFRAME_BYTEMASK]) << 8) | ((U16) pMEMBLK->maddr[1][0] ); } } /*-------------------------------------------------------------------*/ /* Store a two-byte halfword value into operand virtual storage */ /*-------------------------------------------------------------------*/ void (CMPSC_FASTCALL ARCH_DEP( cmpsc_vstore2 ))( U16 val, VADR addr, MEMBLK* pMEMBLK ) { addr &= ADDRESS_MAXWRAP( pMEMBLK->regs ); if (unlikely(!pMEMBLK->maddr[0] || addr < pMEMBLK->vpagebeg)) { pMEMBLK->vpagebeg = (addr & PAGEFRAME_PAGEMASK); pMEMBLK->maddr[1] = 0; pMEMBLK->maddr[0] = MADDR ( pMEMBLK->vpagebeg, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_WRITE, // (store) pMEMBLK->pkey ); } if (!LASTBYTEOFPAGE( addr )) { if (MEMBLK_FIRSTPAGE( pMEMBLK, addr )) { if (U16_ALIGNED( addr )) *(U16*) &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK] = CSWAP16( val ); else store_hw( &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK], val ); } else { if (unlikely(!pMEMBLK->maddr[1])) { pMEMBLK->maddr[1] = MADDR ( pMEMBLK->vpagebeg + PAGEFRAME_PAGESIZE, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_WRITE, // (store) pMEMBLK->pkey ); } if (U16_ALIGNED( addr )) *(U16*) &pMEMBLK->maddr[1][addr & PAGEFRAME_BYTEMASK] = CSWAP16( val ); else store_hw( &pMEMBLK->maddr[1][addr & PAGEFRAME_BYTEMASK], val ); } } else { if (likely(!pMEMBLK->maddr[1])) { pMEMBLK->maddr[1] = MADDR ( pMEMBLK->vpagebeg + PAGEFRAME_PAGESIZE, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_WRITE, // (store) pMEMBLK->pkey ); } pMEMBLK->maddr[0][PAGEFRAME_BYTEMASK] = (U8)(val >> 8); pMEMBLK->maddr[1][0] = (U8)(val ); } } /*-------------------------------------------------------------------*/ /* Fetch a four-byte fullword value from operand virtual storage */ /*-------------------------------------------------------------------*/ U32 (CMPSC_FASTCALL ARCH_DEP( cmpsc_vfetch4 ))( VADR addr, MEMBLK* pMEMBLK ) { addr &= ADDRESS_MAXWRAP( pMEMBLK->regs ); if (unlikely(!pMEMBLK->maddr[0] || addr < pMEMBLK->vpagebeg)) { pMEMBLK->vpagebeg = (addr & PAGEFRAME_PAGEMASK); pMEMBLK->maddr[1] = 0; pMEMBLK->maddr[0] = MADDR ( pMEMBLK->vpagebeg, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_READ, // (fetch) pMEMBLK->pkey ); } if (NOCROSSPAGE( addr, 4 )) { if (MEMBLK_FIRSTPAGE( pMEMBLK, addr )) { if (U32_ALIGNED( addr )) return CSWAP32( *(U32*) &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK] ); return fetch_fw( &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK] ); } else { if (unlikely(!pMEMBLK->maddr[1])) { pMEMBLK->maddr[1] = MADDR ( pMEMBLK->vpagebeg + PAGEFRAME_PAGESIZE, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_READ, // (fetch) pMEMBLK->pkey ); } if (U32_ALIGNED( addr )) return CSWAP32( *(U32*) &pMEMBLK->maddr[1][addr & PAGEFRAME_BYTEMASK] ); return fetch_fw( &pMEMBLK->maddr[1][addr & PAGEFRAME_BYTEMASK] ); } } else { U32 value; U16 len1 = PAGEFRAME_PAGESIZE - (addr & PAGEFRAME_BYTEMASK); if (likely(!pMEMBLK->maddr[1])) { pMEMBLK->maddr[1] = MADDR ( pMEMBLK->vpagebeg + PAGEFRAME_PAGESIZE, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_READ, // (fetch) pMEMBLK->pkey ); } memcpy( (U8*)&value, &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK], len1 ); memcpy( (U8*)&value + len1, &pMEMBLK->maddr[1][0], 4 - len1 ); return CSWAP32( value ); } } /*-------------------------------------------------------------------*/ /* Store a four-byte fullword value into operand virtual storage */ /*-------------------------------------------------------------------*/ void (CMPSC_FASTCALL ARCH_DEP( cmpsc_vstore4 ))( U32 val, VADR addr, MEMBLK* pMEMBLK ) { addr &= ADDRESS_MAXWRAP( pMEMBLK->regs ); if (unlikely(!pMEMBLK->maddr[0] || addr < pMEMBLK->vpagebeg)) { pMEMBLK->vpagebeg = (addr & PAGEFRAME_PAGEMASK); pMEMBLK->maddr[1] = 0; pMEMBLK->maddr[0] = MADDR ( pMEMBLK->vpagebeg, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_WRITE, // (store) pMEMBLK->pkey ); } if (NOCROSSPAGE( addr, 4 )) { if (MEMBLK_FIRSTPAGE( pMEMBLK, addr )) { if (U32_ALIGNED( addr )) *(U32*) &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK] = CSWAP32( val ); else store_dw( &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK], val ); } else { if (unlikely(!pMEMBLK->maddr[1])) { pMEMBLK->maddr[1] = MADDR ( pMEMBLK->vpagebeg + PAGEFRAME_PAGESIZE, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_WRITE, // (store) pMEMBLK->pkey ); } if (U32_ALIGNED( addr )) *(U32*) &pMEMBLK->maddr[1][addr & PAGEFRAME_BYTEMASK] = CSWAP32( val ); else store_dw( &pMEMBLK->maddr[1][addr & PAGEFRAME_BYTEMASK], val ); } } else { U32 value = CSWAP32( val ); U16 len1 = PAGEFRAME_PAGESIZE - (addr & PAGEFRAME_BYTEMASK); if (likely(!pMEMBLK->maddr[1])) { pMEMBLK->maddr[1] = MADDR ( pMEMBLK->vpagebeg + PAGEFRAME_PAGESIZE, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_WRITE, // (store) pMEMBLK->pkey ); } memcpy( &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK], (U8*)&value, len1 ); memcpy( &pMEMBLK->maddr[1][0], (U8*)&value + len1, 4 - len1 ); } } /*-------------------------------------------------------------------*/ /* Fetch an eight-byte doubleword value from operand virtual storage */ /*-------------------------------------------------------------------*/ U64 (CMPSC_FASTCALL ARCH_DEP( cmpsc_vfetch8 ))( VADR addr, MEMBLK* pMEMBLK ) { addr &= ADDRESS_MAXWRAP( pMEMBLK->regs ); if (unlikely(!pMEMBLK->maddr[0] || addr < pMEMBLK->vpagebeg)) { pMEMBLK->vpagebeg = (addr & PAGEFRAME_PAGEMASK); pMEMBLK->maddr[1] = 0; pMEMBLK->maddr[0] = MADDR ( pMEMBLK->vpagebeg, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_READ, // (fetch) pMEMBLK->pkey ); } if (NOCROSSPAGE( addr, 8 )) { if (MEMBLK_FIRSTPAGE( pMEMBLK, addr )) { if (U64_ALIGNED( addr )) return CSWAP64( *(U64*) &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK] ); return fetch_dw( &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK] ); } else { if (unlikely(!pMEMBLK->maddr[1])) { pMEMBLK->maddr[1] = MADDR ( pMEMBLK->vpagebeg + PAGEFRAME_PAGESIZE, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_READ, // (fetch) pMEMBLK->pkey ); } if (U64_ALIGNED( addr )) return CSWAP64( *(U64*) &pMEMBLK->maddr[1][addr & PAGEFRAME_BYTEMASK] ); return fetch_dw( &pMEMBLK->maddr[1][addr & PAGEFRAME_BYTEMASK] ); } } else { U64 value; U16 len1 = PAGEFRAME_PAGESIZE - (addr & PAGEFRAME_BYTEMASK); if (likely(!pMEMBLK->maddr[1])) { pMEMBLK->maddr[1] = MADDR ( pMEMBLK->vpagebeg + PAGEFRAME_PAGESIZE, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_READ, // (fetch) pMEMBLK->pkey ); } memcpy( (U8*)&value, &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK], len1 ); memcpy( (U8*)&value + len1, &pMEMBLK->maddr[1][0], 8 - len1 ); return CSWAP64( value ); } } /*-------------------------------------------------------------------*/ /* Store an eight-byte doubleword value into operand virtual storage */ /*-------------------------------------------------------------------*/ void (CMPSC_FASTCALL ARCH_DEP( cmpsc_vstore8 ))( U64 val, VADR addr, MEMBLK* pMEMBLK ) { addr &= ADDRESS_MAXWRAP( pMEMBLK->regs ); if (unlikely(!pMEMBLK->maddr[0] || addr < pMEMBLK->vpagebeg)) { pMEMBLK->vpagebeg = (addr & PAGEFRAME_PAGEMASK); pMEMBLK->maddr[1] = 0; pMEMBLK->maddr[0] = MADDR ( pMEMBLK->vpagebeg, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_WRITE, // (store) pMEMBLK->pkey ); } if (NOCROSSPAGE( addr, 8 )) { if (MEMBLK_FIRSTPAGE( pMEMBLK, addr )) { if (U64_ALIGNED( addr )) *(U64*) &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK] = CSWAP64( val ); else store_dw( &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK], val ); } else { if (unlikely(!pMEMBLK->maddr[1])) { pMEMBLK->maddr[1] = MADDR ( pMEMBLK->vpagebeg + PAGEFRAME_PAGESIZE, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_WRITE, // (store) pMEMBLK->pkey ); } if (U64_ALIGNED( addr )) *(U64*) &pMEMBLK->maddr[1][addr & PAGEFRAME_BYTEMASK] = CSWAP64( val ); else store_dw( &pMEMBLK->maddr[1][addr & PAGEFRAME_BYTEMASK], val ); } } else { U64 value = CSWAP64( val ); U16 len1 = PAGEFRAME_PAGESIZE - (addr & PAGEFRAME_BYTEMASK); if (likely(!pMEMBLK->maddr[1])) { pMEMBLK->maddr[1] = MADDR ( pMEMBLK->vpagebeg + PAGEFRAME_PAGESIZE, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_WRITE, // (store) pMEMBLK->pkey ); } memcpy( &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK], (U8*)&value, len1 ); memcpy( &pMEMBLK->maddr[1][0], (U8*)&value + len1, 8 - len1 ); } } /*-------------------------------------------------------------------*/ /* Fetch a 1 to PAGEFRAME_PAGESIZE character operand from virtual */ /* storage; len = size of operand minus 1 */ /*-------------------------------------------------------------------*/ void (CMPSC_FASTCALL ARCH_DEP( cmpsc_vfetchc ))( U8* dst, U16 len, VADR addr, MEMBLK* pMEMBLK ) { addr &= ADDRESS_MAXWRAP( pMEMBLK->regs ); if (unlikely(!pMEMBLK->maddr[0] || addr < pMEMBLK->vpagebeg)) { pMEMBLK->vpagebeg = (addr & PAGEFRAME_PAGEMASK); pMEMBLK->maddr[1] = 0; pMEMBLK->maddr[0] = MADDR ( pMEMBLK->vpagebeg, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_READ, // (fetch) pMEMBLK->pkey ); } if (MEMBLK_FIRSTPAGE( pMEMBLK, addr )) { if (NOCROSSPAGE( addr, len )) { memcpy( dst, &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK], len+1 ); } else { U16 len1 = PAGEFRAME_PAGESIZE - (addr & PAGEFRAME_BYTEMASK); if (likely(!pMEMBLK->maddr[1])) { pMEMBLK->maddr[1] = MADDR ( pMEMBLK->vpagebeg + PAGEFRAME_PAGESIZE, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_READ, // (fetch) pMEMBLK->pkey ); } memcpy( dst, &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK], len1 ); memcpy( (dst + len1), &pMEMBLK->maddr[1][0], len+1 - len1 ); } } else { if (unlikely(!pMEMBLK->maddr[1])) { pMEMBLK->maddr[1] = MADDR ( pMEMBLK->vpagebeg + PAGEFRAME_PAGESIZE, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_READ, // (fetch) pMEMBLK->pkey ); } memcpy( dst, &pMEMBLK->maddr[1][addr & PAGEFRAME_BYTEMASK], len+1 ); } } /*-------------------------------------------------------------------*/ /* Store 1 to PAGEFRAME_PAGESIZE characters into operand virtual */ /* storage; len = size of operand minus 1 */ /*-------------------------------------------------------------------*/ void (CMPSC_FASTCALL ARCH_DEP( cmpsc_vstorec ))( U8* src, U16 len, VADR addr, MEMBLK* pMEMBLK ) { addr &= ADDRESS_MAXWRAP( pMEMBLK->regs ); if (unlikely(!pMEMBLK->maddr[0] || addr < pMEMBLK->vpagebeg)) { pMEMBLK->vpagebeg = (addr & PAGEFRAME_PAGEMASK); pMEMBLK->maddr[1] = 0; pMEMBLK->maddr[0] = MADDR ( pMEMBLK->vpagebeg, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_WRITE, // (store) pMEMBLK->pkey ); } if (MEMBLK_FIRSTPAGE( pMEMBLK, addr )) { if (NOCROSSPAGE( addr, len )) { memcpy( &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK], src, len+1 ); } else { U16 len1 = PAGEFRAME_PAGESIZE - (addr & PAGEFRAME_BYTEMASK); if (likely(!pMEMBLK->maddr[1])) { pMEMBLK->maddr[1] = MADDR ( pMEMBLK->vpagebeg + PAGEFRAME_PAGESIZE, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_WRITE, // (store) pMEMBLK->pkey ); } memcpy( &pMEMBLK->maddr[0][addr & PAGEFRAME_BYTEMASK], src, len1 ); memcpy( pMEMBLK->maddr[1], src + len1, len+1 - len1 ); } } else { if (unlikely(!pMEMBLK->maddr[1])) { pMEMBLK->maddr[1] = MADDR ( pMEMBLK->vpagebeg + PAGEFRAME_PAGESIZE, pMEMBLK->arn, pMEMBLK->regs, ACCTYPE_WRITE, // (store) pMEMBLK->pkey ); } memcpy( &pMEMBLK->maddr[1][addr & PAGEFRAME_BYTEMASK], src, len+1 ); } } /////////////////////////////////////////////////////////////////////////////// // Helper functions to either build CMPSCBLK from information in REGS // or the complete opposite: build the REGS struct from the CMPSCBLK. void (CMPSC_FASTCALL ARCH_DEP( cmpsc_SetREGS ))( CMPSCBLK* pCMPSCBLK, REGS* regs, int r1, int r2 ) { SET_GR_A( r1, regs, (VADR) pCMPSCBLK->pOp1 ); SET_GR_A( r2, regs, (VADR) pCMPSCBLK->pOp2 ); SET_GR_A( r1 + 1, regs, (GREG) pCMPSCBLK->nLen1 ); SET_GR_A( r2 + 1, regs, (GREG) pCMPSCBLK->nLen2 ); regs->psw.cc = pCMPSCBLK->cc; regs->psw.intcode = pCMPSCBLK->pic; /* Register 0 is input-only and thus not modified. SET_GR_A( 0, regs, (0 | ((GREG) zeropad << 17) | ((GREG) pCMPSCBLK->st << 16) | ((GREG) pCMPSCBLK->cdss << 12) | ((GREG) pCMPSCBLK->f1 << 9) | ((GREG) expand << 8) )); */ SET_GR_A( 1, regs, ((GREG) pCMPSCBLK->pDict ) | ((GREG) pCMPSCBLK->stt << 3) | ((GREG) pCMPSCBLK->cbn ) ); } /////////////////////////////////////////////////////////////////////////////// // (same thing but including GR0 too. Used only by utility test tool) #if defined( NOT_HERC ) void (CMPSC_FASTCALL ARCH_DEP( util_cmpsc_SetREGS ))( CMPSCBLK* pCMPSCBLK, REGS* regs, int r1, int r2, U8 expand, U8 zeropad ) { SET_GR_A( r1, regs, (VADR) pCMPSCBLK->pOp1 ); SET_GR_A( r2, regs, (VADR) pCMPSCBLK->pOp2 ); SET_GR_A( r1 + 1, regs, (GREG) pCMPSCBLK->nLen1 ); SET_GR_A( r2 + 1, regs, (GREG) pCMPSCBLK->nLen2 ); regs->psw.cc = pCMPSCBLK->cc; regs->psw.intcode = pCMPSCBLK->pic; /* (for the convenience of the utility testing tool) */ SET_GR_A( 0, regs, (0 | ((GREG) zeropad << 17) | ((GREG) pCMPSCBLK->st << 16) | ((GREG) pCMPSCBLK->cdss << 12) | ((GREG) pCMPSCBLK->f1 << 9) | ((GREG) expand << 8) )); SET_GR_A( 1, regs, ((GREG) pCMPSCBLK->pDict ) | ((GREG) pCMPSCBLK->stt << 3) | ((GREG) pCMPSCBLK->cbn ) ); } #endif // defined( NOT_HERC ) /////////////////////////////////////////////////////////////////////////////// // (same idea but going in the opposite direction) void (CMPSC_FASTCALL ARCH_DEP( cmpsc_SetCMPSC ))( CMPSCBLK* pCMPSCBLK, REGS* regs, int r1, int r2 ) { register GREG GR0, GR1; pCMPSCBLK->r1 = r1; pCMPSCBLK->r2 = r2; pCMPSCBLK->pOp1 = GR_A( r1, regs ); pCMPSCBLK->pOp2 = GR_A( r2, regs ); pCMPSCBLK->nLen1 = GR_A( r1+1, regs ); pCMPSCBLK->nLen2 = GR_A( r2+1, regs ); GR0 = regs->GR_L( 0 ); GR1 = GR_A( 1, regs ); // pCMPSCBLK->e = (GR0 >> 8) & 0x01; // (no such field) pCMPSCBLK->f1 = (GR0 >> 9) & 0x01; pCMPSCBLK->cdss = (GR0 >> 12) & 0x0F; pCMPSCBLK->st = (GR0 >> 16) & 0x01; #if defined(_FEATURE_CMPSC_ENHANCEMENT_FACILITY) if (FACILITY_ENABLED( CMPSC_ENH, regs )) pCMPSCBLK->zp = (GR0 >> 17) & 0x01; else #endif // defined(_FEATURE_CMPSC_ENHANCEMENT_FACILITY) pCMPSCBLK->zp = FALSE; pCMPSCBLK->cbn = (GR1 & 0x007); pCMPSCBLK->stt = (GR1 & 0xFFF) >> 3; pCMPSCBLK->pDict = (GR1 & ~0xFFF); pCMPSCBLK->regs = regs; pCMPSCBLK->cc = regs->psw.cc; pCMPSCBLK->pic = regs->psw.intcode; pCMPSCBLK->nCPUAmt = DEF_CMPSC_CPU_AMT; // pCMPSCBLK->dbg = 0; // (future) } /////////////////////////////////////////////////////////////////////////////// #endif /* FEATURE_COMPRESSION */ #ifndef _GEN_ARCH #ifdef _ARCHMODE2 #define _GEN_ARCH _ARCHMODE2 #include "cmpscmem.c" #endif /* #ifdef _ARCHMODE2 */ #ifdef _ARCHMODE3 #undef _GEN_ARCH #define _GEN_ARCH _ARCHMODE3 #include "cmpscmem.c" #endif /* #ifdef _ARCHMODE3 */ #endif /* #ifndef _GEN_ARCH */