Linux test merged.
This commit is contained in:
126
test_i32_overflow.cpp
Normal file
126
test_i32_overflow.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
inline void throw_overflow ()
|
||||
{
|
||||
throw std::runtime_error( "Overflow!!!" );
|
||||
}
|
||||
|
||||
#define E void (*err)()
|
||||
|
||||
//template <class E>
|
||||
inline int add( int op1, int op2, E )
|
||||
{
|
||||
asm ( "add %1, %0"
|
||||
: "=r"(op1)
|
||||
: "r"(op2),"0"(op1) );
|
||||
asm goto( "jo %l[throw_exception]"
|
||||
: : : "memory"
|
||||
: throw_exception );
|
||||
return op1;
|
||||
|
||||
throw_exception:
|
||||
err();
|
||||
}
|
||||
|
||||
//template <class E>
|
||||
inline long add( long op1, long op2, E)
|
||||
{
|
||||
asm ( "add %1, %0"
|
||||
: "=r"(op1)
|
||||
: "r"(op2),"0"(op1) );
|
||||
asm goto( "jo %l[throw_exception]"
|
||||
: : : "memory"
|
||||
: throw_exception );
|
||||
return op1;
|
||||
|
||||
throw_exception:
|
||||
err();
|
||||
}
|
||||
|
||||
// Just test a possible implementation for 386
|
||||
//template <class E>
|
||||
inline long long add( long long op1, long long op2, E )
|
||||
{
|
||||
unsigned int op1l = (unsigned int)op1;
|
||||
unsigned int op1h = (unsigned int)((unsigned long long)op1 >> 32);
|
||||
unsigned int op2l = (unsigned int)op2;
|
||||
unsigned int op2h = (unsigned int)((unsigned long long)op2 >> 32);
|
||||
asm ( "add %2, %0\n"
|
||||
"adc %3, %1"
|
||||
: "=a"(op1l),"=d"(op1h)
|
||||
: "g"(op2l),"g"(op2h),"0"(op1l),"1"(op1h) );
|
||||
asm goto( "jo %l[throw_exception]"
|
||||
: : : "memory"
|
||||
: throw_exception );
|
||||
return (long long)((unsigned long long)op1l | ((unsigned long long)op1h << 32));
|
||||
|
||||
throw_exception:
|
||||
err();
|
||||
}
|
||||
|
||||
#if 0
|
||||
//
|
||||
//GCC 4.5.2 crashes on this template.
|
||||
//I filed a bug against GCC. #55528
|
||||
//
|
||||
template <class C>
|
||||
inline C add2( C op1, C op2 )
|
||||
{
|
||||
asm ( "add %1, %0"
|
||||
: "=r"(op1)
|
||||
: "r"(op2),"0"(op1) );
|
||||
asm goto( "jo %l[throw_exception]"
|
||||
: : : "memory"
|
||||
: throw_exception );
|
||||
return op1;
|
||||
|
||||
throw_exception:
|
||||
return throw_overflow();
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class C>
|
||||
inline void test_add( C op1, C op2 )
|
||||
{try
|
||||
{
|
||||
std::cout << op1 << " + " << op2 << " = ";
|
||||
std::cout.flush();
|
||||
C r = add( op1, op2, &throw_overflow );
|
||||
std::cout << r << std::endl;
|
||||
}
|
||||
catch ( const std::exception& e )
|
||||
{
|
||||
std::cout << e.what() << std::endl;
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
std::cout << "unknown exception" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main( void )
|
||||
{
|
||||
test_add( 10, 20);
|
||||
test_add( 100, 200);
|
||||
test_add( 1000, 2000);
|
||||
test_add( 1000000000, 2000000000);
|
||||
test_add( 1000000000, -2000000000);
|
||||
test_add( -1000000000, 2000000000);
|
||||
test_add( -1000000000, -2000000000);
|
||||
test_add( 1000000000L, 2000000000L);
|
||||
test_add( 1000000000L,-2000000000L);
|
||||
test_add( -1000000000L, 2000000000L);
|
||||
test_add( -1000000000L,-2000000000L);
|
||||
test_add( 7000000000000000000L, 8000000000000000000L);
|
||||
test_add( 7000000000000000000L, -8000000000000000000L);
|
||||
test_add( -7000000000000000000L, 8000000000000000000L);
|
||||
test_add( -7000000000000000000L, -8000000000000000000L);
|
||||
test_add( (long long)7000000000000000000L, (long long)8000000000000000000L);
|
||||
test_add( (long long)7000000000000000000L, (long long)-8000000000000000000L);
|
||||
test_add( (long long)-7000000000000000000L, (long long)8000000000000000000L);
|
||||
test_add( (long long)-7000000000000000000L, (long long)-8000000000000000000L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user