static bool NotEquiv( type_def *a, type_def *b ) /**********************************************/ { if( TypeClass( a ) != TypeClass( b ) ) return( TRUE ); if( a->length != b->length ) return( TRUE ); return( FALSE ); }
static an Unary( cg_op op, an left, type_def *tipe ) /***************************************************/ { instruction *ins; an res; ins = MakeNary( (opcode_defs)op, GenIns( left ), NULL, NULL, TypeClass( tipe ), TypeClass( left->tipe ), 1 ); res = InsName( ins, tipe ); AddIns( ins ); BGDone( left ); return( res ); }
extern void InitCG( void ) /****************************/ { InOptimizer = 0; InsId = 0; CurrProc = NULL; CurrBlock = NULL; BlockList = NULL; HeadBlock = NULL; BlockByBlock = FALSE; abortCG = FALSE; InitFP();/* must be before InitRegTbl */ InitRegTbl(); ScoreInit(); InitQueue(); InitMakeAddr(); RegTreeInit(); InitIns(); InitConflict(); InitRT(); InitNames(); ObjInit(); ClassPointer = TypeClass( TypePtr ); InitSegment(); }
name *StReturn( an retval, type_def *tipe, instruction **pins ) /****************************************************************/ { name *retp; name *ptr; name *off; name *seg; hw_reg_set reg; if( CurrProc->state.attr & ROUTINE_ALLOCS_RETURN ) { retp = CurrProc->targ.return_points; AddIns( MakeUnary( OP_LA, retp, AllocRegName( CurrProc->state.return_reg ), WD ) ); *pins = NULL; } else { if( _IsTargetModel( FLOATING_SS ) || _IsTargetModel( FLOATING_DS ) ) { ptr = AllocTemp( CP ); off = OffsetPart( ptr ); seg = SegmentPart( ptr ); AddIns( MakeMove( AllocRegName( HW_SS ), seg, U2 ) ); } else { ptr = AllocTemp( WD ); off = ptr; } AddIns( MakeMove( CurrProc->targ.return_points, off, WD ) ); retp = SAllocIndex( ptr, NULL, 0, TypeClass( retval->tipe ), tipe->length ); reg = ReturnReg( WD, false ); *pins = MakeMove( CurrProc->targ.return_points, AllocRegName( reg ), WD ); CurrProc->state.return_reg = reg; } return( retp ); }
name *BGNewTemp( type_def *tipe ) /**************************************/ { name *temp; temp = AllocTemp( TypeClass( tipe ) ); if( temp->n.size == 0 ) { temp->n.size = tipe->length; } return( temp ); }
extern an BGCall( cn call, bool use_return, bool in_line ) /********************************************************/ { instruction *call_ins; instruction *conv_ins; call_state *state; name *result; hw_reg_set ret_addr; instruction *ins; call_ins = call->ins; state = call->state; if( state->attr & ROUTINE_MODIFIES_NO_MEMORY ) { call_ins->flags.call_flags |= CALL_WRITES_NO_MEMORY; } if( state->attr & ROUTINE_READS_NO_MEMORY ) { call_ins->flags.call_flags |= CALL_READS_NO_MEMORY; } if( state->attr & ROUTINE_IS_SETJMP ) { call_ins->flags.call_flags |= CALL_IS_SETJMP; } if( use_return == FALSE ) { call_ins->flags.call_flags |= CALL_IGNORES_RETURN; } result = BGNewTemp( call->tipe ); if( call_ins->type_class == XX ) { call_ins->result = result; ret_addr = ParmReg( CP, 4, 8, state ); ins = MakeUnary( OP_LA, result, AllocRegName( ret_addr ), CP ); AddIns( ins ); } else { call_ins->result = AllocRegName( state->return_reg ); } AssgnParms( call, in_line ); AddCallIns( call_ins, call ); if( use_return ) { if( call_ins->type_class != XX ) { conv_ins = MakeConvert( call_ins->result, result, TypeClass( call->tipe ), ReturnClass( call->tipe, call->state->attr ) ); AddIns( conv_ins ); } else { // conv_ins = MakeMove( call_result, result, XX ); } } return( MakeTempAddr( result ) ); }
extern void BGParmInline( cg_sym_handle sym, type_def *tipe ) { /**************************************************************/ name *temp; name *parm_value; inline_parm *parm; parm = InlineStack->parms; InlineStack->parms = InlineStack->parms->next; // if( NotEquiv( parm->addr->tipe, tipe ) ) { // _Zoiks( ZOIKS_070 ); // } temp = SAllocUserTemp( sym, TypeClass( tipe ), tipe->length ); temp->v.usage |= USE_IN_ANOTHER_BLOCK; parm_value = GenIns( parm->addr ); BGDone( parm->addr ); AddIns( MakeMove( parm_value, temp, temp->n.name_class ) ); CGFree( parm ); }
void BGProcDecl( cg_sym_handle sym, type_def *tipe ) /*****************************************************/ { hw_reg_set reg; name *temp; type_class_def type_class; segment_id old_segid; label_handle lbl; SaveTargetModel = TargetModel; type_class = AddCallBlock( sym, tipe ); if( tipe != TypeNone ) { if( type_class == XX ) { if( CurrProc->state.attr & ROUTINE_ALLOCS_RETURN ) { old_segid = SetOP( AskBackSeg() ); lbl = AskForNewLabel(); DataLabel( lbl ); DGUBytes( tipe->length ); CurrProc->targ.return_points = (name *)SAllocMemory( lbl, 0, CG_LBL, TypeClass( tipe ), tipe->length ); SetOP( old_segid ); } else { reg = CurrProc->state.return_reg; if( HW_CEqual( reg, HW_EMPTY ) ) { temp = DoParmDecl( NULL, TypeInteger, HW_EMPTY ); } else { temp = AllocTemp( WD ); temp->v.usage |= USE_IN_ANOTHER_BLOCK; AddIns( MakeMove( AllocRegName( reg ), temp, WD ) ); HW_TurnOn( CurrProc->state.parm.used, reg ); } CurrProc->targ.return_points = temp; } } } if( CurrProc->state.attr & ROUTINE_FARSS ) { TargetModel |= FLOATING_SS; } }
an BGCompare( cg_op op, an left, an rite, label_handle entry, type_def *tipe ) /*********************************************************************************/ { an new; instruction *ins; name *newleft; name *newrite; LastCmpType = tipe; newleft = GenIns( left ); newrite = GenIns( rite ); BGDone( left ); BGDone( rite ); NamesCrossBlocks(); ins = MakeCondition( (opcode_defs)op, newleft, newrite, 0, 1, TypeClass( tipe ) ); AddIns( ins ); GenBlock( BLK_CONDITIONAL, 2 ); AddTarget( NULL, false ); AddTarget( NULL, false ); new = NewBoolNode(); new->u.b.e = entry; new->u.b.t = &CurrBlock->edge[0].destination.u.lbl; new->u.b.f = &CurrBlock->edge[1].destination.u.lbl; EnLink( AskForNewLabel(), true ); return( new ); } an Boolean( an node, label_handle entry )
static void Far16Parms( cn call ) { /*************************************/ instruction *ins; type_length parm_size; pn parm, next; instruction *call_ins; name *eax; name *ecx; name *esi; label_handle lbl; type_length offset; name *parmlist; call_state *state; rt_class rtindex; call_ins = call->ins; parm_size = 0; state = call->state; for( parm = call->parms; parm != NULL; parm = parm->next ) { parm_size += _RoundUp( parm->name->tipe->length, 2 ); } parmlist = SAllocTemp( XX, parm_size ); parmlist->v.usage |= NEEDS_MEMORY | USE_IN_ANOTHER_BLOCK | USE_ADDRESS; offset = 0; for( parm = call->parms; parm != NULL; parm = parm->next ) { parm->name->u.i.ins->result = STempOffset( parmlist, offset, TypeClass( parm->name->tipe ), parm->name->tipe->length ); offset += _RoundUp( parm->name->tipe->length, 2 ); } for( parm = call->parms; parm != NULL; parm = next ) { next = parm->next; parm->name->format = NF_ADDR; /* so instruction doesn't get freed! */ BGDone( parm->name ); CGFree( parm ); } eax = AllocRegName( HW_EAX ); ecx = AllocRegName( HW_ECX ); esi = AllocRegName( HW_ESI ); HW_TurnOn( state->parm.used, eax->r.reg ); HW_TurnOn( state->parm.used, ecx->r.reg ); HW_TurnOn( state->parm.used, esi->r.reg ); ins = MakeMove( AllocS32Const( parm_size ), ecx, WD ); AddIns( ins ); ins = MakeUnary( OP_LA, parmlist, esi, WD ); AddIns( ins ); if( ins->head.opcode == OP_CALL ) { ins = MakeUnary( OP_LA, call->name->u.n.name, eax, WD ); } else { ins = MakeMove( GenIns( call->name ), eax, WD ); call_ins->head.opcode = OP_CALL; } call_ins->num_operands = 2; AddIns( ins ); if( call_ins->type_class == XX ) { if( state->attr & ROUTINE_ALLOCS_RETURN ) { rtindex = RT_Far16Cdecl; } else { rtindex = RT_Far16Pascal; } } else { rtindex = RT_Far16Func; } lbl = RTLabel( rtindex ); call->name->u.n.name = AllocMemory( lbl, 0, CG_LBL, WD ); call_ins->flags.call_flags |= CALL_FAR16 | CALL_POPS_PARMS; call_ins->operands[CALL_OP_USED] = AllocRegName( state->parm.used ); call_ins->operands[CALL_OP_POPS] = AllocS32Const( 0 ); call_ins->zap = &call_ins->operands[CALL_OP_USED]->r; }