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
author: kx <kx@radix-linux.su> 2024-12-20 16:11:07 +0300 committer: kx <kx@radix-linux.su> 2024-12-20 16:11:07 +0300 commit: 868b2b66b564b5c00e3a74d10be45db7151627ac parent: cce2ae8d3312493b7653358bb4af201d3271377b
Commit Summary:
Version 1.0.14
Diffstat:
1 file changed, 272 insertions, 0 deletions
diff --git a/mpu/mpu-mtherr.c b/mpu/mpu-mtherr.c
new file mode 100644
index 0000000..fd909ce
--- /dev/null
+++ b/mpu/mpu-mtherr.c
@@ -0,0 +1,350 @@
+
+/***************************************************************
+  __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.
+ ***************************************************************/