From 386b7d3366f1359a265da207a9cafa3edf553b64 Mon Sep 17 00:00:00 2001 From: Joshua Bakita Date: Mon, 7 Oct 2019 19:13:39 -0400 Subject: Reorganize and commit all the modified TACLeBench code and run scripts --- baseline/source/ammunition/ChangeLog.txt | 66 ++ baseline/source/ammunition/README | 86 ++ baseline/source/ammunition/ammunition.c | 1185 ++++++++++++++++++++ baseline/source/ammunition/ammunitionTimed.txt | 100 ++ baseline/source/ammunition/ammunition_libc.c | 166 +++ baseline/source/ammunition/ammunition_limits.h | 35 + baseline/source/ammunition/ammunition_stdio.h | 8 + baseline/source/ammunition/ammunition_stdlib.h | 6 + baseline/source/ammunition/ammunition_string.h | 18 + baseline/source/ammunition/arithm.c | 1384 ++++++++++++++++++++++++ baseline/source/ammunition/arithm.h | 123 +++ baseline/source/ammunition/bits.c | 313 ++++++ baseline/source/ammunition/bits.h | 60 + baseline/source/ammunition/gmon.out | Bin 0 -> 31048 bytes baseline/source/ammunition/timeScript | 8 + 15 files changed, 3558 insertions(+) create mode 100644 baseline/source/ammunition/ChangeLog.txt create mode 100644 baseline/source/ammunition/README create mode 100644 baseline/source/ammunition/ammunition.c create mode 100644 baseline/source/ammunition/ammunitionTimed.txt create mode 100644 baseline/source/ammunition/ammunition_libc.c create mode 100644 baseline/source/ammunition/ammunition_limits.h create mode 100644 baseline/source/ammunition/ammunition_stdio.h create mode 100644 baseline/source/ammunition/ammunition_stdlib.h create mode 100644 baseline/source/ammunition/ammunition_string.h create mode 100644 baseline/source/ammunition/arithm.c create mode 100644 baseline/source/ammunition/arithm.h create mode 100644 baseline/source/ammunition/bits.c create mode 100644 baseline/source/ammunition/bits.h create mode 100644 baseline/source/ammunition/gmon.out create mode 100644 baseline/source/ammunition/timeScript (limited to 'baseline/source/ammunition') diff --git a/baseline/source/ammunition/ChangeLog.txt b/baseline/source/ammunition/ChangeLog.txt new file mode 100644 index 0000000..814ed86 --- /dev/null +++ b/baseline/source/ammunition/ChangeLog.txt @@ -0,0 +1,66 @@ +File: ammunition.c +Original provenience: DINO programming language + +2016-03-03: +- Add generic TACLeBench header +- Prefix global functions with benchmark name +- Introduce volatile result variable for return statements +- Split code into ammunition_init and ammunition_main +- Fix compiler warnings "array subscript is of type 'char'": + char => unsigned char +- Fix compiler warnings "'&&' within '||'": + Place additional parentheses +- Remove usages and comments related to the macros + HAVE_MEMMOVE, NDEBUG, HAVE_MEMCMP +- Remove comment related to unused NO_TEMPLATE macro +2016-05-02: +- Change C++ style comments to ISO C90 compliant comments +- Avoid mixing declarations and code: move declaration of variable writePos in + functions ammunition_sprintf_d and ammunition_sprintf_u +- Change datatype in function ammunition_bits_test of iteration variables i and + j from int to unsigned int to avoid comparison between signed and unsigned + integer expressions +- Add forward declarations to ammunition.c +- Introduce variable ammunition_result +- Parantheses around comparison in functions ammunition_isdigit and + ammunition_isspace +- Remove usage of limits.h, move definitions of limits into separate file + ammunition_limits.h +- Remove unconditional assignments of variable result to zero after each test in + functions ammunition_bits_test and ammunition_arithm_test +- Remove unused functions unsigned_integer_maximum, integer_minimum, + integer_maximum, integer_remainder +- Remove unused declaration of function default_arithmetic_overflow_reaction +- Remove unused variables zero_constant_itself, zero_constant +- Remove unused declarations of functions set_unsigned_integer_overflow_reaction + and set_integer_overflow_reaction +- Remove block #ifndef MAX_INTEGER_OPERAND_SIZE, set definition of + MAX_INTEGER_OPERAND_SIZE to 128, since this is default +2016-05-10: +- Integrate new version of arithm library from ammunition repository from + dino repository on github (commit: db9cfab042c332abb234ec8d72750103010981c1), + which hanles arithmetic shifts by negative numbers. This change now makes all + test cases in ammunition.c pass. Update headers unsigned int bits => int bits +- Remove assert statements +- Fix memcmp implementation: dereferencing pointer was missing +- Add loop-bound annotation to memcmp +- Fix strcmp implementation +- Integrate working versions of memcpy and memset from pm benchmark +- Update signature of ammunition_memcpy to original version: + void *memcpy(void *dest, const void *src, size_x n); +- Move functions from libc into separate file, introduce header files + ammunition_limits.h, ammunition_stdio.h, ammunition_stdlib.h, + ammunition_string.h +- Fix overflow in sprintf_d: change datatype of variable 'copyOfNumber' from int + to long, since the negative value of INT_MIN is undefined + 2016-05-17: +- Remove all static declarations of global functions +- Rename variables 'digit_number' to digit_num to keep lines below 80 characters +- Rename op1_digit_number to op1_digit_number and op1_digit_num in function + 'ammunition_multiply_unsigned_integer_without_overflow_reaction' +- Rename variable 'scaled_op1_digit_number' in function + 'ammunition_divide_unsigned_integer_without_overflow_reaction' +- Apply code formatting with astyle + +2017-08-18: +- Add explicit casts to silence g++ warnings. diff --git a/baseline/source/ammunition/README b/baseline/source/ammunition/README new file mode 100644 index 0000000..8caddf4 --- /dev/null +++ b/baseline/source/ammunition/README @@ -0,0 +1,86 @@ +This directory AMMUNITION contains reusable packages on C/C++: +`allocate', `vlobject', `objstack', `hashtab', `commline', `ticker', +`position', `errors', `bits', `arithm', `IEEE': + o allocate + Allocating and freeing memory with automatic fixing some + allocation errors. + o vlobject + Work with variable length objects (VLO). Any number of bytes + may be added to and removed from the end of VLO. If it is + needed the memory allocated for storing variable length object + may be expanded possibly with changing the object place. But + between any additions of the bytes (or tailoring) the object + place is not changed. To decrease number of changes of the + object place the memory being allocated for the object is + longer than the current object length. + o objstack + Work with stacks of objects (OS). Work with the object on the + stack top is analogous to one with a variable length object. + One motivation for the package is the problem of growing char + strings in symbol tables. Memory for OS is allocated by + segments. A segment may contain more one objects. The most + recently allocated segment contains object on the top of OS. + If there is not sufficient free memory for the top object than + new segment is created and the top object is transferred into + the new segment, i.e. there is not any memory reallocation. + Therefore the top object may change its address. But other + objects never change address. + o hashtab + Work with hash tables. The package permits to work + simultaneously with several expandable hash tables. Besides + insertion and search of elements the elements from the hash + tables can be also removed. The table element can be only a + pointer. The size of hash tables is not fixed. The hash + table will be automatically expanded when its occupancy will + became big. + o position + Work with source code positions. The package serves to + support information about source positions of compiled files + taking all included files into account. + o errors + Output of compiler messages. The package serves output + one-pass or multi-pass compiler messages of various modes + (errors, warnings, fatal, system errors and appended messages) + in Unix style or for traditional listing. The package also + permits adequate error reporting for included files. + o commline + Work with command line. The package implements features + analogous to ones of public domain function `getopt'. The + goal of the package creation is to use more readable language + of command line description and to use command line + description as help output of program. + o ticker + Simultaneous work with several tickers (timers). + o bits + Work with bit strings (copying, moving, setting, testing, + comparison). + o arithm + Implementing host machine-independently arbitrary precision + integer numbers arithmetic. The implementation of the package + functions are not sufficiently efficient in order to use for + run-time. The package functions are oriented to implement + constant-folding in compilers, cross-compilers. + o IEEE + Implementing host machine-independently IEEE floating point + arithmetic. The implementation of the package functions are + not sufficiently efficient in order to use for run-time. The + package functions are oriented to implement constant-folding + in compilers, cross-compilers. + + There are files with corresponding names and extensions `.h' +(interface file for C/C++), `.c' (implementation file on C), and +`.cpp' (implementation file on C++). + + To install AMMUNITION see file INSTALL in the current directory. + + There are also shell scripts for testing the package with +corresponding names and extension `.tst'. Documentation of the +reusable packages is in files `ammunition.txt', `ammunition.dvi', +`ammunition.ps', `ammunition.info*', `ammunition*.html', +`ammunition*.rtf' for C and `ammunition++.txt', `ammunition++.dvi', +`ammunition++.ps', `ammunition++.info*', `ammunition++*.html', +`ammunition++*.rtf'. + +Please send bug reports and comments to vmakarov@fnmail.com + +Vladimir Makarov diff --git a/baseline/source/ammunition/ammunition.c b/baseline/source/ammunition/ammunition.c new file mode 100644 index 0000000..224babd --- /dev/null +++ b/baseline/source/ammunition/ammunition.c @@ -0,0 +1,1185 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: ammunition + + Author: Vladimir Makarov + + Function: Tests reusable packages bits and arith + bits: Work with bit strings (copying, moving, setting, testing, comparison). + arith: Implementing host machine-independently arbitrary precision integer + numbers arithmetic. The implementation of the package functions are not + sufficiently efficient in order to use for run-time. The package + functions are oriented to implement constant-folding in compilers, + cross-compilers. + + Source: DINO programming language repository + https://github.com/dino-lang/dino/ + + Changes: no major functional changes + + License: GPL 2 and LGPL 2 + +*/ + +#include "../extra.h" +#include "bits.h" +#include "arithm.h" +#include "ammunition_stdlib.h" +#include "ammunition_stdio.h" +#include "ammunition_string.h" + +/* + Forward declaration of functions +*/ + +void ammunition_reset_str_bits( char *str, char *s ); +void ammunition_reset_str_arithm( char *str, char *s, char *d, char *e, + char *g ); +int ammunition_bits_test(); +int ammunition_arithm_test(); +void ammunition_init( void ); +int ammunition_return( void ); +void ammunition_main( void ); +//int main( void ); + + +/* + Forward declaration of global variables +*/ + +int ammunition_result; + + +/* + Core functions +*/ + +void ammunition_reset_str_bits( char *str, char *s ) +{ + int i; + _Pragma( "loopbound min 8 max 8" ) + for ( i = 0; i < 8; i++ ) { + str[i] = 0; + s[i] = 0; + } +} + + +void ammunition_reset_str_arithm( char *str, char *s, char *d, char *e, + char *g ) +{ + int i; + _Pragma( "loopbound min 20 max 20" ) + for ( i = 0; i < 20; i++ ) { + str[i] = 0; + s[i] = 0; + } + + _Pragma( "loopbound min 4 max 4" ) + for ( i = 0; i < 4; i++ ) { + d[i] = 0; + e[i] = 0; + } + + _Pragma( "loopbound min 6 max 6" ) + for ( i = 0; i < 6; i++ ) + g[i] = 0; +} + + +int ammunition_bits_test() +{ + char str[8]; + char str1[8]; + + int result = 0; + unsigned int i, j; + + /* Test 1 */ + ammunition_reset_str_bits( str, str1 ); + + _Pragma( "loopbound min 64 max 64" ) + for ( i = 0; i < sizeof ( str ) * CHAR_BIT; i++ ) { + if ( BIT ( str, i ) ) + result = 1; + } + + _Pragma( "loopbound min 64 max 64" ) + for ( i = 0; i < sizeof ( str ) * CHAR_BIT; i++ ) { + SET_BIT ( str, i, 1 ); + _Pragma( "loopbound min 64 max 64" ) + for ( j = 0; j < sizeof ( str ) * CHAR_BIT; j++ ) + if ( j <= i ) { + if ( BIT ( str, j ) == 0 ) + result = 1; + } else + if ( BIT ( str, j ) ) + result = 1; + } + + /* Test 2 */ + ammunition_reset_str_bits( str, str1 ); + + _Pragma( "loopbound min 64 max 64" ) + for ( i = 0; i < sizeof ( str ) * CHAR_BIT; i++ ) + if ( !ammunition_is_zero_bit_string ( + str, i, ( sizeof ( str ) * CHAR_BIT - i ) / 2 + 1 ) ) + result = 1; + ammunition_bit_string_set ( str, 13, 1, 35 ); + _Pragma( "loopbound min 13 max 13" ) + for ( i = 0; i < 13; i++ ) + if ( !ammunition_is_zero_bit_string ( str, i, 13 - i ) ) + result = 1; + _Pragma( "loopbound min 35 max 35" ) + for ( i = 13; i < 48; i++ ) + if ( ammunition_is_zero_bit_string ( str, i, 48 - i ) ) + result = 1; + _Pragma( "loopbound min 16 max 16" ) + for ( i = 48; i < sizeof ( str ) * CHAR_BIT; i++ ) + if ( !ammunition_is_zero_bit_string ( str, i, + sizeof ( str ) * CHAR_BIT - i ) ) + result = 1; + + /* Test 3 */ + ammunition_reset_str_bits( str, str1 ); + + _Pragma( "loopbound min 42 max 42" ) + for ( i = 0; i + i / 2 + 1 < sizeof ( str ) * CHAR_BIT; i++ ) { + ammunition_bit_string_set ( str, i, 1, i / 2 + 1 ); + if ( !ammunition_is_zero_bit_string ( str, 0, i - 1 ) ) + result = 1; + if ( ammunition_is_zero_bit_string ( str, i, i / 2 + 1 ) ) + result = 1; + if ( !ammunition_is_zero_bit_string ( + str, i + i / 2 + 1, sizeof ( str ) * CHAR_BIT - ( i + i / 2 + 1 ) ) ) + result = 1; + ammunition_bit_string_set ( str, 0, 0, sizeof ( str ) * CHAR_BIT ); + } + + /* Test 4 */ + ammunition_reset_str_bits( str, str1 ); + + ammunition_bit_string_set ( str, 2, 1, 43 ); + ammunition_bit_string_set ( str1, 2, 1, 40 ); + _Pragma( "loopbound min 42 max 42" ) + for ( i = 0; i < 42; i++ ) + if ( ammunition_bit_string_comparison ( str, i, str1, i, 42 - i ) != 0 ) + result = 1; + _Pragma( "loopbound min 43 max 43" ) + for ( i = 0; i < 43; i++ ) + if ( ammunition_bit_string_comparison ( str, i, str1, i, + sizeof ( str ) * CHAR_BIT - i ) + <= 0 ) + result = 1; + _Pragma( "loopbound min 43 max 43" ) + for ( i = 0; i < 43; i++ ) + if ( ammunition_bit_string_comparison ( str1, i, str, i, + sizeof ( str ) * CHAR_BIT - i ) + >= 0 ) + result = 1; + + /* Test 5 */ + ammunition_reset_str_bits( str, str1 ); + + ammunition_bit_string_set ( str, 2, 1, 43 ); + _Pragma( "loopbound min 59 max 59" ) + for ( i = 0; i + 5 < sizeof ( str ) * CHAR_BIT; i++ ) { + ammunition_bit_string_copy ( str1, i + 5, str, i, + sizeof ( str ) * CHAR_BIT - i - 5 ); + if ( ammunition_bit_string_comparison ( + str1, i + 5, str, i, sizeof ( str ) * CHAR_BIT - i - 5 ) != 0 ) + result = 1; + } + + /* Test 6 */ + ammunition_reset_str_bits( str, str1 ); + + ammunition_bit_string_set ( str, 2, 1, 43 ); + ammunition_bit_string_set ( str1, 2, 1, 43 ); + _Pragma( "loopbound min 59 max 59" ) + for ( i = 0; i + 5 < sizeof ( str ) * CHAR_BIT; i++ ) { + ammunition_bit_string_set ( str, 0, 0, sizeof ( str ) * CHAR_BIT ); + ammunition_bit_string_set ( str, 2, 1, 43 ); + ammunition_bit_string_move ( str, i + 5, str, i, + sizeof ( str ) * CHAR_BIT - i - 5 ); + if ( ammunition_bit_string_comparison ( + str, i + 5, str1, i, sizeof ( str ) * CHAR_BIT - i - 5 ) != 0 ) + result = 1; + } + + /* Test 7 */ + ammunition_reset_str_bits( str, str1 ); + + ammunition_bit_string_set ( str, 2, 1, 43 ); + ammunition_bit_string_set ( str1, 2, 1, 43 ); + _Pragma( "loopbound min 59 max 59" ) + for ( i = 0; i + 5 < sizeof ( str ) * CHAR_BIT; i++ ) { + ammunition_bit_string_set ( str, 0, 0, sizeof ( str ) * CHAR_BIT ); + ammunition_bit_string_set ( str, 2, 1, 43 ); + ammunition_bit_string_move ( str, i, str, i + 5, + sizeof ( str ) * CHAR_BIT - i - 5 ); + if ( ammunition_bit_string_comparison ( + str, i, str1, i + 5, sizeof ( str ) * CHAR_BIT - i - 5 ) != 0 ) + result = 1; + } + + return result; +} + + +int ammunition_arithm_test() +{ + int result = 0; + + /* Test 1 */ + int i; + char str [20], s[20], d[4], e[4], g[6]; + + ammunition_integer_from_string ( 4, "-2147483649", d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_d( str, INT_MIN ); + ammunition_integer_from_string ( 4, str, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "2147483648", d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_d( str, INT_MAX ); + ammunition_integer_from_string ( 4, str, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = -2000; i < 2000 ; i++ ) { + ammunition_sprintf_d( str, i ); + ammunition_integer_from_string ( 4, str, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + } + + /* Test 2 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "4294967296", d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_u( str, UINT_MAX ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = 0; i < 4000 ; i++ ) { + ammunition_sprintf_u( str, i ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + } + + /* Test 3 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_sprintf_d( str, INT_MAX ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_integer_from_string ( 4, "1", e ); + ammunition_add_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_d( str, INT_MAX - 4 ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, 4 ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_add_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + ammunition_sprintf_d( str, INT_MAX ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = -2000; i < 2000 ; i++ ) { + ammunition_sprintf_d( str, i ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, i + 1 ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_add_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_atoi ( s ) != i + i + 1 ) + result = 1; + } + + /* Test 4 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_sprintf_u( str, UINT_MAX ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_unsigned_integer_from_string ( 4, "1", e ); + ammunition_add_unsigned_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_u( str, UINT_MAX - 4 ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, 4 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_add_unsigned_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + ammunition_sprintf_u( str, UINT_MAX ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = 0; i < 4000 ; i++ ) { + ammunition_sprintf_u( str, i ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, i + 1 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_add_unsigned_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_atoi ( s ) != i + i + 1 ) + result = 1; + } + + /* Test 5 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_sprintf_d( str, INT_MIN ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_integer_from_string ( 4, "1", e ); + ammunition_subtract_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_d( str, INT_MIN + 4 ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, 4 ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_subtract_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + ammunition_sprintf_d( str, INT_MIN ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = -2000; i < 2000 ; i++ ) { + ammunition_sprintf_d( str, i ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, 10 - i ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_subtract_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_atoi ( s ) != i + i - 10 ) + result = 1; + } + + /* Test 6 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_sprintf_u( str, UINT_MAX - 2 ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, UINT_MAX - 1 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_subtract_unsigned_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_u( str, UINT_MAX ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_subtract_unsigned_integer ( 4, d, d, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = 0; i < 4000 ; i++ ) { + ammunition_sprintf_u( str, i ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, i / 2 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_subtract_unsigned_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_atoi ( s ) != i - i / 2 ) + result = 1; + } + + /* Test 7 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_sprintf_d( str, INT_MAX / 2 + 1 ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_integer_from_string ( 4, "2", e ); + ammunition_multiply_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_d( str, INT_MIN / 2 - 1 ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_integer_from_string ( 4, "2", e ); + ammunition_multiply_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_d( str, INT_MAX / 3 ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, 3 ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_multiply_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + ammunition_sprintf_d( str, ( INT_MAX / 3 ) * 3 ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + ammunition_sprintf_d( str, INT_MIN / 2 ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, 2 ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_multiply_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + ammunition_sprintf_d( str, ( INT_MIN / 2 ) * 2 ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = -2000; i < 2000 ; i++ ) { + ammunition_sprintf_d( str, i ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, i + 1000 ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_multiply_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_atoi ( s ) != i * ( i + 1000 ) ) + result = 1; + } + + /* Test 8 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_sprintf_u( str, UINT_MAX / 5 + 1 ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, 5 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_multiply_unsigned_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_u( str, UINT_MAX / 2 ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, 2 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_multiply_unsigned_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + ammunition_sprintf_u( str, ( UINT_MAX / 2 ) * 2 ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = 0; i < 4000 ; i++ ) { + ammunition_sprintf_u( str, i ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, i / 2 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_multiply_unsigned_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_atoi ( s ) != i * ( i / 2 ) ) + result = 1; + } + + /* Test 9 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "10", d ); + ammunition_integer_from_string ( 4, "0", e ); + ammunition_divide_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = -2000; i < 2000 ; i++ ) { + ammunition_sprintf_d( str, i ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, ( i < 0 ? - i / 20 + 1 : - i / 20 - 1 ) ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_divide_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_atoi ( s ) != i / ( i < 0 ? - i / 20 + 1 : - i / 20 - 1 ) ) + result = 1; + ammunition_sprintf_d( str, i ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_divide_integer ( 4, d, e, e ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_atoi ( s ) != i / ( i < 0 ? - i / 20 + 1 : - i / 20 - 1 ) ) + result = 1; + } + + /* Test 10 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "0", e ); + ammunition_divide_unsigned_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = 0; i < 4000 ; i++ ) { + ammunition_sprintf_u( str, i ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, i / 20 + 1 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_divide_unsigned_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_atoi ( s ) != i / ( i / 20 + 1 ) ) + result = 1; + } + + /* Test 11 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "0", e ); + ammunition_unsigned_integer_remainder ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = 0; i < 4000 ; i++ ) { + ammunition_sprintf_u( str, i ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, i / 20 + 1 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_unsigned_integer_remainder ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_atoi ( s ) != i % ( i / 20 + 1 ) ) + result = 1; + } + + /* Test 12 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_shift_right ( 4, d, 0, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_shift_right ( 4, d, 32, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_shift_right ( 4, d, 8, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "5" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "134890", d ); + ammunition_unsigned_integer_shift_right ( 4, d, 13, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "16" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "134890", d ); + ammunition_unsigned_integer_shift_left ( 4, d, -13, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "16" ) != 0 ) + result = 1; + + /* Test 13 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_shift_right ( 4, d, 0, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_shift_right ( 4, d, 32, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_shift_right ( 4, d, 8, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "5" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "134890", d ); + ammunition_integer_shift_right ( 4, d, 13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "16" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "134890", d ); + ammunition_integer_shift_left ( 4, d, -13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "16" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_shift_right ( 4, d, 0, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_shift_right ( 4, d, 32, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "-1" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_shift_right ( 4, d, 8, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "-6" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-134890", d ); + ammunition_integer_shift_right ( 4, d, 13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "-17" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-134890", d ); + ammunition_integer_shift_left ( 4, d, -13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "-17" ) != 0 ) + result = 1; + + /* Test 14 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_shift_left ( 4, d, 0, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_shift_left ( 4, d, 22, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_shift_left ( 4, d, 8, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "345088" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "134890", d ); + ammunition_unsigned_integer_shift_left ( 4, d, 13, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1105018880" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "134890", d ); + ammunition_unsigned_integer_shift_right ( 4, d, -13, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1105018880" ) != 0 ) + result = 1; + + /* Test 15 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_shift_left ( 4, d, 0, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_shift_left ( 4, d, 21, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_shift_left ( 4, d, 8, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "345088" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "134890", d ); + ammunition_integer_shift_left ( 4, d, 13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1105018880" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "134890", d ); + ammunition_integer_shift_right ( 4, d, -13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1105018880" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_shift_left ( 4, d, 0, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_shift_left ( 4, d, 21, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_shift_left ( 4, d, 8, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-345088" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-134890", d ); + ammunition_integer_shift_left ( 4, d, 13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-1105018880" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-134890", d ); + ammunition_integer_shift_right ( 4, d, -13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-1105018880" ) != 0 ) + result = 1; + + /* Test 16 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "-10", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( ammunition_eq_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( !ammunition_eq_integer ( 4, d, e ) ) + result = 1; + + /* Test 17 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_eq_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_eq_unsigned_integer ( 4, d, e ) ) + result = 1; + + /* Test 18 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "-10", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( !ammunition_ne_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( ammunition_ne_integer ( 4, d, e ) ) + result = 1; + + /* Test 19 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_ne_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_ne_unsigned_integer ( 4, d, e ) ) + result = 1; + + /* Test 20 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "-10", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( ammunition_gt_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( ammunition_gt_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1000000", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( ammunition_gt_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "1000000", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( !ammunition_gt_integer ( 4, d, e ) ) + result = 1; + + /* Test 21 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_gt_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_gt_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1000000", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_gt_unsigned_integer ( 4, d, e ) ) + result = 1; + + /* Test 22 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "-10", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( !ammunition_lt_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( ammunition_lt_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1000000", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( !ammunition_lt_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "1000000", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( ammunition_lt_integer ( 4, d, e ) ) + result = 1; + + /* Test 23 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_lt_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_lt_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1000000", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_lt_unsigned_integer ( 4, d, e ) ) + result = 1; + + /* Test 24 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "-10", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( ammunition_ge_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( !ammunition_ge_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1000000", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( ammunition_ge_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "1000000", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( !ammunition_ge_integer ( 4, d, e ) ) + result = 1; + + /* Test 25 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_ge_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_ge_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1000000", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_ge_unsigned_integer ( 4, d, e ) ) + result = 1; + + /* Test 26 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "-10", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( !ammunition_le_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( !ammunition_le_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1000000", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( !ammunition_le_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "1000000", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( ammunition_le_integer ( 4, d, e ) ) + result = 1; + + /* Test 27 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_le_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_le_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1000000", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_le_unsigned_integer ( 4, d, e ) ) + result = 1; + + /* Test 28 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "70000", d ); + ammunition_change_unsigned_integer_size ( 4, d, 2, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "30000", d ); + ammunition_change_unsigned_integer_size ( 4, d, 2, d ); + ammunition_integer_to_string( 2, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "30000" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "11230000", g ); + ammunition_change_unsigned_integer_size ( 4, g, 6, g ); + ammunition_integer_to_string( 6, g, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "11230000" ) != 0 ) + result = 1; + + /* Test 29 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "40000", d ); + ammunition_change_integer_size ( 4, d, 2, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_integer_from_string ( 4, "-33000", d ); + ammunition_change_integer_size ( 4, d, 2, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_integer_from_string ( 4, "30000", d ); + ammunition_change_integer_size ( 4, d, 2, d ); + ammunition_integer_to_string( 2, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "30000" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-30000", d ); + ammunition_change_integer_size ( 4, d, 2, d ); + ammunition_integer_to_string( 2, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-30000" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "11230000", g ); + ammunition_change_integer_size ( 4, g, 6, g ); + ammunition_integer_to_string( 6, g, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "11230000" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-11230000", g ); + ammunition_change_integer_size ( 4, g, 6, g ); + ammunition_integer_to_string( 6, g, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-11230000" ) != 0 ) + result = 1; + + /* Test 30 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + ammunition_unsigned_integer_or ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "0", e ); + ammunition_unsigned_integer_or ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "4294967295", e ); + ammunition_unsigned_integer_or ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "4294967295" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "96", e ); + ammunition_unsigned_integer_or ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "1380" ) != 0 ) + result = 1; + + /* Test 31 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "1348", e ); + ammunition_integer_or ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "0", e ); + ammunition_integer_or ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "-1", e ); + ammunition_integer_or ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "-1" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "96", e ); + ammunition_integer_or ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "1380" ) != 0 ) + result = 1; + + /* Test 32 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + ammunition_unsigned_integer_and ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "0", e ); + ammunition_unsigned_integer_and ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "4294967295", e ); + ammunition_unsigned_integer_and ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "96", e ); + ammunition_unsigned_integer_and ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "64" ) != 0 ) + result = 1; + + /* Test 33 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "1348", e ); + ammunition_integer_and ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "0", e ); + ammunition_integer_and ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "-1", e ); + ammunition_integer_and ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "96", e ); + ammunition_integer_and ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "64" ) != 0 ) + result = 1; + + /* Test 34 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_not ( 4, d, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_strcmp ( s, "4294965947" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "0", d ); + ammunition_unsigned_integer_not ( 4, d, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_strcmp ( s, "4294967295" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "4294967295", d ); + ammunition_unsigned_integer_not ( 4, d, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + + /* Test 35 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_not ( 4, d, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_strcmp ( s, "-1349" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "0", d ); + ammunition_integer_not ( 4, d, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_strcmp ( s, "-1" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-1", d ); + ammunition_integer_not ( 4, d, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + + return result; +} + + +/* + Initialization- and return-value-related functions +*/ + +void ammunition_init( void ) +{ + ammunition_result = 0; +} + +int ammunition_return( void ) +{ + return ammunition_result; +} + +/* + Main functions +*/ + +void _Pragma( "entrypoint" ) ammunition_main( void ) +{ + ammunition_result |= ammunition_bits_test(); + ammunition_result |= ammunition_arithm_test(); +} + + +int main( int argc, char **argv ) +{ + SET_UP + for (jobsComplete=-1; jobsComplete= '0' ) & ( c <= '9' ) ) + return 1; + else + return 0; +} + +int ammunition_isspace( int c ) +{ + return ( c == ' ' ) | ( c == '\t' ) | ( c == '\n' ) | ( c == '\r' ); +} + +void *ammunition_memcpy( void *dest, const void *src, size_x size ) +{ + size_x i; + _Pragma( "loopbound min 2 max 6" ) + for ( i = 0; i < size; i++ ) + ( ( unsigned char * )dest )[i] = ( ( unsigned char * )src )[i]; + + return dest; +} + + +void *ammunition_memset( void *s, int c, size_x n ) +{ + size_x i; + _Pragma( "loopbound min 0 max 4" ) + for ( i = 0; i < n; i++ ) + ( ( unsigned char * )s )[i] = ( unsigned char )c; + + return s; +} + + +int ammunition_memcmp ( const void *mem1, const void *mem2, size_x size ) +{ + const unsigned char *p1 = (const unsigned char *) mem1, + *p2 = (const unsigned char *) mem2; + _Pragma( "loopbound min 0 max 4" ) + while ( size-- ) + if ( *p1 != *p2 ) + return ( *p1 - *p2 ); + else + p1++, p2++; + return 0; +} + + +/* The following function is an analog of standard C function + `memmove'. The function returns the first operand. */ + +void *ammunition_memmove ( void *s1, const void *s2, size_x n ) +{ + int i; + + if ( ( ( char * ) s1 < ( char * ) s2 && ( char * ) s1 + n <= ( char * ) s2 ) + || ( ( char * ) s2 < ( char * ) s1 + && ( char * ) s2 + n <= ( char * ) s1 ) ) + return ( void * ) ammunition_memcpy ( s1, s2, n ); + if ( ( char * ) s1 < ( char * ) s2 && ( char * ) s1 + n > ( char * ) s2 ) { + _Pragma( "loopbound min 0 max 4" ) + for ( i = 0; ( size_x ) i < n; i++ ) + ( ( char * ) s1 ) [i] = ( ( char * ) s2 ) [i]; + } else { + _Pragma( "loopbound min 0 max 4" ) + for ( i = n - 1; i >= 0; i-- ) + ( ( char * ) s1 )[i] = ( ( char * ) s2 ) [i]; + } + return s1; +} + +int ammunition_strcmp ( const char *str1, const char *str2 ) +{ + _Pragma( "loopbound min 1 max 4008" ) + while ( *str1 && ( *str1 == *str2 ) ) + str1++, str2++; + return *( const unsigned char * )str1 - *( const unsigned char * )str2; +} + +int ammunition_atoi ( const char *str ) +{ + int result = 0; + int sign = ( str[0] == '-' ? -1 : 1 ); + + int readingPos = 0; + if ( str[0] == '-' || str[0] == '+' ) + readingPos++; + _Pragma( "loopbound min 1 max 1" ) + do { + result *= 10; + result += str[readingPos++] - 48; + } while ( str[readingPos] != 0 ); + + return sign * result; +} + + +int ammunition_sprintf_d( char *s, int number ) +{ + /* How many decimal digits do we need? */ + char digits = 0; + unsigned char writePos = 0; + long long copyOfNumber = number; + _Pragma( "loopbound min 1 max 10" ) + do { + digits++; + copyOfNumber /= 10; + } while ( copyOfNumber != 0 ); + + writePos = digits; + if ( number < 0 ) { + writePos++; + s[0] = '-'; + } + s[writePos] = 0; + + copyOfNumber = number; + _Pragma( "loopbound min 1 max 10" ) + do { + s[--writePos] = 48 + ( ( copyOfNumber >= 0 ? + copyOfNumber : -copyOfNumber ) % 10 ); + copyOfNumber /= 10; + } while ( copyOfNumber != 0 ); + + return digits + ( number < 0 ? 1 : 0 ); +} + + +int ammunition_sprintf_u( char *s, unsigned int number ) +{ + /* How many decimal digits do we need? */ + char digits = 0; + unsigned char writePos = 0; + unsigned long copyOfNumber = number; + _Pragma( "loopbound min 1 max 10" ) + do { + digits++; + copyOfNumber /= 10; + } while ( copyOfNumber != 0 ); + + writePos = digits; + s[writePos] = 0; + + copyOfNumber = number; + _Pragma( "loopbound min 1 max 10" ) + do { + s[--writePos] = 48 + ( copyOfNumber % 10 ); + copyOfNumber /= 10; + } while ( copyOfNumber != 0 ); + + return digits; +} diff --git a/baseline/source/ammunition/ammunition_limits.h b/baseline/source/ammunition/ammunition_limits.h new file mode 100644 index 0000000..0de4c82 --- /dev/null +++ b/baseline/source/ammunition/ammunition_limits.h @@ -0,0 +1,35 @@ +#ifndef AMMUNITION_LIMITS_H +#define AMMUNITION_LIMITS_H + +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif +#ifndef UCHAR_MAX +#define UCHAR_MAX 255 +#endif +#ifndef SCHAR_MAX +#define SCHAR_MAX 127 +#endif +#ifndef SCHAR_MIN +#define SCHAR_MIN (-128) +#endif +#ifndef USHRT_MAX +#define USHRT_MAX 65535 +#endif +#ifndef SHRT_MAX +#define SHRT_MAX 32767 +#endif +#ifndef SHRT_MIN +#define SHRT_MIN (-32768) +#endif +#ifndef UINT_MAX +#define UINT_MAX (INT_MAX * 2U + 1) +#endif +#ifndef INT_MAX +#define INT_MAX 2147483647 +#endif +#ifndef INT_MIN +#define INT_MIN (-INT_MAX-1) +#endif + +#endif /* #ifndef AMMUNITION_LIMITS_H */ diff --git a/baseline/source/ammunition/ammunition_stdio.h b/baseline/source/ammunition/ammunition_stdio.h new file mode 100644 index 0000000..a3a7a4b --- /dev/null +++ b/baseline/source/ammunition/ammunition_stdio.h @@ -0,0 +1,8 @@ +#ifndef AMMUNITION_STDIO_H +#define AMMUNITION_STDIO_H + +int ammunition_sprintf_d( char *s, int number ); + +int ammunition_sprintf_u( char *s, unsigned int number ); + +#endif diff --git a/baseline/source/ammunition/ammunition_stdlib.h b/baseline/source/ammunition/ammunition_stdlib.h new file mode 100644 index 0000000..d907212 --- /dev/null +++ b/baseline/source/ammunition/ammunition_stdlib.h @@ -0,0 +1,6 @@ +#ifndef AMMUNITION_STDLIB_H +#define AMMUNITION_STDLIB_H + +int ammunition_atoi ( const char *str ); + +#endif diff --git a/baseline/source/ammunition/ammunition_string.h b/baseline/source/ammunition/ammunition_string.h new file mode 100644 index 0000000..6b042f8 --- /dev/null +++ b/baseline/source/ammunition/ammunition_string.h @@ -0,0 +1,18 @@ +#ifndef AMMUNITION_STRING_H +#define AMMUNITION_STRING_H + +typedef unsigned int size_x; +//typedef __SIZE_TYPE__ size_x; + +/* + Forward declaration of functions +*/ + +void *ammunition_memcpy( void *, const void *, size_x ); +void *ammunition_memset( void *, int, size_x ); +int ammunition_memcmp ( const void *mem1, const void *mem2, size_x size ); +void *ammunition_memmove ( void *s1, const void *s2, size_x n ); +int ammunition_strcmp ( const char *str1, const char *str2 ); + +#endif /* AMMUNITION_STRING_H */ + diff --git a/baseline/source/ammunition/arithm.c b/baseline/source/ammunition/arithm.c new file mode 100644 index 0000000..9480846 --- /dev/null +++ b/baseline/source/ammunition/arithm.c @@ -0,0 +1,1384 @@ +/* + FILE NAME: arithm.c + + TITLE: Package for arbitrary precision integer arithmetic + + DESCRIPTION: This abstract data implements arbitrary precision + integer and unsigned integer numbers by machine independent + way. The implementation of the package functions are not + sufficiently efficient in order to use for run-time. The + package functions are oriented to implement constant-folding in + compilers. This package is necessary because host machine may + not support such arithmetic for target machine. For example, + VAX does not support does not support more 32-bits integer + numbers arithmetic. The numbers are represented by bytes in + big endian mode, negative integer numbers are represented in + complementary code. All sizes are given in bytes and must be + positive. Results of executions of all functions can coincide + with a operand(s). All functions of addition, subtraction, + multiplication, division, evaluation of remainder, shift, + changing size and transformation of string into number fix + overflow. The overflow is fixed when result can not be + represented by number of given size. + +*/ + +#include "arithm.h" +#include "ammunition_string.h" + + +/* This variable can have only two values 0 or 1. The value `1' + corresponds to overflow. The variable value are modified by all + functions of addition, subtract, multiplication, division, + evaluation of remainder, shift, changing size and transformation of + string into number fix overflow. */ + +int ammunition_overflow_bit; + + +/* The following function adds unsigned integers. The function + returns 1 if unsigned integer overflow is fixed, 0 otherwise. + Result can be placed in any operand. */ + +int ammunition_add_unsigned_integer_without_overflow_reaction +( int size, const void *op1, const void *op2, void *result ) +{ + int digit_num; + int carry; + unsigned int sum; + + _Pragma( "loopbound min 4 max 4" ) + for ( digit_num = size - 1, carry = 0; digit_num >= 0; digit_num-- ) { + sum = ( ( ( unsigned char * ) op1 ) [digit_num] + + ( ( unsigned char * ) op2 ) [digit_num] + carry ); + if ( sum > UCHAR_MAX ) { + sum -= UCHAR_MAX + 1; + carry = 1; + } else + carry = 0; + ( ( unsigned char * ) result ) [digit_num] = sum; + } + return carry != 0; +} + +/* The following function adds unsigned integers. The function + returns 1 if unsigned integer overflow (the first operand is less + than the second) is fixed, 0 otherwise. Result can be placed in + any operand. */ + +int ammunition_subtract_unsigned_integer_without_overflow_reaction +( int size, const void *op1, const void *op2, void *result ) +{ + int digit_num; + int carry; + int subtraction; + + _Pragma( "loopbound min 4 max 4" ) + for ( digit_num = size - 1, carry = 0; digit_num >= 0; digit_num-- ) { + subtraction = ( ( ( unsigned char * ) op1 ) [digit_num] + - ( ( unsigned char * ) op2 ) [digit_num] - carry ); + if ( subtraction < 0 ) { + subtraction += UCHAR_MAX + 1; + carry = 1; + } else + carry = 0; + ( ( unsigned char * ) result ) [digit_num] = subtraction; + } + return carry != 0; +} + +/* The following function makes complementary code of number. Result + can be placed in operand. */ + +void ammunition_make_complementary_code +( int size, const void *operand, void *result ) +{ + int digit_num; + int carry; + int subtraction; + + _Pragma( "loopbound min 2 max 6" ) + for ( digit_num = size - 1, carry = 0; digit_num >= 0; digit_num-- ) { + subtraction = ( 0 - ( ( unsigned char * ) operand ) [digit_num] - carry ); + if ( subtraction != 0 ) { + subtraction += UCHAR_MAX + 1; + carry = 1; + } else + carry = 0; + ( ( unsigned char * ) result ) [digit_num] = subtraction; + } +} + +/* The following function multiplys unsigned integer by digit (byte + size). The function returns 1 if unsigned integer overflow is + fixed, 0 otherwise. */ + +int ammunition_multiply_unsigned_integer_by_digit_without_overflow_reaction +( int size, void *operand, unsigned int digit ) +{ + int digit_num; + unsigned int carry; + unsigned int sum; + + _Pragma( "loopbound min 4 max 4" ) + for ( digit_num = size - 1, carry = 0; digit_num >= 0; digit_num-- ) { + sum = ( ( ( unsigned char * ) operand ) [digit_num] * digit + carry ); + if ( sum > UCHAR_MAX ) { + carry = sum / ( UCHAR_MAX + 1 ); + sum %= UCHAR_MAX + 1; + } else + carry = 0; + ( ( unsigned char * ) operand ) [digit_num] = sum; + } + return carry != 0; +} + + +/* Originally reaction on all integer and unsigned integer overflow is + equal to the following function. The function does nothing. */ + +void +ammunition_arithmetic_overflow_reaction ( void ) +{} + + +/* Originally reaction on all integer and unsigned integer overflow is + equal to the following function. The function does nothing. */ + +void +ammunition_arithmetic_unsigned_overflow_reaction ( void ) +{} + + +/* This page contains functions for arbitrary precision addition. */ + +/* The function adds unsigned integers and fixes overflow reaction if + it is needed. The function makes this with the aid of function + `add_unsigned_integer_without_overflow_reaction'. Result can be + placed in any operand. */ + +void +ammunition_add_unsigned_integer ( int size, const void *op1, const void *op2, + void *result ) +{ + ammunition_overflow_bit + = ammunition_add_unsigned_integer_without_overflow_reaction ( + size, op1, op2, result ); + if ( ammunition_overflow_bit != 0 ) + ammunition_arithmetic_unsigned_overflow_reaction(); +} + +/* The function adds integers and fixes overflow reaction if it is + needed. The function makes this with the aid of function + `add_unsigned_integer_without_overflow_reaction'. Result can be + placed in any operand. */ + +void +ammunition_add_integer ( int size, const void *op1, const void *op2, + void *result ) +{ + int op1_sign; + int sign_equality; + + op1_sign = INTEGER_SIGN ( op1 ); + sign_equality = INTEGER_SIGN ( op1 ) == INTEGER_SIGN ( op2 ); + ammunition_add_unsigned_integer_without_overflow_reaction ( + size, op1, op2, result ); + ammunition_overflow_bit = sign_equality && + ( op1_sign != INTEGER_SIGN ( result ) ); + if ( ammunition_overflow_bit != 0 ) + ammunition_arithmetic_overflow_reaction(); +} + + + +/* This page contains functions for arbitrary precision subtraction. */ + +/* The function subtracts unsigned integers and fixes overflow + reaction if it is needed. The function makes this with the aid of + function `subtract_unsigned_integer_without_overflow_reaction'. + Result can be placed in any operand. */ + +void +ammunition_subtract_unsigned_integer ( int size, const void *op1, + const void *op2, + void *result ) +{ + ammunition_overflow_bit + = ammunition_subtract_unsigned_integer_without_overflow_reaction ( + size, op1, op2, result ); + if ( ammunition_overflow_bit != 0 ) + ammunition_arithmetic_unsigned_overflow_reaction(); +} + +/* The function subtracts integers and fixes overflow reaction if it + is needed. The function makes this with the aid of function + `subtract_unsigned_integer_without_overflow_reaction'. Result can + be placed in any operand. */ + +void +ammunition_subtract_integer ( int size, const void *op1, const void *op2, + void *result ) +{ + int op1_sign; + int sign_unequality; + + op1_sign = INTEGER_SIGN ( op1 ); + sign_unequality = INTEGER_SIGN ( op1 ) != INTEGER_SIGN ( op2 ); + ammunition_subtract_unsigned_integer_without_overflow_reaction ( + size, op1, op2, result ); + ammunition_overflow_bit = sign_unequality && + ( op1_sign != INTEGER_SIGN ( result ) ); + if ( ammunition_overflow_bit != 0 ) + ammunition_arithmetic_overflow_reaction(); +} + + + +/* This page contains functions for arbitrary precision multiplication. */ + +/* The following function multiplys unsigned integers. The function + returns 1 if unsigned integer overflow is fixed, 0 otherwise. + Result can be placed in any operand. */ + +int ammunition_multiply_unsigned_integer_without_overflow_reaction +( int size, const void *op1, const void *op2, void *result ) +{ + int op1_digit_num; + int op2_digit_num; + int carry; + unsigned long int partial_sum; + int result_digit_number; + int overflow_flag; + unsigned char long_result [2 * MAX_INTEGER_OPERAND_SIZE]; + + ammunition_memset ( long_result + size, 0, ( size_x ) size ); + _Pragma( "loopbound min 4 max 4" ) + for ( op2_digit_num = size - 1; op2_digit_num >= 0; op2_digit_num-- ) { + if ( ( ( unsigned char * ) op2 ) [op2_digit_num] != 0 ) { + _Pragma( "loopbound min 4 max 4" ) + for ( op1_digit_num = size - 1, carry = 0; op1_digit_num >= 0; + op1_digit_num-- ) { + partial_sum + = ( ( ( unsigned char * ) op1 ) [op1_digit_num] + * ( ( unsigned char * ) op2 ) [op2_digit_num] + + long_result [op1_digit_num + op2_digit_num + 1] + + carry ); + long_result [op1_digit_num + op2_digit_num + 1] + = ( unsigned char ) ( partial_sum % ( UCHAR_MAX + 1 ) ); + carry = partial_sum / ( UCHAR_MAX + 1 ); + } + long_result [op2_digit_num] = carry; + } else + long_result [op2_digit_num] = 0; + } + overflow_flag = 0; + _Pragma( "loopbound min 1 max 4" ) + for ( result_digit_number = size - 1; result_digit_number >= 0; + result_digit_number-- ) { + if ( long_result [result_digit_number] != 0 ) { + overflow_flag = 1; + break; + } + } + ammunition_memcpy ( result, long_result + size, ( size_x ) size ); + return overflow_flag; +} + +/* The following function multiplys unsigned integers and fixes + overflow reaction if it is needed. The function makes this with + the aid of function + `multiply_unsigned_integer_without_overflow_reaction'. Result can + be placed in any operand. */ + +void +ammunition_multiply_unsigned_integer ( int size, const void *op1, + const void *op2, + void *result ) +{ + ammunition_overflow_bit = + ammunition_multiply_unsigned_integer_without_overflow_reaction ( + size, op1, op2, result ); + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); +} + +/* The function multiplys integers and fixes overflow reaction if it + is needed. The function makes this with the aid of function + `multiply_unsigned_integer_without_overflow_reaction'. Result can + be placed in any operand. */ + +void +ammunition_multiply_integer ( int size, const void *op1, const void *op2, + void *result ) +{ + int negative_result_flag; + unsigned char op1_complementary [MAX_INTEGER_OPERAND_SIZE]; + unsigned char op2_complementary [MAX_INTEGER_OPERAND_SIZE]; + unsigned const char *abs_op1; + unsigned const char *abs_op2; + int unsigned_result_sign; + + negative_result_flag = INTEGER_SIGN ( op1 ) != INTEGER_SIGN ( op2 ); + if ( INTEGER_SIGN ( op1 ) ) { + /* May be integer overflow. But result is correct because + it is unsigned. */ + ammunition_make_complementary_code ( size, op1, op1_complementary ); + abs_op1 = ( unsigned const char * )op1_complementary; + } else + abs_op1 = ( unsigned const char * )op1; + if ( INTEGER_SIGN ( op2 ) ) { + /* May be integer overflow. But result is correct because + it is unsigned. */ + ammunition_make_complementary_code ( size, op2, op2_complementary ); + abs_op2 = ( unsigned const char * )op2_complementary; + } else + abs_op2 = ( unsigned const char * )op2; + ammunition_overflow_bit = + ammunition_multiply_unsigned_integer_without_overflow_reaction ( + size, abs_op1, abs_op2, result ); + unsigned_result_sign = INTEGER_SIGN ( result ); + if ( negative_result_flag ) + ammunition_make_complementary_code ( size, result, result ); + if ( unsigned_result_sign + && ( !negative_result_flag + || INTEGER_SIGN ( result ) != unsigned_result_sign ) ) + /* Unsigned result can not be represented as integer. */ + ammunition_overflow_bit = 1; + if ( ammunition_overflow_bit ) + ammunition_arithmetic_overflow_reaction(); +} + + + +/* This page contains functions for arbitrary precision division. */ + +/* The following function divides unsigned integers. The function + returns 1 if unsigned integer overflow (division by zero) is fixed, + 0 otherwise. Result can be placed in any operand. See algorithm + in Knuth's book. */ + +int ammunition_divide_unsigned_integer_without_overflow_reaction +( int size, const void *op1, const void *op2, void *result ) +{ + int scaled_op1_digit_num; + unsigned int q_approximation; + int first_nonzero_digit_number; + int op2_digit_number; + unsigned int scale; + unsigned char scaled_op1 [MAX_INTEGER_OPERAND_SIZE + 1]; + unsigned char normalized_op2 [MAX_INTEGER_OPERAND_SIZE]; + unsigned char extended_normalized_op2 [MAX_INTEGER_OPERAND_SIZE + 1]; + + _Pragma( "loopbound min 4 max 4" ) + for ( op2_digit_number = 0; op2_digit_number < size; op2_digit_number++ ) { + if ( ( ( unsigned char * ) op2 ) [op2_digit_number] != 0 ) + break; + } + first_nonzero_digit_number = op2_digit_number; + if ( first_nonzero_digit_number == size ) { + /* Zero divisor */ + ammunition_memset ( result, 0, ( size_x ) size ); + return 1 /* TRUE */; + } else + if ( first_nonzero_digit_number == size - 1 ) { + /* Division by digit. */ + int digit_num; + int digit; + unsigned long divisable; + unsigned long remainder; + + digit = ( ( unsigned char * ) op2 ) [first_nonzero_digit_number]; + ammunition_memcpy ( result, op1, ( size_x ) size ); + remainder = 0; + _Pragma( "loopbound min 4 max 4" ) + for ( digit_num = 0; digit_num < size; digit_num++ ) { + divisable = ( remainder * ( UCHAR_MAX + 1 ) + + ( ( unsigned char * ) result ) [digit_num] ); + remainder = divisable % digit; + ( ( unsigned char * ) result ) [digit_num] + = ( unsigned char ) ( divisable / digit ); + } + return 0 /* FALSE */; + } + /* Normalization of divisor. */ + scale = ( UCHAR_MAX + 1 ) / ( ( ( unsigned char * ) op2 ) [op2_digit_number] + + 1 ); + ammunition_memcpy ( scaled_op1 + 1, op1, ( size_x ) size ); + *scaled_op1 = 0; + + ammunition_multiply_unsigned_integer_by_digit_without_overflow_reaction + ( size + 1, scaled_op1, scale ); + + ammunition_memcpy ( normalized_op2, op2, ( size_x ) size ); + + ammunition_multiply_unsigned_integer_by_digit_without_overflow_reaction + ( size, normalized_op2, scale ); + + _Pragma( "loopbound min 0 max 0" ) + for ( scaled_op1_digit_num = 0; + scaled_op1_digit_num <= first_nonzero_digit_number; + scaled_op1_digit_num++ ) { + /* Division of `scaled_op1[scaled_op1_digit_number]..scaled_op1[size]' by + `normalized_op2[first_nonzero_digit_number]..normalized_op2[size-1]' + for evaluation of one digit of quotient + `result[size-1-first_nonzero_digit_number-scaled_op1_digit_number]'. + */ + if ( scaled_op1 [scaled_op1_digit_num] + == normalized_op2 [first_nonzero_digit_number] ) + q_approximation = UCHAR_MAX; + else + q_approximation + = ( scaled_op1 [scaled_op1_digit_num] * ( UCHAR_MAX + 1 ) + + scaled_op1 [scaled_op1_digit_num + 1] ) + / normalized_op2 [first_nonzero_digit_number]; + + _Pragma( "loopbound min 0 max 0" ) + while ( normalized_op2 [first_nonzero_digit_number + 1] * q_approximation + > ( ( ( unsigned long int ) scaled_op1 [scaled_op1_digit_num] + * ( UCHAR_MAX + 1 ) + + scaled_op1 [scaled_op1_digit_num + 1] + - q_approximation + * normalized_op2 [first_nonzero_digit_number] ) + * ( UCHAR_MAX + 1 ) + scaled_op1 [scaled_op1_digit_num + 2] ) ) + q_approximation --; + + /* Multiply and subtract */ + ammunition_memcpy ( extended_normalized_op2 + 1, + normalized_op2 + first_nonzero_digit_number, + ( size_x ) ( size - first_nonzero_digit_number ) ); + *extended_normalized_op2 = 0; + ammunition_multiply_unsigned_integer_by_digit_without_overflow_reaction + ( size - first_nonzero_digit_number + 1, extended_normalized_op2, + q_approximation ); + if ( ammunition_subtract_unsigned_integer_without_overflow_reaction + ( size - first_nonzero_digit_number + 1, + scaled_op1 + scaled_op1_digit_num, extended_normalized_op2, + scaled_op1 + scaled_op1_digit_num ) ) { + /* Negative result. Compensation by addition. */ + q_approximation--; + ammunition_memcpy ( extended_normalized_op2 + 1, + normalized_op2 + first_nonzero_digit_number, + ( size_x ) ( size - first_nonzero_digit_number ) ); + *extended_normalized_op2 = 0; + + ammunition_add_unsigned_integer_without_overflow_reaction + ( size - first_nonzero_digit_number + 1, + scaled_op1 + scaled_op1_digit_num, extended_normalized_op2, + scaled_op1 + scaled_op1_digit_num ); + + } + ( ( unsigned char * ) result ) [size - 1 - first_nonzero_digit_number + + scaled_op1_digit_num] = q_approximation; + } + ammunition_memset ( result, 0, + ( size_x ) ( size - 1 - first_nonzero_digit_number ) ); + return 0 /* TRUE */; +} + +/* The function divides unsigned integers and fixes overflow reaction + if it is needed. The function makes this with the aid of function + `divide_unsigned_integer_without_overflow_reaction'. Result can be + placed in any operand. */ + +void +ammunition_divide_unsigned_integer ( int size, const void *op1, const void *op2, + void *result ) +{ + ammunition_overflow_bit = + ammunition_divide_unsigned_integer_without_overflow_reaction ( + size, op1, op2, result ); + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); +} + +/* The function divides integers and fixes overflow reaction if it is + needed. The function makes this with the aid of function + `divide_unsigned_integer_without_overflow_reaction'. Result can be + placed in any operand. */ + +void +ammunition_divide_integer ( int size, const void *op1, const void *op2, + void *result ) +{ + int negative_result_flag; + unsigned char op1_complementary [MAX_INTEGER_OPERAND_SIZE]; + unsigned char op2_complementary [MAX_INTEGER_OPERAND_SIZE]; + unsigned const char *abs_op1; + unsigned const char *abs_op2; + int unsigned_result_sign; + + negative_result_flag = INTEGER_SIGN ( op1 ) != INTEGER_SIGN ( op2 ); + if ( INTEGER_SIGN ( op1 ) ) { + /* May be integer overflow for minimal int. But result is correct because + it is unsigned. */ + ammunition_make_complementary_code ( size, op1, op1_complementary ); + abs_op1 = ( unsigned const char * )op1_complementary; + } else + abs_op1 = ( unsigned const char * )op1; + if ( INTEGER_SIGN ( op2 ) ) { + /* May be integer overflow for minimal int. But result is correct + because it is unsigned. */ + ammunition_make_complementary_code ( size, op2, op2_complementary ); + abs_op2 = ( unsigned const char * )op2_complementary; + } else + abs_op2 = ( unsigned const char * )op2; + ammunition_overflow_bit = + ammunition_divide_unsigned_integer_without_overflow_reaction ( + size, abs_op1, abs_op2, result ); + unsigned_result_sign = INTEGER_SIGN ( result ); + if ( negative_result_flag ) + ammunition_make_complementary_code ( size, result, result ); + if ( unsigned_result_sign + && ( !negative_result_flag + || INTEGER_SIGN ( result ) != unsigned_result_sign ) ) + /* Unsigned result can not be represented as integer. */ + ammunition_overflow_bit = 1; + if ( ammunition_overflow_bit ) + ammunition_arithmetic_overflow_reaction(); +} + + + +/* This page contains functions for arbitrary precision evaluation of + remainder. */ + +/* The function evaluates remainder of division of unsigned integers + as `op1 - (op1/op2)*op2' and fixes overflow reaction if it is + needed. Result can be placed in any operand. */ + +void +ammunition_unsigned_integer_remainder ( int size, const void *op1, + const void *op2, + void *result ) +{ + unsigned char temporary [MAX_INTEGER_OPERAND_SIZE]; + + ammunition_divide_unsigned_integer ( size, op1, op2, temporary ); + if ( ammunition_overflow_bit ) + /* Reaction on zero is called from `divide_unsigned_integer'. */ + ammunition_memset ( result, 0, ( size_x ) size ); + else { + ammunition_multiply_unsigned_integer ( size, temporary, op2, temporary ); + ammunition_subtract_unsigned_integer ( size, op1, temporary, result ); + } +} + + +/* This page contains functions for arbitrary precision number shifts. */ + +/* This function makes right shift of unsigned integer of given size + on given number of bits. If number of bits is negative the + function makes shift to left actually with the aid of function + `unsigned_integer_shift_left'. The function fixes overflow when + result can not be represented by number of given size, i.e. in + other words the opposite unsigned shift (to left) results in number + not equal to source operand. Result can be placed in operand. */ + +void +ammunition_unsigned_integer_shift_right ( int size, const void *operand, + int bits, void *result ) +{ + int byte_number; + unsigned byte; + unsigned carry; + int bit_shift; + int byte_shift; + + + if ( bits < 0 ) + ammunition_unsigned_integer_shift_left ( size, operand, -bits, result ); + else { + ammunition_overflow_bit = 0; + byte_shift = bits / CHAR_BIT; + bit_shift = bits % CHAR_BIT; + _Pragma( "loopbound min 0 max 3" ) + for ( byte_number = ( byte_shift >= size ? 0 : size - byte_shift ); + byte_number < size; byte_number++ ) + if ( ( ( unsigned char * ) operand ) [byte_number] != 0 ) { + ammunition_overflow_bit = 1; + break; + } + if ( byte_shift >= size ) + ammunition_memset ( result, 0, ( size_x ) size ); + else { + ammunition_memmove ( ( char * ) result + byte_shift, operand, + ( size_x ) ( size - byte_shift ) ); + ammunition_memset ( result, 0, ( size_x ) byte_shift ); + if ( bit_shift == 0 ) + return; + _Pragma( "loopbound min 3 max 3" ) + for ( byte_number = byte_shift, carry = 0; byte_number < size; + byte_number++ ) { + byte = ( ( unsigned char * ) result ) [byte_number]; + ( ( unsigned char * ) result ) [byte_number] + = carry | ( byte >> bit_shift ); + carry = ( byte << ( CHAR_BIT - bit_shift ) ) & UCHAR_MAX; + } + if ( carry != 0 ) + ammunition_overflow_bit = 1; + } + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); + } +} + +/* This function makes right arithmetic shift of integer of given size + on given number of bits. If number of bits is negative the + function makes shift to left actually with the aid of function + `integer_shift_left'. The function fixes overflow when result can + not be represented by number of given size, i.e. in other words the + opposite shift (to left) results in number not equal to source + operand. Result can be placed in operand. */ + +void +ammunition_integer_shift_right ( int size, const void *operand, int bits, + void *result ) +{ + int byte_number; + unsigned byte; + unsigned carry; + int bit_shift; + int byte_shift; + int operand_sign; + + if ( bits < 0 ) + ammunition_integer_shift_left ( size, operand, -bits, result ); + else { + operand_sign = INTEGER_SIGN ( operand ); + ammunition_overflow_bit = 0; + byte_shift = bits / CHAR_BIT; + bit_shift = bits % CHAR_BIT; + _Pragma( "loopbound min 0 max 3" ) + for ( byte_number = ( byte_shift >= size ? 0 : size - byte_shift ); + byte_number < size; byte_number++ ) + if ( ( ( unsigned char * ) operand ) [byte_number] != 0 ) { + ammunition_overflow_bit = 1; + break; + } + if ( byte_shift >= size ) + ammunition_memset ( result, + ( operand_sign ? UCHAR_MAX : 0 ), ( size_x ) size ); + else { + ammunition_memmove ( ( char * ) result + byte_shift, operand, + ( size_x ) ( size - byte_shift ) ); + ammunition_memset ( result, ( operand_sign ? UCHAR_MAX : 0 ), + ( size_x ) byte_shift ); + if ( bit_shift == 0 ) + return; + carry = ( ( ( operand_sign ? UCHAR_MAX : 0 ) << ( CHAR_BIT - bit_shift ) ) + & UCHAR_MAX ); + _Pragma( "loopbound min 3 max 3" ) + for ( byte_number = byte_shift; byte_number < size; byte_number++ ) { + byte = ( ( unsigned char * ) result ) [byte_number]; + ( ( unsigned char * ) result ) [byte_number] + = carry | ( byte >> bit_shift ); + carry = ( byte << ( CHAR_BIT - bit_shift ) ) & UCHAR_MAX; + } + if ( carry != 0 ) + ammunition_overflow_bit = 1; + } + if ( ammunition_overflow_bit ) + ammunition_arithmetic_overflow_reaction(); + } +} + +/* This function makes left shift of unsigned integer of given size on + given number of bits. If number of bits is negative the function + makes shift to left actually with the aid of function + `unsigned_integer_shift_right'. The function fixes overflow when + result can not be represented by number of given size, i.e. i.e. in + other words the opposite shift (to right) results in number not + equal to source operand. Result can be placed in operand. */ + +void +ammunition_unsigned_integer_shift_left ( int size, const void *operand, + int bits, void *result ) +{ + int byte_number; + unsigned byte; + unsigned carry; + int bit_shift; + int byte_shift; + + if ( bits < 0 ) + ammunition_unsigned_integer_shift_right ( size, operand, -bits, result ); + else { + ammunition_overflow_bit = 0; + byte_shift = bits / CHAR_BIT; + bit_shift = bits % CHAR_BIT; + _Pragma( "loopbound min 0 max 2" ) + for ( byte_number = 0; byte_number < byte_shift && byte_number < size; + byte_number++ ) + if ( ( ( unsigned char * ) operand ) [byte_number] != 0 ) { + ammunition_overflow_bit = 1; + break; + } + if ( byte_shift >= size ) + ammunition_memset ( result, 0, ( size_x ) size ); + else { + ammunition_memmove ( result, ( char * ) operand + byte_shift, + ( size_x ) ( size - byte_shift ) ); + ammunition_memset ( ( char * ) result + ( size - byte_shift ), 0, + ( size_x ) byte_shift ); + if ( bit_shift == 0 ) + return; + _Pragma( "loopbound min 2 max 3" ) + for ( byte_number = size - byte_shift - 1, carry = 0; + byte_number >= 0; byte_number-- ) { + byte = ( ( unsigned char * ) result ) [byte_number]; + ( ( unsigned char * ) result ) [byte_number] + = carry | ( byte << bit_shift ); + carry = byte >> ( CHAR_BIT - bit_shift ); + } + if ( carry != 0 ) + ammunition_overflow_bit = 1; + } + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); + } +} + +/* This function makes left arithmetic shift of integer of given size + on given number of bits. If number of bits is negative the + function makes shift to left actually with the aid of function + `integer_shift_right'. The function fixes overflow when result can + not be represented by number of given size, i.e. in other words the + opposite shift (to right) results in number not equal to source + operand. Result can be placed in operand. */ + +void +ammunition_integer_shift_left ( int size, const void *operand, int bits, + void *result ) +{ + int byte_number; + unsigned byte; + unsigned carry; + int bit_shift; + int byte_shift; + int operand_sign; + + if ( bits < 0 ) + ammunition_integer_shift_right ( size, operand, -bits, result ); + else { + operand_sign = INTEGER_SIGN ( operand ); + ammunition_overflow_bit = 0; + byte_shift = bits / CHAR_BIT; + bit_shift = bits % CHAR_BIT; + _Pragma( "loopbound min 0 max 2" ) + for ( byte_number = 0; byte_number < byte_shift && byte_number < size; + byte_number++ ) + if ( ( ( unsigned char * ) operand ) [byte_number] + != ( operand_sign ? UCHAR_MAX : 0 ) ) { + ammunition_overflow_bit = 1; + break; + } + if ( byte_shift >= size ) + ammunition_memset ( result, 0, ( size_x ) size ); + else { + ammunition_memmove ( result, ( char * ) operand + byte_shift, + ( size_x ) ( size - byte_shift ) ); + ammunition_memset ( ( char * ) result + ( size - byte_shift ), 0, + ( size_x ) byte_shift ); + if ( bit_shift == 0 ) + return; + _Pragma( "loopbound min 2 max 3" ) + for ( byte_number = size - byte_shift - 1, carry = 0; + byte_number >= 0; byte_number-- ) { + byte = ( ( unsigned char * ) result ) [byte_number]; + ( ( unsigned char * ) result ) [byte_number] + = carry | ( byte << bit_shift ); + carry = byte >> ( CHAR_BIT - bit_shift ); + } + if ( carry != ( ( unsigned ) ( operand_sign ? UCHAR_MAX : 0 ) + >> ( CHAR_BIT - bit_shift ) ) ) + ammunition_overflow_bit = 1; + } + if ( operand_sign != INTEGER_SIGN ( result ) ) + ammunition_overflow_bit = 1; + if ( ammunition_overflow_bit ) + ammunition_arithmetic_overflow_reaction(); + } +} + + + +/* This page contains functions for bitwise operations of arbitrary + precision numbers. */ + +/* This function makes bitwise `or' of two integers of given size. */ + +void +ammunition_integer_or ( int size, const void *op1, const void *op2, + void *result ) +{ + int byte_number; + + _Pragma( "loopbound min 4 max 4" ) + for ( byte_number = 0; byte_number < size; byte_number++ ) { + ( ( unsigned char * ) result ) [byte_number] + = ( ( unsigned char * ) op1 ) [byte_number] + | ( ( unsigned char * ) op2 ) [byte_number]; + } +} + +/* This function makes bitwise `or' of two unsigned integers of given + size. */ + +void +ammunition_unsigned_integer_or ( int size, const void *op1, const void *op2, + void *result ) +{ + ammunition_integer_or ( size, op1, op2, result ); +} + + +/* This function makes bitwise `and' of two integers of given size. */ + +void +ammunition_integer_and ( int size, const void *op1, const void *op2, + void *result ) +{ + int byte_number; + + _Pragma( "loopbound min 4 max 4" ) + for ( byte_number = 0; byte_number < size; byte_number++ ) { + ( ( unsigned char * ) result ) [byte_number] + = ( ( unsigned char * ) op1 ) [byte_number] + & ( ( unsigned char * ) op2 ) [byte_number]; + } +} + +/* This function makes bitwise `and' of two unsigned integers of given + size. */ + +void +ammunition_unsigned_integer_and ( int size, const void *op1, const void *op2, + void *result ) +{ + ammunition_integer_and ( size, op1, op2, result ); +} + + +/* This function makes bitwise `not' of integer of given size. */ + +void +ammunition_integer_not ( int size, const void *operand, void *result ) +{ + int byte_number; + + _Pragma( "loopbound min 4 max 4" ) + for ( byte_number = 0; byte_number < size; byte_number++ ) { + ( ( unsigned char * ) result ) [byte_number] + = ( ( unsigned char * ) operand ) [byte_number] ^ UCHAR_MAX; + } +} + +/* This function makes bitwise `not' of unsigned integer of given + size. */ + +void +ammunition_unsigned_integer_not ( int size, const void *operand, void *result ) +{ + ammunition_integer_not ( size, operand, result ); +} + + + +/* This page contains functions for comparison of arbitrary precision + numbers. */ + +/* This function compares two unsigned integers of given size on + equality. The function returns 1 if unsigned integers are equal, 0 + otherwise. */ + +int +ammunition_eq_unsigned_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_memcmp ( op1, op2, ( size_x ) size ) == 0; +} + +/* This function compares two integers of given size on equality. The + function returns 1 if integers are equal, 0 otherwise. */ + +int +ammunition_eq_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_memcmp ( op1, op2, ( size_x ) size ) == 0; +} + +/* This function compares two unsigned integers of given size on + inequality. The function returns 1 if unsigned integers are not + equal, 0 otherwise. */ + +int +ammunition_ne_unsigned_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_memcmp ( op1, op2, ( size_x ) size ) != 0; +} + +/* This function compares two integers of given size on inequality. + The function returns 1 if integers are not equal, 0 otherwise. */ + +int +ammunition_ne_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_memcmp ( op1, op2, ( size_x ) size ) != 0; +} + + +/* This function compares two memory parts of given size on that the + first operand is greater than the second. The bytes are described + as unsigned. The function returns 1 if the first operand is + greater than the second, - 1 if the first operand is less than the + second, 0 otherwise. */ + +int ammunition_bytes_comparison ( const void *op1, const void *op2, int size ) +{ + const unsigned char *str1 = ( unsigned const char * )op1; + const unsigned char *str2 = ( unsigned const char * )op2; + + _Pragma( "loopbound min 1 max 4" ) + while ( size > 0 && *str1 == *str2 ) { + str1++; + str2++; + size--; + } + if ( size <= 0 ) + return 0; + else + if ( *str1 > *str2 ) + return 1; + else + return -1; +} + +/* This function compares two unsigned integers of given size on that + the first operand is greater than the second. The function returns + 1 if the first unsigned integer is greater than the second, 0 + otherwise. */ + +int +ammunition_gt_unsigned_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_bytes_comparison ( op1, op2, size ) > 0; +} + +/* This function compares two integers of given size on that the first + operand is greater than the second. The function returns 1 if the + first integer is greater than the second, 0 otherwise. */ + +int ammunition_gt_integer ( int size, const void *op1, const void *op2 ) +{ + if ( INTEGER_SIGN ( op1 ) == 0 ) { + if ( INTEGER_SIGN ( op2 ) == 0 ) + return ammunition_bytes_comparison ( op1, op2, size ) > 0; + else + return 1; /* TRUE */ + } else + if ( INTEGER_SIGN ( op2 ) == 0 ) + return 0; /*FALSE*/ + else + return ammunition_bytes_comparison ( op1, op2, size ) > 0; +} + +/* This function compares two unsigned integers of given size on that + the first operand is less than the second. The function returns 1 + if the first unsigned integer is less than the second, 0 + otherwise. */ + +int +ammunition_lt_unsigned_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_bytes_comparison ( op1, op2, size ) < 0; +} + +/* This function compares two integers of given size on that the first + operand is less than the second. The function returns 1 if the + first integer is less than the second, 0 otherwise. */ + +int +ammunition_lt_integer ( int size, const void *op1, const void *op2 ) +{ + if ( INTEGER_SIGN ( op1 ) == 0 ) { + if ( INTEGER_SIGN ( op2 ) == 0 ) + return ammunition_bytes_comparison ( op1, op2, size ) < 0; + else + return 0; /*FALSE*/ + } else + if ( INTEGER_SIGN ( op2 ) == 0 ) + return 1; /* TRUE */ + else + return ammunition_bytes_comparison ( op1, op2, size ) < 0; +} + +/* This function compares two unsigned integers of given size on that + the first operand is greater than or equal to the second. The + function returns 1 if the first unsigned integer is greater than or + equal to the second, 0 otherwise. */ + +int +ammunition_ge_unsigned_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_bytes_comparison ( op1, op2, size ) >= 0; +} + +/* This function compares two integers of given size on that the first + operand is greater than or equal to the second. The function + returns 1 if the first integer is greater than or equal to the + second, 0 otherwise. */ + +int +ammunition_ge_integer ( int size, const void *op1, const void *op2 ) +{ + if ( INTEGER_SIGN ( op1 ) == 0 ) { + if ( INTEGER_SIGN ( op2 ) == 0 ) + return ammunition_bytes_comparison ( op1, op2, size ) >= 0; + else + return 1; /* TRUE */ + } else + if ( INTEGER_SIGN ( op2 ) == 0 ) + return 0; /*FALSE*/ + else + return ammunition_bytes_comparison ( op1, op2, size ) >= 0; +} + +/* This function compares two unsigned integers of given size on that + the first operand is less than or equal to the second. The + function returns 1 if the first unsigned integer is less than or + equal to the second, 0 otherwise. */ + +int +ammunition_le_unsigned_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_bytes_comparison ( op1, op2, size ) <= 0; +} + +/* This function compares two integers of given size on that the first + operand is less than or equal to the second. The function returns + 1 if the first integer is less than or equal to the second, 0 + otherwise. */ + +int +ammunition_le_integer ( int size, const void *op1, const void *op2 ) +{ + if ( INTEGER_SIGN ( op1 ) == 0 ) { + if ( INTEGER_SIGN ( op2 ) == 0 ) + return ammunition_bytes_comparison ( op1, op2, size ) <= 0; + else + return 0; /*FALSE*/ + } else + if ( INTEGER_SIGN ( op2 ) == 0 ) + return 1; /* TRUE */ + else + return ammunition_bytes_comparison ( op1, op2, size ) <= 0; +} + + + +/* This page contains functions for changing size of arbitrary + precision numbers. */ + +/* The function changes size of unsigned integer. The function fixes + overflow when result can not be represented by number of given + size. Result can be placed in operand. */ + +void +ammunition_change_unsigned_integer_size ( int operand_size, const void *operand, + int result_size, void *result ) +{ + int operand_digit_number; + + ammunition_overflow_bit = 0; + if ( operand_size <= result_size ) { + ammunition_memmove ( ( char * ) result + result_size - operand_size, + operand, ( size_x ) operand_size ); + ammunition_memset ( result, 0, ( size_x ) ( result_size - operand_size ) ); + } else { + _Pragma( "loopbound min 2 max 2" ) + for ( operand_digit_number = 0; + operand_digit_number < operand_size - result_size; + operand_digit_number++ ) { + if ( ( ( unsigned char * ) operand ) [operand_digit_number] != 0 ) { + ammunition_overflow_bit = 1; + break; + } + } + ammunition_memmove ( result, + ( char * ) operand + operand_size - result_size, + ( size_x ) result_size ); + } + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); +} + +/* The function changes size of integer. The function fixes overflow + when result can not be represented by number of given size. Result + can be placed in operand. */ + +void +ammunition_change_integer_size ( int operand_size, const void *operand, + int result_size, void *result ) +{ + int operand_digit_number; + int operand_sign; + + ammunition_overflow_bit = 0; + operand_sign = INTEGER_SIGN ( operand ); + if ( operand_size <= result_size ) { + ammunition_memmove ( ( char * ) result + result_size - operand_size, + operand, ( size_x ) operand_size ); + ammunition_memset ( result, ( operand_sign ? UCHAR_MAX : 0 ), + ( size_x ) ( result_size - operand_size ) ); + } else { + _Pragma( "loopbound min 2 max 2" ) + for ( operand_digit_number = 0; + operand_digit_number < operand_size - result_size; + operand_digit_number++ ) { + if ( ( ( unsigned char * ) operand ) [operand_digit_number] + != ( operand_sign ? UCHAR_MAX : 0 ) ) { + ammunition_overflow_bit = 1; + break; + } + } + ammunition_memmove ( result, + ( char * ) operand + operand_size - result_size, + ( size_x ) result_size ); + if ( operand_sign != INTEGER_SIGN ( result ) ) + ammunition_overflow_bit = 1; + } + if ( ammunition_overflow_bit ) + ammunition_arithmetic_overflow_reaction(); +} + + + +/* This page contains functions for conversion of arbitrary precision + numbers to ascii representation. */ + +/* This function transforms unsigned integer of given size to BASE + ascii representation. BASE should be between 2 and 36 including + them. Digits more 9 are represented by 'a', 'b' etc. Sign is + absent in result string. The function returns the result + string. */ + +char * +ammunition_unsigned_integer_to_based_string ( int size, const void *operand, + int base, + char *result ) +{ + int digit_num; + int i; + unsigned long divisable; + unsigned long remainder; + int nonzero_flag; + int length; + int temporary; + unsigned char operand_copy [MAX_INTEGER_OPERAND_SIZE]; + + ammunition_memcpy ( operand_copy, operand, ( size_x ) size ); + length = 0; + _Pragma( "loopbound min 1 max 10" ) + do { + nonzero_flag = 0 /* FALSE */; + _Pragma( "loopbound min 2 max 6" ) + for ( digit_num = 0, remainder = 0; digit_num < size; digit_num++ ) { + divisable = remainder * ( UCHAR_MAX + 1 ) + operand_copy [digit_num]; + remainder = divisable % base; + operand_copy [digit_num] = ( unsigned char ) ( divisable / base ); + if ( operand_copy [digit_num] != 0 ) + nonzero_flag = 1 /* TRUE */; + } + result [length++] = ( unsigned char ) ( remainder < 10 ? '0' + remainder + : 'a' + remainder - 10 ); + } while ( nonzero_flag ); + result [length] = '\0'; + _Pragma( "loopbound min 0 max 5" ) + for ( i = 0; i < length / 2; i++ ) { + temporary = result [i]; + result [i] = result [length - i - 1]; + result [length - i - 1] = temporary; + } + return result; +} + + +/* This function transforms unsigned integer of given size to decimal + ascii representation. Sign is absent in result string. The + function returns the result string. */ + +char * +ammunition_unsigned_integer_to_string ( int size, const void *operand, + char *result ) +{ + return ammunition_unsigned_integer_to_based_string ( size, operand, 10, + result ); +} + + +/* This function transforms integer of given size to BASE ascii + representation. BASE should be between 2 and 36 including them. + Digits more 9 are represented by 'a', 'b' etc. Sign is present in + result string only for negative numbers. The function returns the + result string. */ + +char * +ammunition_integer_to_based_string ( int size, const void *operand, int base, + char *result ) +{ + unsigned char operand_copy [MAX_INTEGER_OPERAND_SIZE]; + + if ( !INTEGER_SIGN ( operand ) ) + return ammunition_unsigned_integer_to_based_string ( size, operand, base, + result ); + ammunition_memcpy ( operand_copy, operand, ( size_x ) size ); + /* May be integer overflow. But result is correct because it is unsigned. */ + ammunition_make_complementary_code ( size, operand_copy, operand_copy ); + *result = '-'; + ammunition_unsigned_integer_to_based_string ( size, operand_copy, base, + result + 1 ); + return result; +} + + + +/* This function transforms integer of given size to decimal ascii + representation. Sign is present in result string only for negative + numbers. The function returns the result string. */ + +char * +ammunition_integer_to_string ( int size, const void *operand, char *result ) +{ + return ammunition_integer_to_based_string ( size, operand, 10, result ); +} + +/* This page contains functions for conversion of decimal ascii + representation to arbitrary precision numbers. */ + +/* The function adds digit (byte size) to unsigned integer. The + function returns 1 if unsigned integer overflow is fixed, 0 + otherwise. */ + +int ammunition_add_digit_to_unsigned_integer_without_overflow_reaction +( int size, void *operand, unsigned int digit ) +{ + int digit_num; + unsigned int carry; + unsigned int sum; + + _Pragma( "loopbound min 4 max 4" ) + for ( digit_num = size - 1, carry = digit; digit_num >= 0; + digit_num-- ) { + sum = ( ( unsigned char * ) operand ) [digit_num] + carry; + if ( sum > UCHAR_MAX ) { + carry = sum / ( UCHAR_MAX + 1 ); + sum %= UCHAR_MAX + 1; + } else + carry = 0; + ( ( unsigned char * ) operand ) [digit_num] = sum; + } + return carry != 0; +} + +/* This function transforms source string (decimal ascii + representation without sign) to given size unsigned integer and + returns pointer to first non digit in the source string through a + parameter. If the string started with invalid integer + representation the result will be zero and returns the operand + through the parameter. The function returns 1 if unsigned integer + overflow is fixed, 0 otherwise. */ + +int ammunition_string_to_unsigned_integer_without_overflow_reaction +( int size, const char *operand, void *result, char **first_nondigit ) +{ + int overflow_flag; + + ammunition_memset ( result, 0, ( size_x ) size ); + _Pragma( "loopbound min 0 max 10" ) + for ( overflow_flag = 0; ammunition_isdigit ( *operand ); operand++ ) { + overflow_flag + = overflow_flag || + ammunition_multiply_unsigned_integer_by_digit_without_overflow_reaction + ( size, result, 10 ); + overflow_flag + = overflow_flag + || ammunition_add_digit_to_unsigned_integer_without_overflow_reaction + ( size, result, *operand - '0' ); + } + *first_nondigit = ( char * ) operand; + return overflow_flag; +} + +/* This function skips all white spaces at the begin of source string + and transforms tail of the source string (decimal ascii + representation without sign) to given size unsigned integer with + the aid of function + `string_to_unsigned_integer_without_overflow_reaction'. If the + string started with invalid unsigned integer representation the + result will be zero. The function fixes overflow when result can + not be represented by number of given size. The function returns + address of the first nondigit in the source string. */ + +char * +ammunition_unsigned_integer_from_string ( int size, const char *operand, + void *result ) +{ + char *first_nondigit; + + _Pragma( "loopbound min 0 max 0" ) + while ( ammunition_isspace ( *operand ) ) + operand++; + ammunition_overflow_bit + = ammunition_string_to_unsigned_integer_without_overflow_reaction + ( size, operand, result, &first_nondigit ); + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); + return first_nondigit; +} + +/* This function skips all white spaces at the begin of source string + and transforms tail of the source string (decimal ascii + representation with possible sign `+' or `-') to given size integer + with the aid of function + `string_to_unsigned_integer_without_overflow_reaction'. If the + string started with invalid integer representation the result will + be zero. The function fixes overflow when result can not be + represented by number of given size. the function returns Address + of the first nondigit in the source string. */ + +char * +ammunition_integer_from_string ( int size, const char *operand, void *result ) +{ + int negative_number_flag; + char *first_nondigit; + int unsigned_result_sign; + + _Pragma( "loopbound min 0 max 0" ) + while ( ammunition_isspace ( *operand ) ) + operand++; + negative_number_flag = 0; /* FALSE */ + if ( *operand == '+' ) + operand++; + else + if ( *operand == '-' ) { + operand++; + negative_number_flag = 1; /* TRUE */ + } + ammunition_overflow_bit + = ammunition_string_to_unsigned_integer_without_overflow_reaction + ( size, operand, result, &first_nondigit ); + unsigned_result_sign = INTEGER_SIGN ( result ); + if ( negative_number_flag ) + /* May be integer overflow when `result' is correct. But result + is correct because it is unsigned. */ + ammunition_make_complementary_code ( size, result, result ); + ammunition_overflow_bit + = ammunition_overflow_bit + || ( unsigned_result_sign + && ( !negative_number_flag + || INTEGER_SIGN ( result ) != unsigned_result_sign ) ); + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); + return first_nondigit; +} + diff --git a/baseline/source/ammunition/arithm.h b/baseline/source/ammunition/arithm.h new file mode 100644 index 0000000..8ed78bf --- /dev/null +++ b/baseline/source/ammunition/arithm.h @@ -0,0 +1,123 @@ +/* + FILE NAME: arithm.h + + TITLE: Include file of package for arbitrary precision integer + arithmetic + + DESCRIPTION: This header file contains ANSI C prototype definitions of + the package functions and definitions of external + variable of the package and C++ classes for arbitrary + precision integer arithmetic. + +*/ + + +#ifndef __ARITHMETIC__ +#define __ARITHMETIC__ + +#include "ammunition_limits.h" + + +/* This page contains definitions of variables and macros common for + all package functions. */ + +/* The value of macro is suggested to be maximum length of integer operands + The length of use integers should be not greater than this value. */ + +#define MAX_INTEGER_OPERAND_SIZE 128 + +/* The following macro value is sign of integer number (0 or 1) given + as macro parameter. */ + +#define INTEGER_SIGN(operand) (*(unsigned char *) (operand) >> (CHAR_BIT - 1)) + +extern int ammunition_overflow_bit; + +extern void ammunition_add_unsigned_integer ( int size, const void *op1, + const void *op2, + void *result ); +extern void ammunition_add_integer ( int size, const void *op1, const void *op2, + void *result ); +extern void ammunition_subtract_unsigned_integer ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_subtract_integer ( int size, const void *op1, + const void *op2, + void *result ); +extern void ammunition_multiply_unsigned_integer ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_multiply_integer ( int size, const void *op1, + const void *op2, + void *result ); +extern void ammunition_divide_unsigned_integer ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_divide_integer ( int size, const void *op1, + const void *op2, + void *result ); +extern void ammunition_unsigned_integer_remainder ( int size, const void *op1, + const void *op2, void *result ); + +extern void ammunition_unsigned_integer_shift_right ( int size, + const void *operand, + int bits, void *result ); +extern void ammunition_integer_shift_right ( int size, const void *operand, + int bits, void *result ); +extern void ammunition_integer_shift_left ( int size, const void *operand, + int bits, void *result ); +extern void ammunition_unsigned_integer_shift_left ( int size, + const void *operand, + int bits, void *result ); + +extern void ammunition_integer_or ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_unsigned_integer_or ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_integer_and ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_unsigned_integer_and ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_integer_not ( int size, const void *operand, + void *result ); +extern void ammunition_unsigned_integer_not ( int size, const void *operand, + void *result ); + +extern int ammunition_eq_unsigned_integer ( int size, const void *op1, + const void *op2 ); +extern int ammunition_eq_integer ( int size, const void *op1, const void *op2 ); +extern int ammunition_ne_unsigned_integer ( int size, const void *op1, + const void *op2 ); +extern int ammunition_ne_integer ( int size, const void *op1, const void *op2 ); +extern int ammunition_gt_unsigned_integer ( int size, const void *op1, + const void *op2 ); +extern int ammunition_gt_integer ( int size, const void *op1, const void *op2 ); +extern int ammunition_lt_unsigned_integer ( int size, const void *op1, + const void *op2 ); +extern int ammunition_lt_integer ( int size, const void *op1, const void *op2 ); +extern int ammunition_ge_unsigned_integer ( int size, const void *op1, + const void *op2 ); +extern int ammunition_ge_integer ( int size, const void *op1, const void *op2 ); +extern int ammunition_le_unsigned_integer ( int size, const void *op1, + const void *op2 ); +extern int ammunition_le_integer ( int size, const void *op1, const void *op2 ); + +extern void ammunition_change_unsigned_integer_size +( int operand_size, const void *operand, int result_size, void *result ); +extern void ammunition_change_integer_size ( int operand_size, + const void *operand, + int result_size, void *result ); + +extern char *ammunition_unsigned_integer_to_string ( int size, + const void *operand, + char *result ); +extern char *ammunition_integer_to_string ( int size, const void *operand, + char *result ); + +extern char *ammunition_unsigned_integer_from_string ( int size, + const char *operand, + void *result ); +extern char *ammunition_integer_from_string ( int size, const char *operand, + void *result ); + +char ammunition_isdigit( unsigned char c ); +int ammunition_isspace( int c ); + +#endif /* #ifndef __ARITHMETIC__ */ diff --git a/baseline/source/ammunition/bits.c b/baseline/source/ammunition/bits.c new file mode 100644 index 0000000..9169656 --- /dev/null +++ b/baseline/source/ammunition/bits.c @@ -0,0 +1,313 @@ +/* + + FILE NAME: bits.c + + TITLE: Package for work with bits + + DESCRIPTION: This file implements functions of the package for work + with bit strings. A bit is given by address (start address) of + byte from which counting bits starts and its displacement which + is any non negative number of bit from the start address. The + most significant bit of the start address byte has number 0. + The bit string is given by its first bit and its length in + bits. + +*/ + +#include "bits.h" + +/* This function determines that given bit string contains only zero + bits. The function retruns TRUE if all bits of given bit string + are zero or `bit_length' <= 0. Value of `bit_displacement' must be + non-negative and can be greater than CHAR_BIT. */ + +int +ammunition_is_zero_bit_string ( const void *start_byte, int bit_displacement, + int bit_length ) +{ + const unsigned char *current_byte = ( unsigned const char * )start_byte; + + if ( bit_length <= 0 ) + return 1 /* TRUE */; + current_byte += bit_displacement / CHAR_BIT; + bit_displacement %= CHAR_BIT; + if ( bit_length < CHAR_BIT - bit_displacement ) + return ( ( ( *current_byte << bit_displacement ) + & ( UCHAR_MAX << ( CHAR_BIT - bit_length ) ) ) + & UCHAR_MAX ) == 0; + else + if ( bit_displacement != 0 ) { + if ( ( ( *current_byte << bit_displacement ) & UCHAR_MAX ) != 0 ) + return 0 /* FALSE */; + current_byte += 1; + bit_length -= CHAR_BIT - bit_displacement; + } + _Pragma( "loopbound min 0 max 7" ) + while ( bit_length >= CHAR_BIT ) { + if ( *current_byte != 0 ) + return 0 /* FALSE */; + current_byte++; + bit_length -= CHAR_BIT; + } + if ( bit_length > 0 && ( *current_byte >> ( CHAR_BIT - bit_length ) ) != 0 ) + return 0 /* FALSE */; + return 1 /* TRUE */; +} + +/* This function sets up new value of all bits of given bit string. + This function is analog of standard C function `memset'. Value of + `bit_displacement' must be non-negative and can be greater than + CHAR_BIT. */ + +void +ammunition_bit_string_set ( void *start_byte, int bit_displacement, int bit, + int bit_length ) +{ + unsigned char *current_byte = ( unsigned char * )start_byte; + unsigned char filling_byte; + int mask; + + if ( bit_length <= 0 ) + return ; + bit = bit != 0; /* 1 or 0 */ + filling_byte = ( bit ? UCHAR_MAX : 0 ); + current_byte += bit_displacement / CHAR_BIT; + bit_displacement %= CHAR_BIT; + if ( bit_displacement != 0 ) { + mask = UCHAR_MAX << ( CHAR_BIT - bit_displacement ); + if ( bit_length < CHAR_BIT - bit_displacement ) + mask |= UCHAR_MAX >> ( bit_displacement + bit_length ); + *current_byte = ( *current_byte & mask ) | ( filling_byte & ~mask ); + current_byte += 1; + bit_length -= CHAR_BIT - bit_displacement; + } + _Pragma( "loopbound min 0 max 8" ) + while ( bit_length >= CHAR_BIT ) { + *current_byte = filling_byte; + current_byte++; + bit_length -= CHAR_BIT; + } + if ( bit_length > 0 ) + *current_byte + = ( *current_byte & ~( UCHAR_MAX << ( CHAR_BIT - bit_length ) ) ) + | ( filling_byte & ( UCHAR_MAX << ( CHAR_BIT - bit_length ) ) ); +} + +/* This function copys a bit string to another bit string. This + function is analog of standard C function `memcpy'. Values of + `to_bit_displacement' and `from_bit_displacement' must be + non-negative and can be greater than CHAR_BIT. The bit string must + be non-overlapped. */ + +void +ammunition_bit_string_copy ( void *to, int to_bit_displacement, + const void *from, int from_bit_displacement, + int bit_length ) +{ + unsigned char *current_to_byte = ( unsigned char * )to; + const unsigned char *current_from_byte = ( unsigned const char * )from; + int byte; + int mask; + + if ( bit_length <= 0 ) + return ; + current_to_byte += to_bit_displacement / CHAR_BIT; + to_bit_displacement %= CHAR_BIT; + current_from_byte += from_bit_displacement / CHAR_BIT; + from_bit_displacement %= CHAR_BIT; + _Pragma( "loopbound min 1 max 8" ) + while ( 1 ) { + byte = ( ( ( *current_from_byte << from_bit_displacement ) & UCHAR_MAX ) + | ( from_bit_displacement != 0 + && bit_length > ( CHAR_BIT - from_bit_displacement ) + ? current_from_byte [1] >> ( CHAR_BIT - from_bit_displacement ) + : 0 ) ); + if ( bit_length <= CHAR_BIT ) + break; + /* Shift is correct when to_bit_displacement == 0 because its + value is less than word bit size. */ + *current_to_byte + = ( *current_to_byte + & ( UCHAR_MAX << ( CHAR_BIT - to_bit_displacement ) ) ) + | ( byte >> to_bit_displacement ); + if ( to_bit_displacement != 0 ) + current_to_byte [1] + = ( current_to_byte [1] & ( UCHAR_MAX >> to_bit_displacement ) ) + | ( byte << ( CHAR_BIT - to_bit_displacement ) ); + bit_length -= CHAR_BIT; + current_from_byte++; + current_to_byte++; + } + /* Shift is correct when to_bit_displacement == 0 because its + value is less than word bit size. */ + mask = ( ( UCHAR_MAX << ( CHAR_BIT - to_bit_displacement ) ) + | ( UCHAR_MAX >> ( to_bit_displacement + bit_length ) ) ); + *current_to_byte + = ( *current_to_byte & mask ) | ( ( byte >> to_bit_displacement ) & ~mask ); + bit_length -= CHAR_BIT - to_bit_displacement; + if ( bit_length > 0 ) + current_to_byte [1] + = ( current_to_byte [1] & ( UCHAR_MAX >> bit_length ) ) + | ( ( byte << ( CHAR_BIT - to_bit_displacement ) ) + & ( UCHAR_MAX << ( CHAR_BIT - bit_length ) ) ); +} + +/* This function copys a bit string to another bit string. Copying + starts with the last bits of the bit strings. This function is + used by function `bit_string_move'. Values of + `to_bit_displacement' and `from_bit_displacement' must be + non-negative and can be greater than CHAR_BIT. The bit string must + be non-overlapped. */ + +void ammunition_reverse_bit_string_copy ( void *to, int to_bit_displacement, + const void *from, int from_bit_displacement, + int bit_length ) +{ + unsigned char *current_to_byte = ( unsigned char * )to; + const unsigned char *current_from_byte = ( unsigned const char * )from; + int byte; + int mask; + + if ( bit_length <= 0 ) + return ; + to_bit_displacement += bit_length - 1; + current_to_byte += to_bit_displacement / CHAR_BIT; /* last byte */ + to_bit_displacement %= CHAR_BIT; /* last bit */ + from_bit_displacement += bit_length - 1; + current_from_byte += from_bit_displacement / CHAR_BIT; /* last byte */ + from_bit_displacement %= CHAR_BIT; /* last bit */ + _Pragma( "loopbound min 1 max 8" ) + while ( 1 ) { + /* Shift is correct when to_bit_displacement == 0 because its + value is less than word bit size. */ + byte = ( ( *current_from_byte >> ( CHAR_BIT - 1 - from_bit_displacement ) ) + | ( ( from_bit_displacement != CHAR_BIT - 1 + && bit_length > from_bit_displacement + 1 + ? current_from_byte [ -1 ] << ( from_bit_displacement + 1 ) + : 0 ) + & UCHAR_MAX ) ); + if ( bit_length <= CHAR_BIT ) + break; + /* Shift is correct when to_bit_displacement == 0 because its + value is less than word bit size. */ + *current_to_byte + = ( *current_to_byte & ( UCHAR_MAX >> ( to_bit_displacement + 1 ) ) ) + | ( byte << ( CHAR_BIT - 1 - to_bit_displacement ) ); + if ( to_bit_displacement != CHAR_BIT - 1 ) + current_to_byte [-1] + = ( current_to_byte [-1] + & ( UCHAR_MAX << ( CHAR_BIT - 1 - to_bit_displacement ) ) ) + | ( byte >> ( to_bit_displacement + 1 ) ); + bit_length -= CHAR_BIT; + current_from_byte--; + current_to_byte--; + } + /* Shift is correct when to_bit_displacement == 0 because its + value is less than word bit size. */ + mask = ( ( UCHAR_MAX >> ( to_bit_displacement + 1 ) ) | + ( UCHAR_MAX << ( CHAR_BIT - 1 - to_bit_displacement + + bit_length ) ) ); + *current_to_byte + = ( *current_to_byte & mask ) + | ( ( byte << ( CHAR_BIT - 1 - to_bit_displacement ) ) & ~mask ); + bit_length -= to_bit_displacement + 1; + if ( bit_length > 0 ) + current_to_byte [-1] + = ( current_to_byte [-1] & ( UCHAR_MAX << bit_length ) ) + | ( byte >> ( to_bit_displacement + 1 ) + & ( UCHAR_MAX >> ( CHAR_BIT - bit_length ) ) ); +} + +/* This function copys a bit string to another bit string with the aid + of functions `bit_string_copy' and `reverse_bit_string_copy'. This + function is analog of standard C function `memmove'. Values of + `to_bit_displacement' and `from_bit_displacement' must be + non-negative and can be greater than CHAR_BIT. The bit string can + be overlapped. */ + +void +ammunition_bit_string_move ( void *to, int to_bit_displacement, + const void *from, int from_bit_displacement, + int bit_length ) +{ + unsigned char *current_to_byte = ( unsigned char * )to; + const unsigned char *current_from_byte = ( unsigned const char * )from; + + if ( bit_length <= 0 ) + return ; + current_to_byte += to_bit_displacement / CHAR_BIT; + to_bit_displacement %= CHAR_BIT; + current_from_byte += from_bit_displacement / CHAR_BIT; + from_bit_displacement %= CHAR_BIT; + if ( current_from_byte > current_to_byte + || ( current_from_byte == current_to_byte + && from_bit_displacement > to_bit_displacement ) ) + ammunition_bit_string_copy ( current_to_byte, to_bit_displacement, + current_from_byte, from_bit_displacement, + bit_length ); + else + ammunition_reverse_bit_string_copy ( current_to_byte, to_bit_displacement, + current_from_byte, + from_bit_displacement, bit_length ); +} + +/* This function compares bit strings. This function is analog of + standard C function `memcmp'. The function returns 0 if the bit + strings are equal, 1 if the first bit string is greater than the + second, -1 if the first bit string is less than the first. Values + of `bit_displacement1' and `bit_displacement2' must be non-negative + and can be greater than CHAR_BIT. */ + +int +ammunition_bit_string_comparison ( const void *str1, int bit_displacement1, + const void *str2, int bit_displacement2, + int bit_length ) +{ + const unsigned char *current_byte1 = ( unsigned const char * )str1; + const unsigned char *current_byte2 = ( unsigned const char * )str2; + int byte1; + int byte2; + int mask; + + if ( bit_length <= 0 ) + return 0; + current_byte1 += bit_displacement1 / CHAR_BIT; + bit_displacement1 %= CHAR_BIT; + current_byte2 += bit_displacement2 / CHAR_BIT; + bit_displacement2 %= CHAR_BIT; + _Pragma( "loopbound min 1 max 284" ) + while ( 1 ) { + byte1 = ( ( ( *current_byte1 << bit_displacement1 ) & UCHAR_MAX ) + | ( bit_displacement1 != 0 + /* Shift is correct when to_bit_displacement == 0 + because its value is less than word bit size. */ + && bit_length > CHAR_BIT - bit_displacement1 + ? current_byte1 [1] >> ( CHAR_BIT - bit_displacement1 ) + : 0 ) ); + byte2 = ( ( ( *current_byte2 << bit_displacement2 ) & UCHAR_MAX ) + | ( bit_displacement2 != 0 + && bit_length > CHAR_BIT - bit_displacement2 + ? current_byte2 [1] >> ( CHAR_BIT - bit_displacement2 ) + : 0 ) ); + if ( bit_length <= CHAR_BIT ) + break; + if ( byte1 > byte2 ) + return 1; + else + if ( byte1 < byte2 ) + return -1; + bit_length -= CHAR_BIT; + current_byte2++; + current_byte1++; + } + /* Shift is correct when to_bit_displacement == 0 because its value + is less than word bit size. */ + mask = UCHAR_MAX << ( CHAR_BIT - bit_length ); + if ( ( byte1 & mask ) > ( byte2 & mask ) ) + return 1; + else + if ( ( byte1 & mask ) < ( byte2 & mask ) ) + return -1; + else + return 0; +} diff --git a/baseline/source/ammunition/bits.h b/baseline/source/ammunition/bits.h new file mode 100644 index 0000000..70cf8bd --- /dev/null +++ b/baseline/source/ammunition/bits.h @@ -0,0 +1,60 @@ +/* + FILE NAME: bits.h + + TITLE: Include file of package for work with bits + + DESCRIPTION: + This is header file contains macros and the ANSI C prototype + definitions for the package for work with bits and bit strings + and C++ class for work with bits and bit strings. A bit is + given by address (start address) of byte from which counting + bits starts and its displacement which is any non negative + number of bit from the start address. The most significant bit + of the start address byte has number 0. The bit string is + given by its first bit and its length in bits. + +*/ + +#ifndef __BITS__ +#define __BITS__ + +#include "ammunition_limits.h" + +/* This macro value returns bit vlaue (0 or 1) with given bit + displacement (0, 1, ...). The macro has side effects! Value of + `bit_displacement' must be nonegative and can be greater than + CHAR_BIT. */ + +#define BIT(start_byte, bit_displacement)\ + ((((const char *) (start_byte)) [(bit_displacement) / CHAR_BIT]\ + >> (CHAR_BIT - 1 - (bit_displacement) % CHAR_BIT)) & 1) + + +/* This macro value sets up new value (must be `0' or `1') of a given + bit (bit displacement starts with 0). The macro has side effects! + Value of `bit_displacement' must be nonegative and can be greater + than CHAR_BIT. */ + +#define SET_BIT(start_byte, bit_displacement, bit)\ + (((char *) (start_byte)) [(bit_displacement) / CHAR_BIT]\ + = (((char *) (start_byte)) [(bit_displacement) / CHAR_BIT]\ + & ~(1 << (CHAR_BIT - 1 - (bit_displacement) % CHAR_BIT)))\ + | ((bit) << (CHAR_BIT - 1 - (bit_displacement) % CHAR_BIT))) + +int ammunition_is_zero_bit_string ( const void *start_byte, + int bit_displacement, + int bit_length ); +void ammunition_bit_string_set ( void *start_byte, int bit_displacement, + int bit, + int bit_length ); +void ammunition_bit_string_copy ( void *to, int to_bit_displacement, + const void *from, int from_bit_displacement, + int bit_length ); +void ammunition_bit_string_move ( void *to, int to_bit_displacement, + const void *from, int from_bit_displacement, + int bit_length ); +int ammunition_bit_string_comparison ( const void *str1, int bit_displacement1, + const void *str2, int bit_displacement2, + int bit_length ); + +#endif /* #ifndef __BITS__ */ diff --git a/baseline/source/ammunition/gmon.out b/baseline/source/ammunition/gmon.out new file mode 100644 index 0000000..2d07b7f Binary files /dev/null and b/baseline/source/ammunition/gmon.out differ diff --git a/baseline/source/ammunition/timeScript b/baseline/source/ammunition/timeScript new file mode 100644 index 0000000..33ba812 --- /dev/null +++ b/baseline/source/ammunition/timeScript @@ -0,0 +1,8 @@ +#!/bin/bash +startTime=$(date +%N) +echo start time $startTime +$1 +stopTime=$(date +%N) +echo stop time $stopTime +totalTime=`expr $stopTime - $startTime` +echo total time $totalTime -- cgit v1.2.2