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

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <nls.h>

#include <errno.h>
#include <locale.h>

#include <libmpu.h>
#include <mpu-context.h>
#include <mpu-symbols.h>

/* Allocate MPU Context in .tbss segment: */
__thread struct __mpu_context mctx;

/* Share address of mpu_context: */
struct __mpu_context *pmctx;

/* Should be called at start of main thread and at start of each posix threads: */
void __mpu_init( void )
{
  pmctx = &mctx;

  mctx._ierrno = 0;
  mctx._rerrno = 0;
  mctx._cerrno = 0;
  mctx._merrno = 0;
  mctx._ewarns = 0;

  mctx.mflags  = 0;

  pmctx->_cur_brk = (__mpu_void_t *)&((pmctx->_mem)[0]);

#if ENABLE_NLS == 1
  setlocale( LC_ALL, "" );
  bind_textdomain_codeset( PACKAGE, "UTF-8" );
  textdomain( PACKAGE );
#endif
}

/************************************************************************
  User may call the __mpu_free_context() function when needed to
  clear MPU context and all allocated memory resources.

  We do not use __mpu_weak_alias() because the __mpu_weak_alias() macro
  is dedicated to create aliases of external symbols:
 */
#if defined( HAVE_WEAK_SYMBOLS )
void __mpu_free_context( void ) __attribute__ ((weak, alias ("__mpu_init")));
#else
void __mpu_free_context( void ) __attribute__ ((alias ("__mpu_init")));
#endif


static int
__mpu_brk( __mpu_void_t *end_d )
{
  __mpu_void_t  *ptr = __mem;

  if( (__mpu_UNIT_t *)end_d < (__mpu_UNIT_t *)ptr ||
      (__mpu_UNIT_t *)end_d > (__mpu_UNIT_t *)ptr + REGISTERS_MEM_SIZE_IN_UNITS )
  {
    errno = ENOMEM;
    return( -1 );
  }

 /*
   __cur_brk = (__tx_UNIT_t *)end_d;

   Функция  __mpu_brk()  лишь проверяет границы
   области памяти, значение __cur_brk выставляется
   в __mpu_sbrk() .
  *************************************************/

  return( 0 );

} /* End of __mpu_brk() */


__mpu_void_t *
__mpu_sbrk( int incr )
{
  __mpu_void_t  *ptr = __cur_brk;
  register int   rc;

  if( incr == 0 ) return( ptr );

  rc = __mpu_brk( ptr + incr );
  if( rc == -1 )
  {
    /* errno is set into __mpu_brk() */
    return( (__mpu_void_t *)0 );
  }

  __cur_brk = ((__mpu_UNIT_t *)ptr) + (int)incr;

  return( ptr );

} /* End of __mpu_sbrk() */


/***************************************************************
  For external purposes:
 ***************************************************************/
__mpu_error_t *__ptr_integer_error_no( void ) { return( &mctx._ierrno ); }
__mpu_error_t *__ptr_real_error_no   ( void ) { return( &mctx._rerrno ); }
__mpu_error_t *__ptr_complex_error_no( void ) { return( &mctx._cerrno ); }
__mpu_error_t *__ptr_math_error_no   ( void ) { return( &mctx._merrno ); }
__mpu_error_t *__ptr_extra_warnings  ( void ) { return( &mctx._ewarns ); }


void __mpu_clear_iflags( void ) { __CLEAR_IFLAGS; }
void __mpu_clear_rflags( void ) { __CLEAR_RFLAGS; }
void __mpu_clear_mflags( void ) { __CLEAR_MFLAGS; }


int  __mpu_gta( void ) { return __MFLAG( AF ); }
int  __mpu_gtc( void ) { return __MFLAG( CF ); }
int  __mpu_gto( void ) { return __MFLAG( OF ); }
int  __mpu_gts( void ) { return __MFLAG( SF ); }
int  __mpu_gtp( void ) { return __MFLAG( PF ); }
int  __mpu_gtz( void ) { return __MFLAG( ZF ); }
int  __mpu_gtr( void ) { return __MFLAG( RF ); }
int  __mpu_gtv( void ) { return __MFLAG( VF ); }

void __mpu_sta( void ) { __STA; }
void __mpu_stc( void ) { __STC; }
void __mpu_sto( void ) { __STO; }
void __mpu_sts( void ) { __STS; }
void __mpu_stp( void ) { __STP; }
void __mpu_stz( void ) { __STZ; }
void __mpu_str( void ) { __STR; }
void __mpu_stv( void ) { __STV; }

void __mpu_cla( void ) { __CLA; }
void __mpu_clc( void ) { __CLC; }
void __mpu_clo( void ) { __CLO; }
void __mpu_cls( void ) { __CLS; }
void __mpu_clp( void ) { __CLP; }
void __mpu_clz( void ) { __CLZ; }
void __mpu_clr( void ) { __CLR; }
void __mpu_clv( void ) { __CLV; }

void __mpu_cma( void ) { __CMA; }
void __mpu_cmc( void ) { __CMC; }
void __mpu_cmo( void ) { __CMO; }
void __mpu_cms( void ) { __CMS; }
void __mpu_cmp( void ) { __CMP; }
void __mpu_cmz( void ) { __CMZ; }
void __mpu_cmr( void ) { __CMR; }
void __mpu_cmv( void ) { __CMV; }


int  __mpu_gtdom( void ) { return __MFLAG( DOMF ); }
int  __mpu_gtsng( void ) { return __MFLAG( SNGF ); }
int  __mpu_gtovf( void ) { return __MFLAG( OVFF ); }
int  __mpu_gtudf( void ) { return __MFLAG( UDFF ); }
int  __mpu_gttls( void ) { return __MFLAG( TLSF ); }
int  __mpu_gtpls( void ) { return __MFLAG( PLSF ); }
int  __mpu_gtind( void ) { return __MFLAG( INDF ); }
int  __mpu_gtinx( void ) { return __MFLAG( INXF ); }

void __mpu_stdom( void ) { __STDOM; }
void __mpu_stsng( void ) { __STSNG; }
void __mpu_stovf( void ) { __STOVF; }
void __mpu_studf( void ) { __STUDF; }
void __mpu_sttls( void ) { __STTLS; }
void __mpu_stpls( void ) { __STPLS; }
void __mpu_stind( void ) { __STIND; }
void __mpu_stinx( void ) { __STINX; }

void __mpu_cldom( void ) { __CLDOM; }
void __mpu_clsng( void ) { __CLSNG; }
void __mpu_clovf( void ) { __CLOVF; }
void __mpu_cludf( void ) { __CLUDF; }
void __mpu_cltls( void ) { __CLTLS; }
void __mpu_clpls( void ) { __CLPLS; }
void __mpu_clind( void ) { __CLIND; }
void __mpu_clinx( void ) { __CLINX; }

void __mpu_cmdom( void ) { __CMDOM; }
void __mpu_cmsng( void ) { __CMSNG; }
void __mpu_cmovf( void ) { __CMOVF; }
void __mpu_cmudf( void ) { __CMUDF; }
void __mpu_cmtls( void ) { __CMTLS; }
void __mpu_cmpls( void ) { __CMPLS; }
void __mpu_cmind( void ) { __CMIND; }
void __mpu_cminx( void ) { __CMINX; }