i86rtrtn.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 752 行 · 第 1/3 页
C
752 行
static rt_aux_info Scn4 = {
0, 18,
{0x83, 0xC7, 0x02, /* L1: add d1,2*/
0x49, /* L2: dec cx*/
0x74, 0x08, /* je L3*/
0xAF, /* scasw*/
0x75, 0xF7, /* jne L1*/
0x92, /* xchg dx,ax*/
0xAF, /* scasw*/
0x92, /* xchg dx,ax*/
0x75, 0xF5, /* jne L2*/
0xD1, 0xE1, /* L3: shl cx,1*/
0x89, 0xCF} /* mov di,cx*/
};
#include "cgrealgn.h"
extern char *AskRTName( int rtindex ) {
/*****************************************/
return( RTInfo[ rtindex ].nam );
}
static hw_reg_set FirstReg( reg_set_index index ) {
/********************************************************
the tables above use RL_ consts rather that hw_reg_sets cause
it cheaper. This just picks off the first register from a
register list and returns it.
*/
hw_reg_set *list;
list = RegSets[ index ];
return( *list );
}
extern name *Addressable( name *cons, type_class_def class ) {
/*****************************************************************
make sure a floating point constant is addressable (dropped
it into memory if it isnt)
*/
unsigned_64 buffer;
if( cons->n.class == N_CONSTANT ) {
switch( class ) {
case FD:
case FS:
return( GenFloat( cons, class ) );
case U8:
case I8:
buffer.u._32[ I64LO32 ] = cons->c.int_value;
buffer.u._32[ I64HI32 ] = cons->c.int_value_2;
return( GenConstData( (byte *)&buffer, class ) );
default:
Zoiks( ZOIKS_138 );
break;
}
return( GenFloat( cons, class ) );
}
return( cons );
}
static void CheckForPCS( instruction *ins ) {
/********************************************
check to see if pointer subtract is really pointer - pointer
or pointer - integer (PCS = Pointer Constant Subtract)
*/
if( RoutineNum + BEG_RTNS == RT_PTS ) {
if( ins->operands[ 1 ]->n.name_class != PT
&& ins->operands[ 1 ]->n.name_class != CP ) {
RoutineNum = RT_PCS - BEG_RTNS;
}
}
}
extern bool RTLeaveOp2( instruction *ins ) {
/***********************************************
return true if it's a bad idea to put op2 into a temporary since we're
gonna take the bugger's address in rMAKECALL anyway for FDD, FDC, EDA, etc
*/
switch( ins->type_class ) {
case FD:
if( _FPULevel( FPU_87 ) ) return( FALSE );
break;
case I8:
case U8:
break;
default:
return( FALSE );
}
if( NumOperands( ins ) != 2 ) return( FALSE );
return( TRUE );
}
static void FlipIns( instruction *ins ) {
/********************************************
maybe flip the const/mem into the second operand so it goes in local data
*/
name *temp;
switch( ins->head.opcode ) {
case OP_ADD:
case OP_MUL:
break;
default:
return;
}
switch( ins->type_class ) {
case FD:
case I8:
case U8:
break;
default:
return;
}
temp = ins->operands[ 0 ];
if( temp->n.class == N_CONSTANT
|| temp->n.class == N_MEMORY
|| temp->n.class == N_INDEXED ) {
ins->operands[ 0 ] = ins->operands[ 1 ];
ins->operands[ 1 ] = temp;
}
}
extern instruction *rMAKECALL( instruction *ins ) {
/*******************************************************
turn an instruction into the approprate runtime call sequence, using
the tables above to decide where parms go.
*/
rtn_info *info;
label_handle lbl;
instruction *left_ins;
instruction *new_ins;
instruction *la_ins;
instruction *last_ins;
name *reg_name;
hw_reg_set regs;
hw_reg_set all_regs;
name *temp;
name *also_used;
conflict_node *conf;
hw_reg_set tmp;
type_class_def parm2_class;
if( !_IsConvert( ins ) ) {
LookupRoutine( ins );
CheckForPCS( ins );
} else { /* RoutineNum might be wrong if we ran out of memory in ExpandIns*/
RoutineNum = AskHow( ins->base_type_class, ins->type_class )
- BEG_RTNS;
}
FlipIns( ins );
info = &RTInfo[ RoutineNum ];
regs = FirstReg( info->left );
all_regs = regs;
tmp = ReturnReg( WD, FALSE );
HW_TurnOn( all_regs, tmp );
left_ins = MakeMove( ins->operands[ 0 ], AllocRegName( regs ),
info->operand_class );
ins->operands[ 0 ] = left_ins->result;
MoveSegOp( ins, left_ins, 0 );
PrefixIns( ins, left_ins );
regs = FirstReg( info->right );
also_used = NULL;
if( !HW_CEqual( regs, HW_EMPTY ) ) {
if( info->right == RL_8 ) {
temp = ins->operands[ 1 ];
if( temp->n.class==N_TEMP && ( temp->t.temp_flags & CONST_TEMP ) ) {
temp = temp->v.symbol;
}
if( temp->n.class == N_CONSTANT ) {
temp = Addressable( temp, info->operand_class );
la_ins = MakeUnary( OP_CAREFUL_LA, temp,
AllocRegName( HW_SI ), U2 );
also_used = la_ins->operands[ 0 ];
ins->operands[ 1 ] = la_ins->result;
PrefixIns( ins, la_ins );
if( !SegIsSS( temp ) ) {
new_ins = MakeMove( GetSegment( temp ),
AllocRegName(HW_ES), U2 );
HW_CTurnOn( all_regs, HW_ES );
PrefixIns( ins, new_ins );
++RoutineNum;
}
} else if( temp->n.class == N_TEMP ) {
la_ins = MakeUnary( OP_CAREFUL_LA,temp,
AllocRegName( HW_SI ),U2 );
also_used = temp;
ins->operands[ 1 ] = la_ins->result;
MoveSegOp( ins, la_ins, 0 );
DelSeg( la_ins );
PrefixIns( ins, la_ins );
} else if( ins->num_operands == 3 ) {
new_ins = MakeMove( ins->operands[ 2 ],
AllocRegName(HW_ES), U2 );
ins->operands[ 2 ] = new_ins->result;
PrefixIns( ins, new_ins );
la_ins = MakeUnary( OP_CAREFUL_LA, temp,
AllocRegName( HW_SI ), U2 );
also_used = temp;
ins->operands[ 1 ] = la_ins->result;
MoveSegOp( ins, la_ins, 0 );
DelSeg( la_ins );
PrefixIns( ins, la_ins );
HW_CTurnOn( all_regs, HW_ES );
++RoutineNum;
} else if( ( temp->n.class == N_MEMORY && !SegIsSS( temp ) ) ||
( temp->n.class == N_INDEXED && temp->i.base != NULL &&
!SegIsSS( temp->i.base ) ) ) {
la_ins = MakeUnary( OP_CAREFUL_LA, ins->operands[ 1 ],
AllocRegName( HW_ES_SI ), PT );
also_used = ins->operands[ 1 ];
ins->operands[ 1 ] = la_ins->result;
PrefixIns( ins, la_ins );
HW_CTurnOn( all_regs, HW_ES );
++RoutineNum;
} else {
la_ins = MakeUnary( OP_CAREFUL_LA, temp,
AllocRegName( HW_SI ), U2 );
also_used = temp;
ins->operands[ 1 ] = la_ins->result;
MoveSegOp( ins, la_ins, 0 );
DelSeg( la_ins );
PrefixIns( ins, la_ins );
}
HW_CTurnOn( all_regs, HW_SI );
} else {
/* If I knew how to turn a register list index into a type class,
I'd do that, and avoid this if */
if( info->right == RL_SI ) {
new_ins = MakeMove( ins->operands[ 1 ], AllocRegName( regs ),
U2 );
} else {
new_ins = MakeMove( ins->operands[ 1 ], AllocRegName( regs ),
info->operand_class );
}
ins->operands[ 1 ] = new_ins->result;
MoveSegOp( ins, new_ins, 0 );
HW_TurnOn( all_regs, regs );
PrefixIns( ins, new_ins );
}
} else if( NumOperands( ins ) == 2 ) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?