OVL_EXTERN bool ConvU8( stack_entry *entry, conv_class from ) { unsigned_64 tmp; switch( from ) { case U1: case U2: case U4: case U8: tmp = entry->v.uint; break; case I1: case I2: case I4: case I8: tmp = entry->v.sint; break; case F4: case F8: case F10: //NYI: 64-bit support I32ToI64( LDToD( &entry->v.real ), &tmp ); break; case C8: case C16: case C20: I32ToI64( LDToD( &entry->v.cmplx.re ), &tmp ); break; case NP2: case NP4: //NYI: 64-bit offsets U32ToU64( entry->v.addr.mach.offset, &tmp ); break; case FP4: case HP4: U32ToU64( entry->v.addr.mach.offset + ((long) entry->v.addr.mach.segment << 16), &tmp ); break; case FP6: U32ToU64( entry->v.addr.mach.offset, &tmp ); break; default: return( FALSE ); } entry->v.uint = tmp; return( TRUE ); }
void DoMinus( void ) { stack_entry *left; left = StkEntry( 1 ); LRValue( left ); RValue( ExprSP ); AddOp( left, ExprSP ); switch( left->info.kind ) { case TK_BOOL: case TK_ENUM: case TK_CHAR: case TK_INTEGER: U64Sub( &left->v.uint, &ExprSP->v.uint, &left->v.uint ); left->info.modifier = TM_SIGNED; break; case TK_POINTER: case TK_ADDRESS: switch( ExprSP->info.kind ) { case TK_BOOL: case TK_CHAR: case TK_ENUM: case TK_INTEGER: //NYI: 64 bit offsets left->v.addr = AddrAdd( left->v.addr, -U32FetchTrunc( ExprSP->v.uint ) ); break; case TK_POINTER: case TK_ADDRESS: I32ToI64( AddrDiff( left->v.addr, ExprSP->v.addr ), &left->v.sint ); left->info.kind = TK_INTEGER; left->info.modifier = TM_SIGNED; left->info.size = sizeof( signed_64 ); left->th = NULL; break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); } break; case TK_REAL: LDSub( &left->v.real, &ExprSP->v.real, &left->v.real ); break; case TK_COMPLEX: LDSub( &left->v.cmplx.re, &ExprSP->v.cmplx.re, &left->v.cmplx.re ); LDSub( &left->v.cmplx.im, &ExprSP->v.cmplx.im, &left->v.cmplx.im ); break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); break; } CombineEntries( left, left, ExprSP ); }
int64( long i ) { I32ToI64( i, &_d ); }
/* * 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 ConvI4( stack_entry *entry, conv_class from ) { if( !ConvU8( entry, from ) ) return( FALSE ); I32ToI64( (signed_32)U32FetchTrunc( entry->v.uint ), &entry->v.sint ); return( TRUE ); }
/* Take advantage of the SETcc instruction in cases such as * x = y ? 3 : 4; * by adding a constant to the result of SETcc to directly obtain * the result of the assignment. */ static bool FindFlowOut( block *blk ) { /*****************************************/ signed_64 false_cons; signed_64 true_cons; signed_64 one; signed_64 neg_one; signed_64 diff; instruction *ins; instruction *ins0; instruction *ins1; // instruction *prev; block *true_blk; block *false_blk; block *join_blk; block_edge *new_edge; bool reverse; name *u1temp; name *temp; name *result; name *konst; type_class_def class; for( ins = blk->ins.hd.prev; !_OpIsCondition( ins->head.opcode ); ) { ins = ins->head.prev; } // prev = ins->head.prev; if( TypeClassSize[ ins->type_class ] > WORD_SIZE ) return( FALSE ); true_blk = blk->edge[ _TrueIndex( ins ) ].destination.u.blk; if( true_blk->inputs != 1 ) return( FALSE ); if( true_blk->targets != 1 ) return( FALSE ); false_blk = blk->edge[ _FalseIndex( ins ) ].destination.u.blk; if( false_blk->inputs != 1 ) return( FALSE ); if( false_blk->targets != 1 ) return( FALSE ); join_blk = false_blk->edge[ 0 ].destination.u.blk; if( join_blk != true_blk->edge[ 0 ].destination.u.blk ) return( FALSE ); if( join_blk->inputs != 2 ) return( FALSE ); if( join_blk->class & UNKNOWN_DESTINATION ) return( FALSE ); ins0 = SetToConst( false_blk, &false_cons ); if( ins0 == NULL ) return( FALSE ); ins1 = SetToConst( true_blk, &true_cons ); if( ins1 == NULL ) return( FALSE ); I32ToI64( 1, &one ); I32ToI64( -1, &neg_one ); U64Sub( &true_cons, &false_cons, &diff ); if( U64Cmp( &diff, &neg_one ) == 0 ) { U64IncDec( &false_cons, -1 ); reverse = TRUE; } else { if( U64Cmp( &diff, &one ) != 0 ) return( FALSE ); reverse = FALSE; } result = ins0->result; if( result != ins1->result ) return( FALSE ); class = ins0->type_class; if( class != ins1->type_class ) return( FALSE ); if( reverse ) FlipCond( ins ); u1temp = AllocTemp( U1 ); temp = AllocTemp( class ); ins->result = u1temp; ins1 = MakeConvert( u1temp, temp, class, U1 ); SuffixIns( ins, ins1 ); ins = ins1; if( I64Test( &false_cons ) != 0 ) { konst = AllocS64Const( false_cons.u._32[I64LO32], false_cons.u._32[I64HI32] ); ins1 = MakeBinary( OP_ADD, temp, konst, result, class ); } else {
OVL_EXTERN bool ConvI2( stack_entry *entry, conv_class from ) { if( !ConvU8( entry, from ) ) return( false ); I32ToI64( (signed_16)U32FetchTrunc( entry->v.uint ), &entry->v.sint ); return( true ); }