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