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_MTHERR.C

       This file contains source code of functions for
       MATH ERROR operations.

       PART OF : MPU - library .

       USAGE   : Internal only .

       NOTE    : NONE .

       Copyright (C) 2000 - 2024  by Andrew V.Kosteltsev.
       All Rights Reserved.
 ***************************************************************/

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

#include <nls.h>

#include <errno.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>

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

#include <mpu-math-errno.h>
#include <mpu-strerror.h>
#include <mpu-mtherr.h>

#include <mpu-real.h>


/********************************************************
  INTEGER operations error.
 ********************************************************/
void __integer_invalid_size( __mpu_char8_t *name )
{
  struct __exception  e;

  __integer_error_no = __I_ESIZE__; /* Invalid size of operand(s) */
  __STV; /* Set INTEGER Invalid operation Flag*/

  e.who          = _INTEGER_;
  e.type         = __integer_error_no;
  e.name         = name;
  e.msg          = __mpu_utf8mpu_error( _INTEGER_, __integer_error_no );
  e.msg_type     = _ERROR_MSG_;
  e.nb_a1        = 0;
  e.nb_a2        = 0;
  e.nb_rv        = 0;
  e.arg_1        = (unsigned char *)0;
  e.arg_2        = (unsigned char *)0;
  e.return_value = (unsigned char *)0;

  if( __extra_warnings )
  {
    __mpu_warning( &e );
  }

  if( e.msg ) free( e.msg );

  return;

} /* End of __integer_invalid_size( __mpu_char8_t *name ) */

void __integer_invalid_shift( __mpu_char8_t *name )
{
  struct __exception  e;

  __integer_error_no = __I_ESHIFT__; /* Invalid number of shifts */
  __STV; /* Set INTEGER Invalid operation Flag*/

  e.who          = _INTEGER_;
  e.type         = __integer_error_no;
  e.name         = name;
  e.msg          = __mpu_utf8mpu_error( _INTEGER_, __integer_error_no );
  e.msg_type     = _ERROR_MSG_;
  e.nb_a1        = 0;
  e.nb_a2        = 0;
  e.nb_rv        = 0;
  e.arg_1        = (unsigned char *)0;
  e.arg_2        = (unsigned char *)0;
  e.return_value = (unsigned char *)0;

  if( __extra_warnings )
  {
    __mpu_warning( &e );
  }

  if( e.msg ) free( e.msg );

  return;

} /* End of __integer_invalid_shift( __mpu_char8_t *name ) */

void __integer_invalid_number( __mpu_char8_t *name )
{
  struct __exception  e;

  __integer_error_no = __I_ENUMBER__; /* Invalid number of shifts */
  __STV; /* Set INTEGER Invalid operation Flag*/

  e.who          = _INTEGER_;
  e.type         = __integer_error_no;
  e.name         = name;
  e.msg          = __mpu_utf8mpu_error( _INTEGER_, __integer_error_no );
  e.msg_type     = _ERROR_MSG_;
  e.nb_a1        = 0;
  e.nb_a2        = 0;
  e.nb_rv        = 0;
  e.arg_1        = (unsigned char *)0;
  e.arg_2        = (unsigned char *)0;
  e.return_value = (unsigned char *)0;

  if( __extra_warnings )
  {
    __mpu_warning( &e );
  }

  if( e.msg ) free( e.msg );

  return;

} /* End of __integer_invalid_number( __mpu_char8_t *name ) */

void __integer_invalid_radix( __mpu_char8_t *name )
{
  struct __exception  e;

  __integer_error_no = __I_ERADIX__; /* Invalid number of shifts */
  __STV; /* Set INTEGER Invalid operation Flag*/

  e.who          = _INTEGER_;
  e.type         = __integer_error_no;
  e.name         = name;
  e.msg          = __mpu_utf8mpu_error( _INTEGER_, __integer_error_no );
  e.msg_type     = _ERROR_MSG_;
  e.nb_a1        = 0;
  e.nb_a2        = 0;
  e.nb_rv        = 0;
  e.arg_1        = (unsigned char *)0;
  e.arg_2        = (unsigned char *)0;
  e.return_value = (unsigned char *)0;

  if( __extra_warnings )
  {
    __mpu_warning( &e );
  }

  if( e.msg ) free( e.msg );

  return;

} /* End of __integer_invalid_radix( __mpu_char8_t *name ) */

/********************************************************
  REAL operations error.
 ********************************************************/
void __real_invalid_size( __mpu_char8_t *name )
{
  struct __exception  e;

  __real_error_no = __R_ESIZE__; /* Invalid size of operand(s) */
  __STIND; /* Set REAL ind-produsing operation Flag */

  e.who          = _REAL_;
  e.type         = __real_error_no;
  e.name         = name;
  e.msg          = __mpu_utf8mpu_error( _REAL_, __real_error_no );
  e.msg_type     = _ERROR_MSG_;
  e.nb_a1        = 0;
  e.nb_a2        = 0;
  e.nb_rv        = 0;
  e.arg_1        = (unsigned char *)0;
  e.arg_2        = (unsigned char *)0;
  e.return_value = (unsigned char *)0;

  if( __extra_warnings )
  {
    __mpu_warning( &e );
  }

  if( e.msg ) free( e.msg );

  return;

} /* End of __real_invalid_size( __mpu_char8_t *name ) */

void __real_truncate_error( void )
{
  struct __exception  e;

  __real_error_no = __R_ETRUNC__; /* Invalid number of TRUNC bits(BZ) */
  __STIND; /* Set REAL ind-produsing operation Flag */

  e.who          = _REAL_;
  e.type         = __real_error_no;
  e.name         = (__mpu_char8_t *)"ei_trunc";
  e.msg          = __mpu_utf8mpu_error( _REAL_, __real_error_no );
  e.msg_type     = _ERROR_MSG_;
  e.nb_a1        = 0;
  e.nb_a2        = 0;
  e.nb_rv        = 0;
  e.arg_1        = (unsigned char *)0;
  e.arg_2        = (unsigned char *)0;
  e.return_value = (unsigned char *)0;

  if( __extra_warnings )
  {
    __mpu_warning( &e );
  }

  if( e.msg ) free( e.msg );

  return;

} /* End of __real_truncate_error( void ) */


void _mtherr( EMUSHORT *rc, __mpu_char8_t *name, int type, EMUSHORT *ret_val, EMUSHORT *arg1, EMUSHORT *arg2, int nb )
  /* *rc;      - return code            */
  /* *name;    - name of function       */
  /*  type;    - type of ERROR          */
  /* *ret_val; - internal e-type number */
  /* *arg1;    - internal e-type number */
  /* *arg2;    - internal e-type number */
  /*  nb;      - number of bits         */
{
  __mpu_byte_t        rv[NB_R_MAX],
                      a1[NB_R_MAX],
                      a2[NB_R_MAX];
  int                 n_bytes;
  int                 i;
  struct __exception  e;

  /* ZERO: rv, a1, a2. */
  for( i = 0; i < NB_R_MAX; i++ ) { rv[i]=0; a1[i]=0; a2[i]=0; }

  n_bytes = nb / BITS_PER_BYTE;

  if( n_bytes > NB_R_MAX )
  {
    /* error: Invalid size of operand(s) */
    __real_invalid_size( (__mpu_char8_t *)"_mtherr" );
    _gen_zero( rc, nb );
    return;
  }

  if( (type <= 0) || (type >= __M_MAX_ERRNO) ) type = 0;

  __math_error_no = type;

  e.who           = _MATH_;
  e.type          = type;
  e.name          = name;
  e.msg           = __mpu_utf8mpu_error( _MATH_, type );
  e.msg_type      = _ERROR_MSG_;

  /*
    RETURN VALUE
   **************/
  if( ret_val )
  {
    pack( (EMUSHORT *)rv, ret_val, nb ); 
    e.nb_rv        = n_bytes;
    e.return_value = (unsigned char *)rv;
  }
  else
  {
    e.nb_rv        = 0;
    e.return_value = (unsigned char *)0;
  }
  /*
    ARGUMENT NO _1_
   *****************/
  if( arg1 )
  {
    pack( (EMUSHORT *)a1, arg1, nb ); 
    e.nb_a1 = n_bytes;
    e.arg_1 = (unsigned char *)a1;
  }
  else
  {
    e.nb_a1 = 0;
    e.arg_1 = (unsigned char *)0;
  }
  /*
    ARGUMENT NO _2_
   *****************/
  if( arg2 )
  {
    pack( (EMUSHORT *)a2, arg2, nb ); 
    e.nb_a2 = n_bytes;
    e.arg_2 = (unsigned char *)a2;
  }
  else
  {
    e.nb_a2 = 0;
    e.arg_2 = (unsigned char *)0;
  }

  if( !__mpu_math_error( &e ) )
  {
    /* ERROR NOT TREAT */

    errno = __mpu_math_errnotab[type];

    if( __extra_warnings )
    {
      __mpu_warning( &e );
    }

  } /* End if( !_math_error( &e ) ) */

  if( rc )
  {
    unpack( rc, (EMUSHORT *)e.return_value, nb );
  }

  if( e.msg ) free( e.msg );

} /* End of _mtherr() */


/***************************************************************
  Hide internal symbols:
 ***************************************************************/

__mpu_hidden_decl(__integer_invalid_size);
__mpu_hidden_decl(__integer_invalid_shift);
__mpu_hidden_decl(__integer_invalid_number);
__mpu_hidden_decl(__integer_invalid_radix);
__mpu_hidden_decl(__real_invalid_size);
__mpu_hidden_decl(__real_truncate_error);

__mpu_hidden_decl(_mtherr);


/*
  End of hide internal symbols.
 ***************************************************************/