OVL_EXTERN bool ConvC16( stack_entry *entry, conv_class from ) { if( !ConvC20( entry, from ) ) return( FALSE ); DToLD( (double)LDToD( &entry->v.cmplx.re ), &entry->v.cmplx.re ); DToLD( (double)LDToD( &entry->v.cmplx.im ), &entry->v.cmplx.im ); return( TRUE ); }
OVL_EXTERN bool ConvR10( stack_entry *entry, conv_class from ) { xreal tmp; switch( from ) { case U1: case U2: case U4: case U8: //NYI: 64 bit support DToLD( U32FetchTrunc( entry->v.uint ), &tmp ); break; case I1: case I2: case I4: case I8: //NYI: 64 bit support DToLD( I32FetchTrunc( entry->v.sint ), &tmp ); break; case F4: case F8: case F10: tmp = entry->v.real; break; case C8: case C16: case C20: tmp = entry->v.cmplx.re; break; default: return( FALSE ); } entry->v.real = tmp; return( TRUE ); }
OVL_EXTERN bool ConvC8( stack_entry *entry, conv_class from ) { if( !ConvC20( entry, from ) ) return( false ); DToLD( (float)LDToD( &entry->v.cmplx.re ), &entry->v.cmplx.re ); DToLD( (float)LDToD( &entry->v.cmplx.im ), &entry->v.cmplx.im ); return( true ); }
void DoDiv( void ) { stack_entry *left; xreal re, im, mag, t1, t2; left = StkEntry( 1 ); BinOp( left, ExprSP ); switch( left->info.kind ) { case TK_BOOL: case TK_ENUM: case TK_CHAR: case TK_INTEGER: if( U64Test( &ExprSP->v.uint ) == 0 ) { Error( ERR_NONE, LIT_ENG( ERR_ZERO_DIV ) ); } if( (left->info.modifier & TM_MOD_MASK) == TM_UNSIGNED ) { U64Div( &left->v.uint, &ExprSP->v.uint, &left->v.uint, NULL ); } else { I64Div( &left->v.sint, &ExprSP->v.sint, &left->v.sint, NULL ); } break; case TK_REAL: DToLD( 0.0, &t1 ); if( LDCmp( &ExprSP->v.real, &t1 ) == 0 ) { Error( ERR_NONE, LIT_ENG( ERR_ZERO_DIV ) ); } LDDiv( &left->v.real, &ExprSP->v.real, &left->v.real ); break; case TK_COMPLEX: DToLD( 0.0, &t1 ); if( LDCmp( &ExprSP->v.cmplx.re, &t1 ) == 0 && LDCmp( &ExprSP->v.cmplx.im, &t1 ) == 0 ) { Error( ERR_NONE, LIT_ENG( ERR_ZERO_DIV ) ); } /* (a,b)/(c,d) = (ac+bd,bc-ad) / (c^2+d^2) */ LDMul( &ExprSP->v.cmplx.re, &ExprSP->v.cmplx.re, &t1 ); LDMul( &ExprSP->v.cmplx.im, &ExprSP->v.cmplx.im, &t2 ); LDAdd( &t1, &t2, &mag ); LDMul( &left->v.cmplx.re, &ExprSP->v.cmplx.re, &t1 ); LDMul( &left->v.cmplx.im, &ExprSP->v.cmplx.im, &t2 ); LDAdd( &t1, &t2, &re ); LDMul( &left->v.cmplx.im, &ExprSP->v.cmplx.re, &t1 ); LDMul( &left->v.cmplx.re, &ExprSP->v.cmplx.im, &t2 ); LDSub( &t1, &t2, &im ); LDDiv( &re, &mag, &left->v.cmplx.re ); LDDiv( &im, &mag, &left->v.cmplx.im ); break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); break; } CombineEntries( left, left, ExprSP ); }
OVL_EXTERN bool ConvC20( stack_entry *entry, conv_class from ) { xcomplex tmp; DToLD( 0.0, &tmp.im ); switch( from ) { case U1: case U2: case U4: case U8: //NYI: 64 bit support DToLD( U32FetchTrunc( entry->v.uint ), &tmp.re ); break; case I1: case I2: case I4: case I8: DToLD( I32FetchTrunc( entry->v.sint ), &tmp.re ); break; case F4: case F8: case F10: tmp.re = entry->v.real; break; case C8: case C16: case C20: tmp = entry->v.cmplx; break; default: return( false ); } entry->v.cmplx = tmp; return( true ); }
/* * ConvertTo -- convert 'entry' to the given 'class'. * 'entry' should be an rvalue. */ void ConvertTo( stack_entry *entry, type_kind k, type_modifier m, unsigned s ) { conv_class from; char *dest; if( s == 0 && k == TK_INTEGER ) { s = DefaultSize( DK_INT ); } if( entry->info.kind == k && entry->info.modifier == m && entry->info.size == s ) return; from = ConvIdx( &entry->info ); switch( from ) { case U1: U32ToU64( U8FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case U2: U32ToU64( U16FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case U4: U32ToU64( U32FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case I1: I32ToI64( I8FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case I2: I32ToI64( I16FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case I4: I32ToI64( I32FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case F4: DToLD( (float)LDToD( &entry->v.real ), &entry->v.real ); break; case F8: DToLD( (double)LDToD( &entry->v.real ), &entry->v.real ); break; case C8: DToLD( (float)LDToD( &entry->v.cmplx.re ), &entry->v.cmplx.re ); DToLD( (float)LDToD( &entry->v.cmplx.im ), &entry->v.cmplx.im ); break; case C16: DToLD( (double)LDToD( &entry->v.cmplx.re ), &entry->v.cmplx.re ); DToLD( (double)LDToD( &entry->v.cmplx.im ), &entry->v.cmplx.im ); break; case NP2: case FP4: entry->v.addr.mach.offset &= 0xffff; break; case STR: if( k != TK_STRING ) { Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) ); } if( s > entry->info.size ) { /* have to expand string */ _ChkAlloc( dest, s, LIT( ERR_NO_MEMORY_FOR_EXPR ) ); memcpy( dest, entry->v.string.loc.e[0].u.p, entry->info.size ); memset( &dest[entry->info.size], ' ', s - entry->info.size ); if( AllocatedString( entry ) ) { _Free( entry->v.string.allocated ); } entry->v.string.allocated = dest; LocationCreate( &entry->v.string.loc, LT_INTERNAL, dest ); } break; default: break; } entry->info.kind = k; entry->info.modifier = m; entry->info.size = s; if( !ConvFunc[ ConvIdx( &entry->info ) ]( entry, from ) ) { Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) ); } entry->th = NULL; }
OVL_EXTERN bool ConvR8( stack_entry *entry, conv_class from ) { if( !ConvR10( entry, from ) ) return( FALSE ); DToLD( (double)LDToD( &entry->v.real ), &entry->v.real ); return( TRUE ); }
OVL_EXTERN bool ConvR4( stack_entry *entry, conv_class from ) { if( !ConvR10( entry, from ) ) return( false ); DToLD( (float)LDToD( &entry->v.real ), &entry->v.real ); return( true ); }