i86score.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 259 行
C
259 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include "standard.h"
#include "coderep.h"
#include "score.h"
#include "model.h"
#include "pattern.h"
#include "procdef.h"
#include "vergen.h"
#include "opcodes.h"
extern name *AllocRegName(hw_reg_set);
extern name *NearSegment(void);
extern hw_reg_set HighReg(hw_reg_set);
extern hw_reg_set LowReg(hw_reg_set);
extern void FreeIns(instruction*);
extern bool IsIndexReg(hw_reg_set,type_class_def,bool);
extern proc_def *CurrProc;
extern name *Names[];
extern score_reg **ScoreList;
#define S_MAX 3
#define S_DS 0
#define S_SS 1
#define S_ES 2
#define I_MAX 3
#define I_BX 0
#define I_DI 1
#define I_SI 2
static name *PtrRegs[S_MAX][I_MAX];
static name *DS;
static name *SS;
static name *ES;
extern void ScInitRegs( score *sc ) {
/****************************************
Add some register equality "truths" to the scoreboard "sc"
*/
int ss;
int ds;
if( _IsntTargetModel( FLOATING_DS | FLOATING_SS ) ) {
ss = AllocRegName(HW_SS)->r.reg_index;
ds = AllocRegName(HW_DS)->r.reg_index;
if( RegsEqual( sc, ss, ds ) == FALSE ) {
RegInsert( sc, ss, ds );
}
}
}
static name *NewRegName( hw_reg_set reg ) {
/**********************************************
Allocate a new "far pointer" register an set its class
*/
name *reg_name;
reg_name = AllocRegName( reg );
reg_name->n.name_class = CP;
return( reg_name );
}
extern void AddRegs( void ) {
/**************************
Add some registers to the N_REGISTER list, so that we can do
scoreboarding on them
*/
hw_reg_set lo_part;
name *reg_name;
int i;
int j;
DS = AllocRegName( HW_DS );
SS = AllocRegName( HW_SS );
/* 89-01-03*/
ES = AllocRegName( HW_ES );
i = S_MAX;
while( --i >= 0 ) {
j = I_MAX;
while( --j >= 0 ) {
PtrRegs[i][j] = NULL;
}
}
reg_name = Names[N_REGISTER];
while( reg_name != NULL ) {
if( IsIndexReg( reg_name->r.reg, CP, FALSE ) ) {
if( HW_COvlap( reg_name->r.reg, HW_DS )
|| HW_COvlap( reg_name->r.reg, HW_ES )
|| HW_COvlap( reg_name->r.reg, HW_SS ) ) {
lo_part = LowReg( reg_name->r.reg );
if( HW_COvlap( lo_part, HW_BX ) ) {
PtrRegs[S_DS][I_BX] = NewRegName( HW_DS_BX );
PtrRegs[S_SS][I_BX] = NewRegName( HW_SS_BX );
PtrRegs[S_ES][I_BX] = NewRegName( HW_ES_BX );
} else if( HW_COvlap( lo_part, HW_SI ) ) {
PtrRegs[S_DS][I_SI] = NewRegName( HW_DS_SI );
PtrRegs[S_SS][I_SI] = NewRegName( HW_SS_SI );
PtrRegs[S_ES][I_SI] = NewRegName( HW_ES_SI );
} else if( HW_COvlap( lo_part, HW_DI ) ) {
PtrRegs[S_DS][I_DI] = NewRegName( HW_DS_DI );
PtrRegs[S_SS][I_DI] = NewRegName( HW_SS_DI );
PtrRegs[S_ES][I_DI] = NewRegName( HW_ES_DI );
}
}
}
reg_name = reg_name->n.next_name;
}
/* 89-01-03*/
}
extern void ScoreSegments( score *sc ) {
/*******************************************
Do special scoreboarding on segment registers. Given that BX = DI,
for example, we know that SS:BX = SS:DI, and DS:BX = DS:DI.
*/
score *ds;
score *xs;
int i;
name *dst;
name *src;
ds = &sc[ DS->r.reg_index ];
xs = ds->next_reg;
while( xs != ds ) {
if( xs->index == SS->r.reg_index ) {
i = I_MAX;
while( --i >= 0 ) {
dst = PtrRegs[S_SS][i];
src = PtrRegs[S_DS][i];
if( dst != NULL && src != NULL ) {
if( !RegsEqual( sc, dst->r.reg_index, src->r.reg_index ) ) {
RegInsert( sc, dst->r.reg_index, src->r.reg_index );
}
}
}
} else if( xs->index == ES->r.reg_index ) {
i = I_MAX;
while( --i >= 0 ) {
dst = PtrRegs[S_ES][i];
src = PtrRegs[S_DS][i];
if( dst != NULL && src != NULL ) {
if( !RegsEqual( sc, dst->r.reg_index, src->r.reg_index ) ) {
RegInsert( sc, dst->r.reg_index, src->r.reg_index );
}
}
}
}
xs = xs->next_reg;
}
}
extern bool ScAddOk( hw_reg_set reg1, hw_reg_set reg2 ) {
/************************************************************
Is it ok to say that "reg1" = "reg2"? This is not ok for
unalterable registers since there may be hidden modifications of
these registers.
*/
if( HW_Ovlap( reg1, CurrProc->state.unalterable ) ) {
if( !HW_CEqual( reg1, HW_DS ) && !HW_CEqual( reg1, HW_SS ) ) {
return( FALSE );
}
}
if( HW_Ovlap( reg2, CurrProc->state.unalterable ) ) {
if( !HW_CEqual( reg2, HW_DS ) && !HW_CEqual( reg2, HW_SS ) ) {
return( FALSE );
}
}
return( TRUE );
}
extern bool ScConvert( instruction *ins ) {
/**********************************************
Get rid of instructions like CBW if the high part is not used in the
next instruction.
*/
hw_reg_set tmp;
if( ins->u.gen_table->generate == G_SIGNEX ) {
tmp = HighReg( ins->result->r.reg );
if( !HW_Ovlap( ins->head.next->head.live.regs, tmp ) ) {
FreeIns( ins ); /* get rid of the pesky cwd or cbw instruction!*/
return( TRUE );
}
}
return( FALSE );
}
extern bool CanReplace( instruction *ins ) {
/***********************************************
Are we allowed to replace any of the operands of "ins" with
different registers? For long shifts the answer is no since CX is a
must for the loop counter.
*/
if( ( ins->head.opcode == OP_LSHIFT
|| ins->head.opcode == OP_RSHIFT )
&& ( ins->type_class == U4
|| ins->type_class == I4 ) ) return( FALSE );
return( TRUE );
}
extern bool ScRealRegister( name *reg ) {
/********************************************
Return "TRUE" if "reg" is a real machine register and not some
monstrosity like AX:DX:BX used for calls.
*/
return( reg->n.name_class != XX );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?