void DoMul( void ) { stack_entry *left; xreal re, im, t1, t2; left = StkEntry( 1 ); BinOp( left, ExprSP ); switch( left->info.kind ) { case TK_BOOL: case TK_ENUM: case TK_CHAR: case TK_INTEGER: U64Mul( &left->v.uint, &ExprSP->v.uint, &left->v.uint ); break; case TK_REAL: LDMul( &left->v.real, &ExprSP->v.real, &left->v.real ); break; case TK_COMPLEX: /* (a,b) * (c,d) = (ac-bd,ad+bc) */ LDMul( &left->v.cmplx.re, &ExprSP->v.cmplx.re, &t1 ); LDMul( &left->v.cmplx.im, &ExprSP->v.cmplx.im, &t2 ); LDSub( &t1, &t2, &re ); LDMul( &left->v.cmplx.re, &ExprSP->v.cmplx.im, &t1 ); LDMul( &left->v.cmplx.im, &ExprSP->v.cmplx.re, &t2 ); LDAdd( &t1, &t2, &im ); left->v.cmplx.re = re; left->v.cmplx.im = im; break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); break; } CombineEntries( left, left, ExprSP ); }
BOOL StrToU64( char *str, unsigned_64 *u64, BOOL neg ) { unsigned_64 r64; unsigned_64 v64; int value; int radix; str = eatSpace( str ); U32ToU64( 0, u64 ); if( neg == TRUE ) { if( *str == '-') { str++; } else { if( *str == '+' ) { str++; neg = FALSE; } } } str = eatSpace( str ); switch( *str ){ case '\0': return( FALSE ); case '0': str++; if( tolower(*str) == 'x' ) { radix = 16; str++; } else { radix = 8; } break; default: radix = 10; } U32ToU64( radix, &r64 ); while( *str != '\0' ) { if( isdigit( *str ) ) { value = *str - '0'; } else { value = 10 + tolower( *str ) - 'a'; } if( value < 0 || value >= radix ) { return ( FALSE ); } U32ToU64( value, &v64 ); U64Mul( u64, &r64, u64 ); U64Add( &v64, u64, u64 ); str++; } if( neg == TRUE) { U64Neg( u64, u64 ); } return( TRUE ); }
static bool GetNum( unsigned base ) { bool ok; unsigned_64 num; unsigned_64 big_base; unsigned_64 big_dig; int dig; ok = FALSE; U32ToU64( base, &big_base ); U64Clear( num ); for( ; ; ) { dig = GetDig( base ); if( dig < 0 ) break; U32ToU64( dig, &big_dig ); U64Mul( &num, &big_base, &num ); U64Add( &num, &big_dig, &num ); ++ScanPtr; ok = TRUE; } TokenVal.int_val = num; return( ok ); }
int64 operator*( const int64 & a ) const { int64 result; U64Mul( &this->_d, &a._d, &result._d ); return( result ); }
static PTREE foldInt64( CGOP op, PTREE left, signed_64 v2 ) { signed_64 test; signed_64 v1; float_handle t0, t1, t2; v1 = left->u.int64_constant; switch( op ) { case CO_PLUS: U64Add( &v1, &v2, &left->u.int64_constant ); break; case CO_MINUS: U64Sub( &v1, &v2, &left->u.int64_constant ); break; case CO_TIMES: t0 = BFCnvI64F( v1 ); t1 = BFCnvI64F( v2 ); t2 = BFMul( t0, t1 ); test = BFCnvF64( t2 ); BFFree( t0 ); BFFree( t1 ); BFFree( t2 ); U64Mul( &v1, &v2, &left->u.int64_constant ); if( 0 != I64Cmp( &test, &left->u.int64_constant ) ) { CErr1( ANSI_ARITHMETIC_OVERFLOW ); } break; case CO_DIVIDE: { signed_64 rem; idiv64( &v1, &v2, &left->u.int64_constant, &rem ); } break; case CO_PERCENT: { signed_64 div; idiv64( &v1, &v2, &div, &left->u.int64_constant ); } break; case CO_AND: left->u.int64_constant.u._32[0] = v1.u._32[0] & v2.u._32[0]; left->u.int64_constant.u._32[1] = v1.u._32[1] & v2.u._32[1]; break; case CO_OR: left->u.int64_constant.u._32[0] = v1.u._32[0] | v2.u._32[0]; left->u.int64_constant.u._32[1] = v1.u._32[1] | v2.u._32[1]; break; case CO_XOR: left->u.int64_constant.u._32[0] = v1.u._32[0] ^ v2.u._32[0]; left->u.int64_constant.u._32[1] = v1.u._32[1] ^ v2.u._32[1]; break; case CO_RSHIFT: I64ShiftR( &v1, v2.u._32[ I64LO32 ], &left->u.int64_constant ); break; case CO_LSHIFT: U64ShiftL( &v1, v2.u._32[ I64LO32 ], &left->u.int64_constant ); break; case CO_EQ: left = makeBooleanConst( left, 0 == I64Cmp( &v1, &v2 ) ); return( left ); case CO_NE: left = makeBooleanConst( left, 0 != I64Cmp( &v1, &v2 ) ); return( left ); case CO_GT: left = makeBooleanConst( left, 0 < I64Cmp( &v1, &v2 )) ; return( left ); case CO_LE: left = makeBooleanConst( left, 0 >= I64Cmp( &v1, &v2 ) ); return( left ); case CO_LT: left = makeBooleanConst( left, 0 > I64Cmp( &v1, &v2 )) ; return( left ); case CO_GE: left = makeBooleanConst( left, 0 <= I64Cmp( &v1, &v2 ) ); return( left ); case CO_AND_AND: left = makeBooleanConst( left, !Zero64( &v1 ) && !Zero64( &v2 ) ); return( left ); case CO_OR_OR: left = makeBooleanConst( left, !Zero64( &v1) || !Zero64( &v2 ) ); return( left ); case CO_COMMA: left->u.int64_constant = v2; break; default: return( NULL ); } left->op = PT_INT_CONSTANT; return( left ); }