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 + -
显示快捷键?