split.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 882 行 · 第 1/2 页
C
882 行
/****************************************************************************
*
* 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: Architecture independent instruction splitting (reductions).
*
****************************************************************************/
#include "standard.h"
#include "coderep.h"
#include "opcodes.h"
#include "pattern.h"
#include "regset.h"
#include "vergen.h"
#include "conflict.h"
#include "cfloat.h"
extern conflict_node *GiveRegister(conflict_node*,bool);
extern conflict_node *InMemory(conflict_node*);
extern conflict_node *NameConflict(instruction*,name*);
extern instruction *MakeBinary(opcode_defs,name*,name*,name*,type_class_def);
extern instruction *MakeMove(name*,name*,type_class_def);
extern instruction *MakeUnary(opcode_defs,name*,name*,type_class_def);
extern name *AllocConst(pointer);
extern name *AllocIntConst(int);
extern name *AllocS32Const(signed_32);
extern name *AllocRegName(hw_reg_set);
extern name *AllocTemp(type_class_def);
extern name *HighPart(name*,type_class_def);
extern name *LowPart(name*,type_class_def);
extern void CheckCC(instruction*,instruction*);
extern void DoNothing(instruction*);
extern void DupSeg(instruction*,instruction*);
extern void DupSegRes(instruction*,instruction*);
extern void MarkPossible(instruction*,name*,reg_set_index);
extern void MoveSegOp(instruction*,instruction*,int);
extern void MoveSegRes(instruction*,instruction*);
extern void PrefixIns(instruction*,instruction*);
extern void ReplIns(instruction*,instruction*);
extern void RevCond(instruction*);
extern void SuffixIns(instruction*,instruction*);
extern hw_reg_set HighReg(hw_reg_set);
extern instruction *MakeNop(void);
extern reg_list *RegSets[];
extern op_regs RegList[];
type_class_def HalfClass[] = {
/*****************************/
0, /* U1*/
0, /* I1*/
U1, /* U2*/
I1, /* I2*/
U2, /* U4*/
I2, /* I4*/
U4, /* U8*/
I4, /* I8*/
U2, /* CP*/
U2, /* PT*/
I2, /* FS*/
I4, /* FD*/
U4, /* FL*/
U4 }; /* XX*/
type_class_def DoubleClass[] = {
/*******************************/
U2, /* U1*/
I2, /* I1*/
U4, /* U2*/
I4, /* I2*/
U8, /* U4*/
I8, /* I4*/
XX, /* U8*/
XX, /* I8*/
0, /* CP*/
0, /* PT*/
0, /* FS*/
0, /* FD*/
XX }; /* XX*/
type_class_def Unsigned[] = {
/****************************/
U1, /* U1*/
U1, /* I1*/
U2, /* U2*/
U2, /* I2*/
U4, /* U4*/
U4, /* I4*/
U8, /* U8*/
U8, /* U8*/
#if _TARGET & _TARG_370
U4, /* CP*/
U4, /* PT*/
#else
CP, /* CP*/
PT, /* PT*/
#endif
FS, /* FS*/
FD, /* FD*/
FL, /* FL*/
XX }; /* XX*/
type_class_def Signed[] = {
/**************************/
I1, /* U1*/
I1, /* I1*/
I2, /* U2*/
I2, /* I2*/
I4, /* U4*/
I4, /* I4*/
I8, /* U8*/
I8, /* I8*/
#if _TARGET & _TARG_370
I4, /* CP*/
I4, /* PT*/
#else
CP, /* CP*/
PT, /* PT*/
#endif
FS, /* FS*/
FD, /* FD*/
FL, /* FL*/
XX }; /* XX*/
extern instruction *(*ReduceTab[])( instruction * );
static reg_set_index ResultPossible( instruction *ins )
/********************************************************/
{
return( RegList[ ins->u.gen_table->reg_set ].result );
}
static reg_set_index Op2Possible( instruction *ins )
/*****************************************************/
{
return( RegList[ ins->u.gen_table->reg_set ].right );
}
static reg_set_index Op1Possible( instruction *ins )
/*****************************************************/
{
return( RegList[ ins->u.gen_table->reg_set ].left );
}
static reg_set_index ResPossible( instruction *ins )
/*****************************************************/
{
return( RegList[ ins->u.gen_table->reg_set ].result );
}
extern hw_reg_set Op1Reg( instruction *ins )
/************************************************/
{
hw_reg_set *list;
list = RegSets[ Op1Possible( ins ) ];
return( *list );
}
extern hw_reg_set ResultReg( instruction *ins )
/***************************************************/
{
hw_reg_set *list;
list = RegSets[ ResultPossible( ins ) ];
return( *list );
}
extern hw_reg_set ZapReg( instruction *ins )
/************************************************/
{
hw_reg_set *list;
list = RegSets[ RegList[ ins->u.gen_table->reg_set ].zap ];
return( *list );
}
extern instruction *MoveConst( unsigned_32 value,
name *result, type_class_def class )
/**********************************************************************/
{
return( MakeMove( AllocConst( CFCnvU32F( value ) ), result, class ) );
}
extern instruction *Reduce( instruction *ins )
/*************************************************/
{
ins->head.state = INS_NEEDS_WORK;
return( ReduceTab[ ins->u.gen_table->generate-FIRST_REDUCT ]( ins ) );
}
extern void HalfType( instruction *ins )
/******************************************/
{
ins->type_class = HalfClass[ ins->type_class ];
ins->table = NULL;
ins->head.state = INS_NEEDS_WORK;
}
extern void ChangeType( instruction *ins, type_class_def class )
/******************************************************************/
{
ins->type_class = class;
ins->table = NULL;
ins->head.state = INS_NEEDS_WORK;
}
static void ForceToMemory( name *name )
/*****************************************/
{
while( name->v.conflict != NULL ) {
InMemory( name->v.conflict );
}
}
extern instruction *rMOVOP1TEMP( instruction *ins )
/******************************************************/
{
instruction *new_ins;
type_class_def class;
name *name;
class = _OpClass( ins );
name = AllocTemp( class );
new_ins = MakeMove( ins->operands[ 0 ], name, class );
ins->operands[ 0 ] = name;
MoveSegOp( ins, new_ins, 0 );
PrefixIns( ins, new_ins );
return( new_ins );
}
extern instruction *rMOVOP2TEMP( instruction *ins )
/******************************************************/
{
instruction *new_ins;
name *name1;
name1 = AllocTemp( ins->type_class );
new_ins = MakeMove( ins->operands[ 1 ], name1, ins->type_class );
ins->operands[ 1 ] = name1;
MoveSegOp( ins, new_ins, 0 );
PrefixIns( ins, new_ins );
return( new_ins );
}
extern instruction *rOP1REG( instruction *ins )
/**************************************************/
{
instruction *new_ins;
name *name1;
type_class_def class;
class = _OpClass( ins );
name1 = AllocTemp( class );
new_ins = MakeMove( ins->operands[ 0 ], name1, class );
ins->operands[ 0 ] = name1;
MoveSegOp( ins, new_ins, 0 );
PrefixIns( ins, new_ins );
MarkPossible( ins, name1, Op1Possible( ins ) );
ins->u.gen_table = NULL;
GiveRegister( NameConflict( ins, name1 ), TRUE );
return( new_ins );
}
extern instruction *rOP2REG( instruction *ins )
/**************************************************/
{
instruction *new_ins;
name *name1;
type_class_def class;
class = _OpClass( ins );
name1 = AllocTemp( class );
new_ins = MakeMove( ins->operands[ 1 ], name1, class );
ins->operands[ 1 ] = name1;
MoveSegOp( ins, new_ins, 0 );
PrefixIns( ins, new_ins );
MarkPossible( ins, name1, Op1Possible( ins ) );
ins->u.gen_table = NULL;
GiveRegister( NameConflict( ins, name1 ), TRUE );
return( new_ins );
}
/* 370 */
extern instruction *rMOVRESREG( instruction *ins )
/*****************************************************/
{
instruction *new_ins;
name *name1;
name1 = AllocTemp( ins->type_class );
new_ins = MakeMove( name1, ins->result, ins->type_class );
ins->result = name1;
MoveSegRes( ins, new_ins );
SuffixIns( ins, new_ins );
MarkPossible( ins, name1, ResPossible( ins ) );
ins->u.gen_table = NULL;
GiveRegister( NameConflict( ins, name1 ), TRUE );
return( ins );
}
extern instruction *rMOVRESTEMP( instruction *ins )
/******************************************************/
{
instruction *new_ins;
name *name1;
name1 = AllocTemp( ins->type_class );
new_ins = MakeMove( name1, ins->result, ins->type_class );
ins->result = name1;
MoveSegRes( ins, new_ins );
SuffixIns( ins, new_ins );
MarkPossible( ins, name1, ResPossible( ins ) );
ins->u.gen_table = NULL;
return( ins );
}
extern instruction *rRESREG( instruction *ins )
/**************************************************/
{
instruction *new_ins;
name *name1;
name1 = AllocTemp( ins->type_class );
new_ins = MakeMove( name1, ins->result, ins->type_class );
ins->result = name1;
MoveSegRes( ins, new_ins );
SuffixIns( ins, new_ins );
MarkPossible( ins, name1, ResultPossible( ins ) );
ins->u.gen_table = NULL;
GiveRegister( NameConflict( ins, name1 ), TRUE );
new_ins = ins;
return( new_ins );
}
extern instruction *rOP1RESREG( instruction *ins )
/*****************************************************/
{
instruction *new_ins;
instruction *ins2;
name *name1;
name *name2;
name1 = AllocRegName( Op1Reg( ins ) );
new_ins = MakeMove( ins->operands[ 0 ], name1, _OpClass( ins ) );
ins->operands[ 0 ] = name1;
MoveSegOp( ins, new_ins, 0 );
PrefixIns( ins, new_ins );
name2 = AllocRegName( ResultReg( ins ) );
ins2 = MakeMove( name2, ins->result, ins->type_class );
ins->result = name2;
MoveSegRes( ins, ins2 );
SuffixIns( ins, ins2 );
return( new_ins );
}
/* 370 */
static bool CanUseOp1( instruction *ins, name *op1 )
/******************************************************/
{
name *name2;
if( op1->n.class != N_REGISTER ) return( FALSE );
if( HW_Ovlap( op1->r.reg, ins->head.next->head.live.regs ) ) return( FALSE );
if( ins->result->n.class == N_INDEXED ) {
name2 = ins->result->i.index;
if( name2->n.class == N_REGISTER ) {
if( HW_Ovlap( name2->r.reg, op1->r.reg ) ) return( FALSE );
}
}
return( TRUE );
}
/* 370 */
extern instruction *rUSEREGISTER( instruction *ins )
/*******************************************************/
{
instruction *new_ins;
instruction *ins2;
name *name1;
name1 = ins->operands[ 0 ];
if( CanUseOp1( ins, name1 ) ) {
new_ins = MakeMove( name1, ins->result, ins->type_class );
ins->result = name1;
MoveSegRes( ins, new_ins );
SuffixIns( ins, new_ins );
new_ins = ins;
} else {
name1 = AllocTemp( ins->type_class );
new_ins = MakeMove( ins->operands[ 0 ], name1, ins->type_class );
CheckCC( ins, new_ins );
ins->operands[ 0 ] = name1;
MoveSegOp( ins, new_ins, 0 );
PrefixIns( ins, new_ins );
ins2 = MakeMove( name1, ins->result, ins->type_class );
ins->result = name1;
MoveSegRes( ins, ins2 );
SuffixIns( ins, ins2 );
MarkPossible( ins, name1, ResultPossible( ins ) );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?