Math Processor Unit Library

libmpu – library of arithmetic functions for integer, real, and complex numbers of increased digit capacity

16 Commits   0 Branches   2 Tags

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