Files
org-hyperion-cules/cmpscmem.c
Fish (David B. Trout) d4a1b5e109 New 2012 CMPSC instruction implementation is now the default:
Original/legacy cmpsc.c implementation moved to altcmpsc.dll module.

Refer to Release Notes and/or README.CMPSC documents for more details.
2014-12-29 17:17:01 -08:00

747 lines
24 KiB
C

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