diff --git a/tests/Makefile b/tests/Makefile index 4492635..73e0c07 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,31 +1,31 @@ -CC = g++ -o = main.o uinttest.o -CFLAGS = -Wall -pedantic -ttmath = /d/roboczy/prog/ttmath -name = tests - - - -.SUFFIXES: .cpp .o - -.cpp.o: - $(CC) -c $(CFLAGS) -I$(ttmath) $< - - -all: $(name) - - -$(name): $(o) - $(CC) -o $(name) $(CFLAGS) -I$(ttmath) $(o) - - -main.o: main.cpp uinttest.h -uinttest.o: uinttest.cpp uinttest.h - - -clean: - rm -f *.o - rm -f $(name) - rm -f $(name).exe - - +CC = g++ +o = main.o uinttest.o +CFLAGS = -Wall -pedantic +ttmath = .. +name = tests + + + +.SUFFIXES: .cpp .o + +.cpp.o: + $(CC) -c $(CFLAGS) -I$(ttmath) $< + + +all: $(name) + + +$(name): $(o) + $(CC) -o $(name) $(CFLAGS) -I$(ttmath) $(o) + + +main.o: main.cpp uinttest.h +uinttest.o: uinttest.cpp uinttest.h + + +clean: + rm -f *.o + rm -f $(name) + rm -f $(name).exe + + diff --git a/tests/main.cpp b/tests/main.cpp index b052c4a..52f31f6 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -36,35 +36,33 @@ */ -#include -#include -#include "uinttest.h" - - -const char uint_tests_file[] = "tests.uint32"; - - -void test_uint() -{ - UIntTest test; - - test.set_file_name(uint_tests_file); - test.go(); -} - - - -int main() -{ -using namespace ttmath; - - - - test_uint(); - - - - - -return 0; -} +#include +#include +#include "uinttest.h" + + +const char uint_tests_file[] = "tests.uint32"; + + +void test_uint() +{ + UIntTest test; + + test.set_file_name(uint_tests_file); + test.go(); +} + + + +int main() +{ +using namespace ttmath; + + test_uint(); + + + + + +return 0; +} diff --git a/tests/tests.uint32 b/tests/tests.uint32 index c890d97..7aeabd6 100644 --- a/tests/tests.uint32 +++ b/tests/tests.uint32 @@ -1,63 +1,63 @@ -# Add - -# min_bits max_bits a b result carry -add 32 0 0 0 0 0 -add 32 0 1 1 2 0 -add 32 0 2342234 3563456 5905690 0 -add 32 0 254455 3453435 3707890 0 -add 32 0 4294967295 0 4294967295 0 - -# testing a carry for add -add 32 32 4294967295 1 0 1 -add 32 32 4294967295 0 4294967295 0 -add 64 64 18446744073709551615 1 0 1 -add 64 64 18446744073709551615 0 18446744073709551615 0 -add 96 96 79228162514264337593543950335 1 0 1 -add 96 96 79228162514264337593543950335 0 79228162514264337593543950335 0 -add 128 128 340282366920938463463374607431768211455 1 0 1 -add 128 128 340282366920938463463374607431768211455 0 340282366920938463463374607431768211455 0 -add 160 160 1461501637330902918203684832716283019655932542975 1 0 1 -add 160 160 1461501637330902918203684832716283019655932542975 0 1461501637330902918203684832716283019655932542975 0 -add 192 192 6277101735386680763835789423207666416102355444464034512895 1 0 1 -add 192 192 6277101735386680763835789423207666416102355444464034512895 0 6277101735386680763835789423207666416102355444464034512895 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Add + +# min_bits max_bits a b result carry +add 32 0 0 0 0 0 +add 32 0 1 1 2 0 +add 32 0 2342234 3563456 5905690 0 +add 32 0 254455 3453435 3707890 0 +add 32 0 4294967295 0 4294967295 0 + +# testing a carry for add +add 32 32 4294967295 1 0 1 +add 32 32 4294967295 0 4294967295 0 +add 64 64 18446744073709551615 1 0 1 +add 64 64 18446744073709551615 0 18446744073709551615 0 +add 96 96 79228162514264337593543950335 1 0 1 +add 96 96 79228162514264337593543950335 0 79228162514264337593543950335 0 +add 128 128 340282366920938463463374607431768211455 1 0 1 +add 128 128 340282366920938463463374607431768211455 0 340282366920938463463374607431768211455 0 +add 160 160 1461501637330902918203684832716283019655932542975 1 0 1 +add 160 160 1461501637330902918203684832716283019655932542975 0 1461501637330902918203684832716283019655932542975 0 +add 192 192 6277101735386680763835789423207666416102355444464034512895 1 0 1 +add 192 192 6277101735386680763835789423207666416102355444464034512895 0 6277101735386680763835789423207666416102355444464034512895 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/uinttest.cpp b/tests/uinttest.cpp index b696b09..3fd41d6 100644 --- a/tests/uinttest.cpp +++ b/tests/uinttest.cpp @@ -36,206 +36,206 @@ */ -#include "uinttest.h" - - - -void UIntTest::set_file_name(const std::string & f) -{ - file_name = f; -} - - -int UIntTest::read_int() -{ -int result = 0; - - skip_white_characters(); - - for( ; *pline>='0' && *pline<='9' ; ++pline ) - result = result * 10 + (*pline - '0'); - -return result; -} - - - -template -void UIntTest::test_add() -{ -using namespace ttmath; - - UInt a,b,result, new_result; - - int min_bits = read_int(); - int max_bits = read_int(); - - if( min_bits != 0 && type_size * TTMATH_BITS_PER_UINT < (unsigned int)min_bits ) - return; - - if( max_bits != 0 && type_size * TTMATH_BITS_PER_UINT > (unsigned int)max_bits ) - return; - - a.FromString(pline, 10, &pline); - b.FromString(pline, 10, &pline); - result.FromString(pline, 10, &pline); - int carry = read_int(); - - std::cerr << '[' << row << "] Add<" << type_size << ">: "; - - skip_white_characters(); - if( *pline!='#' && *pline!= 0 ) - { - std::cerr << "syntax error" << std::endl; - return; - } - - new_result = a; - int new_carry = new_result.Add(b); - bool ok = true; - - if( new_carry != carry ) - { - std::cerr << "Incorrect carry: " << new_carry << " (expected: " << carry << ")" << std::endl; - ok = false; - } - - if( new_result != result ) - { - std::cerr << "Incorrect result: " << new_result << " (expected: " << result << ")" << std::endl; - ok = false; - } - - if( ok ) - { - std::cerr << "ok" << std::endl; - } -} - - - - -int UIntTest::upper_char(int c) -{ - if( c>='a' && c<='z' ) - return c - 'a' + 'A'; - -return c; -} - - -bool UIntTest::is_white(int c) -{ - if( c==' ' || c=='\t' || c==13 ) - return true; - -return false; -} - - -void UIntTest::skip_white_characters() -{ - while( is_white(*pline) ) - ++pline; -} - - - -bool UIntTest::read_method() -{ - skip_white_characters(); - - if( *pline == '#' ) - return false; - - method.clear(); - - for(int c = upper_char(*pline) ; c>='A'&& c<='Z' ; c = upper_char(*pline) ) - { - method += c; - ++pline; - } - - if( method.empty() ) - { - skip_white_characters(); - if( *pline == 0 ) - return false; - else - { - std::cerr << '[' << row << "] "; - std::cerr << "syntax error" << std::endl; - return false; - } - } - - -return true; -} - - -void UIntTest::test_method() -{ -const char * p = pline; - - if( method == "ADD" ) - { - pline = p; test_add<1>(); - pline = p; test_add<2>(); - pline = p; test_add<3>(); - pline = p; test_add<4>(); - pline = p; test_add<5>(); - pline = p; test_add<6>(); - pline = p; test_add<7>(); - pline = p; test_add<8>(); - pline = p; test_add<9>(); - } - else - { - std::cerr << '[' << row << "] "; - std::cerr << "method " << method << " is not supported" << std::endl; - } -} - - -bool UIntTest::check_line() -{ - std::getline(file, line); - - pline = line.c_str(); - - if( read_method() ) - test_method(); - - - if( file.eof() ) - return false; - - -return true; -} - - - - -void UIntTest::go() -{ - file.open(file_name.c_str()); - - - if( !file ) - { - std::cerr << "I can't open the input file" << std::endl; - return; - } - - row = 1; - - while( check_line() ) - ++row; - -} - - - - +#include "uinttest.h" + + + +void UIntTest::set_file_name(const std::string & f) +{ + file_name = f; +} + + +int UIntTest::read_int() +{ +int result = 0; + + skip_white_characters(); + + for( ; *pline>='0' && *pline<='9' ; ++pline ) + result = result * 10 + (*pline - '0'); + +return result; +} + + + +template +void UIntTest::test_add() +{ +using namespace ttmath; + + UInt a,b,result, new_result; + + int min_bits = read_int(); + int max_bits = read_int(); + + if( min_bits != 0 && type_size * TTMATH_BITS_PER_UINT < (unsigned int)min_bits ) + return; + + if( max_bits != 0 && type_size * TTMATH_BITS_PER_UINT > (unsigned int)max_bits ) + return; + + a.FromString(pline, 10, &pline); + b.FromString(pline, 10, &pline); + result.FromString(pline, 10, &pline); + int carry = read_int(); + + std::cerr << '[' << row << "] Add<" << type_size << ">: "; + + skip_white_characters(); + if( *pline!='#' && *pline!= 0 ) + { + std::cerr << "syntax error" << std::endl; + return; + } + + new_result = a; + int new_carry = new_result.Add(b); + bool ok = true; + + if( new_carry != carry ) + { + std::cerr << "Incorrect carry: " << new_carry << " (expected: " << carry << ")" << std::endl; + ok = false; + } + + if( new_result != result ) + { + std::cerr << "Incorrect result: " << new_result << " (expected: " << result << ")" << std::endl; + ok = false; + } + + if( ok ) + { + std::cerr << "ok" << std::endl; + } +} + + + + +int UIntTest::upper_char(int c) +{ + if( c>='a' && c<='z' ) + return c - 'a' + 'A'; + +return c; +} + + +bool UIntTest::is_white(int c) +{ + if( c==' ' || c=='\t' || c==13 ) + return true; + +return false; +} + + +void UIntTest::skip_white_characters() +{ + while( is_white(*pline) ) + ++pline; +} + + + +bool UIntTest::read_method() +{ + skip_white_characters(); + + if( *pline == '#' ) + return false; + + method.clear(); + + for(int c = upper_char(*pline) ; c>='A'&& c<='Z' ; c = upper_char(*pline) ) + { + method += c; + ++pline; + } + + if( method.empty() ) + { + skip_white_characters(); + if( *pline == 0 ) + return false; + else + { + std::cerr << '[' << row << "] "; + std::cerr << "syntax error" << std::endl; + return false; + } + } + + +return true; +} + + +void UIntTest::test_method() +{ +const char * p = pline; + + if( method == "ADD" ) + { + pline = p; test_add<1>(); + pline = p; test_add<2>(); + pline = p; test_add<3>(); + pline = p; test_add<4>(); + pline = p; test_add<5>(); + pline = p; test_add<6>(); + pline = p; test_add<7>(); + pline = p; test_add<8>(); + pline = p; test_add<9>(); + } + else + { + std::cerr << '[' << row << "] "; + std::cerr << "method " << method << " is not supported" << std::endl; + } +} + + +bool UIntTest::check_line() +{ + std::getline(file, line); + + pline = line.c_str(); + + if( read_method() ) + test_method(); + + + if( file.eof() ) + return false; + + +return true; +} + + + + +void UIntTest::go() +{ + file.open(file_name.c_str()); + + + if( !file ) + { + std::cerr << "I can't open the input file" << std::endl; + return; + } + + row = 1; + + while( check_line() ) + ++row; + +} + + + + diff --git a/tests/uinttest.h b/tests/uinttest.h index bc4d649..69933de 100644 --- a/tests/uinttest.h +++ b/tests/uinttest.h @@ -36,55 +36,55 @@ */ -#ifndef headerfileuinttest -#define headerfileuinttest - -#include -#include -#include - -#include - - - - -class UIntTest -{ - - std::string file_name; - - // current line from the file - std::string line; - const char * pline; - - std::ifstream file; - - - std::string method; - - int row; - -public: - - void set_file_name(const std::string & f); - - void go(); - - template - void test_add(); - - -int upper_char(int c); -bool is_white(int c); -void skip_white_characters(); -bool read_method(); -void test_method(); -bool check_line(); -int read_int(); - - - -}; - - -#endif +#ifndef headerfileuinttest +#define headerfileuinttest + +#include +#include +#include + +#include + + + + +class UIntTest +{ + + std::string file_name; + + // current line from the file + std::string line; + const char * pline; + + std::ifstream file; + + + std::string method; + + int row; + +public: + + void set_file_name(const std::string & f); + + void go(); + + template + void test_add(); + + +int upper_char(int c); +bool is_white(int c); +void skip_white_characters(); +bool read_method(); +void test_method(); +bool check_line(); +int read_int(); + + + +}; + + +#endif diff --git a/ttmath/ttmathuint.h b/ttmath/ttmathuint.h index 01ae44a..0046361 100644 --- a/ttmath/ttmathuint.h +++ b/ttmath/ttmathuint.h @@ -265,9 +265,9 @@ public: xor eax,eax sub eax,[c] - lahf // flags -> AH (flags: SF ZF AF CF) PF? + lahf // flags -> AH (flags: SF ZF AF PF CF) p: - sahf // AH -> flags (flags: SF ZF AF CF) PF? + sahf // AH -> flags (flags: SF ZF AF PF CF) mov eax,[ebx] adc eax,[edx] mov [ebx],eax @@ -276,7 +276,7 @@ public: add ebx,4 add edx,4 - sub ecx,1 + dec ecx jnz p // checking carry from the last word @@ -318,7 +318,7 @@ public: "add $4,%%ebx \n" "add $4,%%edx \n" - "subl $1,%%ecx \n" + "decl %%ecx \n" "jnz 1b \n" "test $1,%%ah \n" diff --git a/ttmath/ttmathuint64.h b/ttmath/ttmathuint64.h index 8de3684..02adb0f 100644 --- a/ttmath/ttmathuint64.h +++ b/ttmath/ttmathuint64.h @@ -225,37 +225,36 @@ namespace ttmath "push %%rcx \n" "push %%rdx \n" - "movq $0, %%rax \n" + "xorq %%rax, %%rax \n" "subq %%rsi, %%rax \n" + //"lahf \n" + // in order to use this instruction one need to use -msahf option of the GCC + // but in my compiler (gcc version 4.2.1) there is no such option + // at the moment I'm using the opcode of this instruction + // In the future this can be simply change into 'lahf' + ".byte 0x9f \n" + "1: \n" + //"sahf \n" + ".byte 0x9e \n" + "movq (%%rbx),%%rax \n" "adcq (%%rdx),%%rax \n" "movq %%rax,(%%rbx) \n" - - "inc %%rbx \n" - "inc %%rbx \n" - "inc %%rbx \n" - "inc %%rbx \n" - "inc %%rbx \n" - "inc %%rbx \n" - "inc %%rbx \n" - "inc %%rbx \n" - - "inc %%rdx \n" - "inc %%rdx \n" - "inc %%rdx \n" - "inc %%rdx \n" - "inc %%rdx \n" - "inc %%rdx \n" - "inc %%rdx \n" - "inc %%rdx \n" - - "loop 1b \n" - "movq $0, %%rax \n" - "adcq %%rax,%%rax \n" - "movq %%rax, %%rsi \n" + //"lahf \n" + ".byte 0x9f \n" + + "addq $8, %%rbx \n" + "addq $8, %%rdx \n" + + "decq %%rcx \n" + "jnz 1b \n" + + "test $1, %%ah \n" + "setnz %%al \n" + "movzx %%al, %%rsi \n" "pop %%rdx \n" "pop %%rcx \n" @@ -680,11 +679,14 @@ namespace ttmath "push %%rbx \n" "push %%rcx \n" - "lahf \n" + //"lahf \n" + ".byte 0x9f \n" "1: \n" - "sahf \n" + //"sahf \n" + ".byte 0x9e \n" "rclq $1,(%%rbx) \n" - "lahf \n" + //"lahf \n" + ".byte 0x9f \n" "addq $8,%%rbx \n" @@ -698,7 +700,8 @@ namespace ttmath "jnz 2b \n" "xor %%rdx,%%rdx \n" - "sahf \n" + //"sahf \n" + ".byte 0x9e \n" "setc %%dl \n" "pop %%rsi \n" @@ -762,13 +765,17 @@ namespace ttmath "xorq %%rax, %%rax \n" "subq %%rdx, %%rax \n" - "lahf \n" + //"lahf \n" + ".byte 0x9f \n" "1: \n" "subq $8, %%rbx \n" - "sahf \n" + //"sahf \n" + ".byte 0x9e \n" + "rcrq $1,(%%rbx) \n" - "lahf \n" + //"lahf \n" + ".byte 0x9f \n" "subq $1,%%rcx \n" "jnz 1b \n" @@ -781,7 +788,8 @@ namespace ttmath "jnz 2b \n" "xor %%rdx,%%rdx \n" - "sahf \n" + //"sahf \n" + ".byte 0x9e \n" "setc %%dl \n" "pop %%rsi \n"