/***************************************************************
__MPU_CONTEXT.H
This file contains CONTEXT operation functions & data
declarations.
PART OF : MPU - library .
USAGE : Internal only .
NOTE : Include "libmpu.h" before this FILE .
Copyright (C) 2000 - 2024 by Andrew V.Kosteltsev.
All Rights Reserved.
***************************************************************/
#ifndef __MPU_CONTEXT_H
#define __MPU_CONTEXT_H
#ifdef __cplusplus
extern "C" {
#endif
#define REGISTERS_MEM_SIZE_IN_UNITS 524288
typedef struct __mpu_context mpu_context;
struct __mpu_context
{
__mpu_error_t _ierrno; /* integer errno */
__mpu_error_t _rerrno; /* real errno */
__mpu_error_t _cerrno; /* complex errno */
__mpu_error_t _merrno; /* math errno */
__mpu_error_t _ewarns; /* extra warnings */
__mpu_uint32_t mflags; /* mpu flags register */
__mpu_void_t *_cur_brk;
__mpu_UNIT_t _mem[REGISTERS_MEM_SIZE_IN_UNITS];
};
extern struct __mpu_context *pmctx;
#define __integer_error_no (*(&(pmctx->_ierrno)))
#define __real_error_no (*(&(pmctx->_rerrno)))
#define __complex_error_no (*(&(pmctx->_cerrno)))
#define __math_error_no (*(&(pmctx->_merrno)))
#define __extra_warnings (*(&(pmctx->_ewarns)))
#define __cur_brk (*((__mpu_void_t **)&(pmctx->_cur_brk)))
#define __mem ((__mpu_UNIT_t *)&((pmctx->_mem)[0]))
/***************************************************************
INTEGER OPERATIONS FLAGS:
------------------------
AF - Auxiliary Carry Flag
CF - Carry Flag
OF - Overflow Flag
SF - Sign Flag
PF - Parity Flag (of lowest significant byte)
ZF - Zero Flag
RF - major || remainder
VF - Invalid operation
NOTE: AF, PF are set only by 8-, 16-bit operations.
REAL OPERATIONS FLAGS:
---------------------
DOMF - Domain Flag
SNGF - Singularity Flag
OVFF - Overflow Flag
UDFF - Underflow Flag
TLSF - TLOSS Flag
PLSF - PLOSS Flag
INDF - ind-produsing operation Flag
INXF - Inexact Flag
***************************************************************/
/*
Значения флагов снимаются часто, а опереция log2(mask)
для вычисления сдвига посредством подсчета установленных
битов
SHIFT(flag) = __BITCOUNT((flag ## _MASK)-1)
может занимать время. Поэтому здесь используются явные
значения количества битов на которое надо сдвигать флаг,
чтобы снять его величину.
*/
#define AF_MASK __mpu_UINT32_C( 0x00000001 )
#define CF_MASK __mpu_UINT32_C( 0x00000002 )
#define OF_MASK __mpu_UINT32_C( 0x00000004 )
#define SF_MASK __mpu_UINT32_C( 0x00000008 )
#define PF_MASK __mpu_UINT32_C( 0x00000010 )
#define ZF_MASK __mpu_UINT32_C( 0x00000020 )
#define RF_MASK __mpu_UINT32_C( 0x00000040 )
#define VF_MASK __mpu_UINT32_C( 0x00000080 )
#define AF_SHIFT 0
#define CF_SHIFT 1
#define OF_SHIFT 2
#define SF_SHIFT 3
#define PF_SHIFT 4
#define ZF_SHIFT 5
#define RF_SHIFT 6
#define VF_SHIFT 7
#define DOMF_MASK __mpu_UINT32_C( 0x00000100 )
#define SNGF_MASK __mpu_UINT32_C( 0x00000200 )
#define OVFF_MASK __mpu_UINT32_C( 0x00000400 )
#define UDFF_MASK __mpu_UINT32_C( 0x00000800 )
#define TLSF_MASK __mpu_UINT32_C( 0x00001000 )
#define PLSF_MASK __mpu_UINT32_C( 0x00002000 )
#define INDF_MASK __mpu_UINT32_C( 0x00004000 )
#define INXF_MASK __mpu_UINT32_C( 0x00008000 )
#define DOMF_SHIFT 8
#define SNGF_SHIFT 9
#define OVFF_SHIFT 10
#define UDFF_SHIFT 11
#define TLSF_SHIFT 12
#define PLSF_SHIFT 13
#define INDF_SHIFT 14
#define INXF_SHIFT 15
#define IFLAGS_MASK __mpu_UINT32_C( 0x000000ff )
#define RFLAGS_MASK __mpu_UINT32_C( 0x0000ff00 )
#define MFLAGS_MASK __mpu_UINT32_C( 0x0000ffff )
#if HAVE___BUILTIN_POPCOUNT
#define __BITCOUNT __builtin_popcount
#else
#define __BITCOUNT(x) (((_BX(x)+(_BX(x)>>4)) & 0x0F0F0F0F) % 255)
#define _BX(x) ((x) - (((x)>>1)&0x77777777) \
- (((x)>>2)&0x33333333) \
- (((x)>>3)&0x11111111))
#endif
#if HAVE___BUILTIN_PARITY
#define __PARITY __builtin_parity
#else
#define __PARITY(x) (__BITCOUNT(x) % 2)
#endif
#define __MPARITY(x) (((x)&0xff)?!__PARITY(x):0)
/* All arithmetic flags for store/restore operations: */
#define __MPU_FLAGS (pmctx->mflags)
/* Set, clear, or invert particular flag (by name): */
#define __SET_MFLAG(flag) (pmctx->mflags |= (flag ## _MASK))
#define __CLEAR_MFLAG(flag) (pmctx->mflags &= (~flag ## _MASK))
#define __INVERT_MFLAG(flag) (pmctx->mflags ^= (flag ## _MASK))
#define __MFLAG(flag) ((pmctx->mflags & flag ## _MASK)>>(flag ## _SHIFT))
/* Clear set of integer, relal or all of arithmetic flags: */
#define __CLEAR_IFLAGS (pmctx->mflags &= (~IFLAGS_MASK))
#define __CLEAR_RFLAGS (pmctx->mflags &= (~RFLAGS_MASK))
#define __CLEAR_MFLAGS (pmctx->mflags &= (~MFLAGS_MASK))
#define __CLEAR_IFLAGS_WITHOUT_CARRY (pmctx->mflags &= (~(IFLAGS_MASK & (~CF_MASK))))
/* Set integer flags: */
#define __STA __SET_MFLAG( AF )
#define __STC __SET_MFLAG( CF )
#define __STO __SET_MFLAG( OF )
#define __STS __SET_MFLAG( SF )
#define __STP __SET_MFLAG( PF )
#define __STZ __SET_MFLAG( ZF )
#define __STR __SET_MFLAG( RF )
#define __STV __SET_MFLAG( VF )
/* Clear integer flags: */
#define __CLA __CLEAR_MFLAG( AF )
#define __CLC __CLEAR_MFLAG( CF )
#define __CLO __CLEAR_MFLAG( OF )
#define __CLS __CLEAR_MFLAG( SF )
#define __CLP __CLEAR_MFLAG( PF )
#define __CLZ __CLEAR_MFLAG( ZF )
#define __CLR __CLEAR_MFLAG( RF )
#define __CLV __CLEAR_MFLAG( VF )
/* Complement integer flags: */
#define __CMA __INVERT_MFLAG( AF )
#define __CMC __INVERT_MFLAG( CF )
#define __CMO __INVERT_MFLAG( OF )
#define __CMS __INVERT_MFLAG( SF )
#define __CMP __INVERT_MFLAG( PF )
#define __CMZ __INVERT_MFLAG( ZF )
#define __CMR __INVERT_MFLAG( RF )
#define __CMV __INVERT_MFLAG( VF )
/* Set real flags: */
#define __STDOM __SET_MFLAG( DOMF )
#define __STSNG __SET_MFLAG( SNGF )
#define __STOVF __SET_MFLAG( OVFF )
#define __STUDF __SET_MFLAG( UDFF )
#define __STTLS __SET_MFLAG( TLSF )
#define __STPLS __SET_MFLAG( PLSF )
#define __STIND __SET_MFLAG( INDF )
#define __STINX __SET_MFLAG( INXF )
/* Clear real flags: */
#define __CLDOM __CLEAR_MFLAG( DOMF )
#define __CLSNG __CLEAR_MFLAG( SNGF )
#define __CLOVF __CLEAR_MFLAG( OVFF )
#define __CLUDF __CLEAR_MFLAG( UDFF )
#define __CLTLS __CLEAR_MFLAG( TLSF )
#define __CLPLS __CLEAR_MFLAG( PLSF )
#define __CLIND __CLEAR_MFLAG( INDF )
#define __CLINX __CLEAR_MFLAG( INXF )
/* Complement real flags: */
#define __CMDOM __INVERT_MFLAG( DOMF )
#define __CMSNG __INVERT_MFLAG( SNGF )
#define __CMOVF __INVERT_MFLAG( OVFF )
#define __CMUDF __INVERT_MFLAG( UDFF )
#define __CMTLS __INVERT_MFLAG( TLSF )
#define __CMPLS __INVERT_MFLAG( PLSF )
#define __CMIND __INVERT_MFLAG( INDF )
#define __CMINX __INVERT_MFLAG( INXF )
extern __mpu_void_t *__mpu_sbrk( int incr );
#ifdef __cplusplus
} /* ... extern "C" */
#endif
#endif /* __MPU_CONTEXT_H */