void ClassNum( stack_entry *entry ) { unsigned long val; entry->info.kind = TK_INTEGER; entry->flags &= ~SF_FORM_MASK; entry->flags |= SF_CONST; if( I64Test( &entry->v.sint ) < 0 ) { /* A bit backwards - if the top bit is on, it won't fit in in 63 bits. */ entry->info.modifier = TM_UNSIGNED; entry->info.size = sizeof( unsigned_64 ); return; } if( !U64IsU32( entry->v.uint ) ) { entry->info.modifier = TM_SIGNED; entry->info.size = sizeof( signed_64 ); return; } val = U32FetchTrunc( entry->v.uint ); if( val > 0x7fffffff ) { entry->info.modifier = TM_UNSIGNED; entry->info.size = sizeof( unsigned_32 ); } else if( DefaultSize( DK_INT ) > 2 ) { entry->info.modifier = TM_SIGNED; entry->info.size = sizeof( signed_32 ); } else if( val > 0xffff ) { entry->info.modifier = TM_SIGNED; entry->info.size = sizeof( signed_32 ); } else if( val > 0x7fff ) { entry->info.modifier = TM_UNSIGNED; entry->info.size = sizeof( unsigned_16 ); } else { entry->info.modifier = TM_SIGNED; entry->info.size = sizeof( signed_16 ); } }
OVL_EXTERN bool ConvFP6( stack_entry *entry, conv_class from ) { address tmp; tmp = DefAddrSpaceForAddr( Context.execution ); switch( from ) { case U1: case U2: case U4: case U8: if( (entry->flags & SF_CONST) && U64Test( &entry->v.uint ) == 0 ) tmp = NilAddr; //NYI: 64 bit offsets tmp.mach.offset = U32FetchTrunc( entry->v.uint ); break; case I1: case I2: case I4: case I8: if( (entry->flags & SF_CONST) && I64Test( &entry->v.sint ) == 0 ) tmp = NilAddr; //NYI: 64 bit offsets tmp.mach.offset = U32FetchTrunc( entry->v.sint ); break; case NP2: case NP4: /* near pointers already have correct segment information filled in */ tmp = entry->v.addr; break; case FP4: case FP6: case HP4: tmp = entry->v.addr; break; default: return( FALSE ); } entry->v.addr = tmp; 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 {