i86split.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,100 行 · 第 1/3 页

C
1,100
字号
/****************************************************************************
*
*                            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:  Intel i86/386 instruction spliting 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"
#include "model.h"
#include "system.h"
#include "zoiks.h"

extern  conflict_node   *GiveRegister(conflict_node*,bool);
extern  conflict_node   *NameConflict(instruction*,name*);
extern  constant_defn   *GetFloat(name*,type_class_def);
extern  hw_reg_set      Op1Reg(instruction*);
extern  hw_reg_set      ResultReg(instruction*);
extern  hw_reg_set      ZapReg(instruction*);
extern  instruction     *ByteShift(instruction*);
extern  instruction     *CheapShift(instruction*);
extern  instruction     *ClrHighDbl(instruction*);
extern  instruction     *ExtPush1(instruction*);
extern  instruction     *ExtPush2(instruction*);
extern  instruction     *HighCmp(instruction*);
extern  instruction     *MakeBinary(opcode_defs,name*,name*,name*,type_class_def);
extern  instruction     *MakeFNeg(instruction*);
extern  instruction     *MakeMove(name*,name*,type_class_def);
extern  instruction     *MakeU2(instruction*);
extern  instruction     *MakeU4(instruction*);
extern  instruction     *MakeUnary(opcode_defs,name*,name*,type_class_def);
extern  instruction     *MakeConvert(name*,name*,type_class_def,type_class_def);
extern  instruction     *MoveConst(unsigned_32,name*,type_class_def);
extern  instruction     *Split4Neg(instruction*);
extern  instruction     *SplitCPPush(instruction*);
extern  instruction     *SplitCompare(instruction*);
extern  instruction     *SplitMove(instruction*);
extern  instruction     *SplitOp(instruction*);
extern  instruction     *SplitFDPush(instruction*);
extern  instruction     *SplitMove(instruction*);
extern  instruction     *SplitUnary(instruction*);
extern  int             NumOperands(instruction*);
extern  name            *Addressable(name*,type_class_def);
extern  name            *AllocU64Const( unsigned_32, unsigned_32 );
extern  name            *AllocConst(pointer);
extern  name            *AllocIndex(name*,name*,type_length,type_class_def);
extern  name            *AllocIntConst(int);
extern  name            *AllocMemory(pointer,type_length,cg_class,type_class_def);
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  name            *NearSegment(void);
extern  name            *OffsetPart(name*);
extern  name            *SAllocIndex(name*,name*,type_length,type_class_def,type_length);
extern  name            *ScaleIndex(name*,name*,type_length,type_class_def,type_length,int,i_flags);
extern  name            *SegName(name*);
extern  name            *SegmentPart(name*);
extern  name            *TempOffset(name*,type_length,type_class_def);
extern  void            ChangeType(instruction*,type_class_def);
extern  void            DelSeg(instruction*);
extern  void            DupSeg(instruction*,instruction*);
extern  void            DupSegRes(instruction*,instruction*);
extern  void            HalfType(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  instruction     *SplitLoadAddr(instruction*);
extern  void            UpdateLive(instruction*,instruction*);

extern  instruction             *rCHANGESHIFT(instruction*);
extern  instruction             *rFIXSHIFT(instruction *);
extern  instruction             *rCLRHI_BW(instruction*);
extern  instruction             *rCONVERT_LOW(instruction*);
extern  instruction             *rCYPHIGH(instruction*);
extern  instruction             *rCYPLOW(instruction*);
extern  instruction             *rDOCVT(instruction*);
extern  instruction             *rDOUBLEHALF(instruction*);
extern  instruction             *rMAKECALL(instruction*);
extern  instruction             *rOP1MEM(instruction*);
extern  instruction             *rFORCERESMEM(instruction*);
extern  instruction             *rHIGHCMP(instruction*);
extern  instruction             *rLOADLONGADDR(instruction*);
extern  instruction             *rMAKEFNEG(instruction*);
extern  instruction             *rMAKEMOVE(instruction*);
extern  instruction             *rMAKEU2(instruction*);
extern  instruction             *rMAKEU4(instruction*);
extern  instruction             *rMAKEXORRR(instruction*);
extern  instruction             *rMOVEINDEX(instruction*);
extern  instruction             *rMOVOP1TEMP(instruction*);
extern  instruction             *rMOVOP2(instruction*);
extern  instruction             *rMOVOP2TEMP(instruction*);
extern  instruction             *rOP1REG(instruction*);
extern  instruction             *rMOVOP1RES(instruction*);
extern  instruction             *rMOVRESREG(instruction*);
extern  instruction             *rOP1RESTEMP(instruction*);
extern  instruction             *rRESREG(instruction*);
extern  instruction             *rSPLIT8(instruction*);
extern  instruction             *rSPLITCMP(instruction*);
extern  instruction             *rSPLITMOVE(instruction*);
extern  instruction             *rSPLITOP(instruction*);
extern  instruction             *rSWAPCMP(instruction*);
extern  instruction             *rSWAPOPS(instruction*);
extern  instruction             *rUSEREGISTER(instruction*);
extern  instruction             *rOP1RESREG(instruction*);
extern  instruction             *rSPLITNEG(instruction*);
extern  instruction             *rBYTESHIFT(instruction*);
extern  instruction             *rCYPSHIFT(instruction*);
extern  instruction             *rLOADOP2(instruction*);
extern  instruction             *rMAKEADD(instruction*);
extern  instruction             *rMAKENEG(instruction*);
extern  instruction             *rMAKESUB(instruction*);
extern  instruction             *rCMPTRUE(instruction*);
extern  instruction             *rCMPFALSE(instruction*);
extern  instruction             *rNEGADD(instruction*);
extern  instruction             *rOP2MEM(instruction*);
extern  instruction             *rCLRHI_D(instruction*);
extern  instruction             *rADDRR(instruction*);
extern  instruction             *rSPLITPUSH(instruction*);
extern  instruction             *rEXT_PUSH1(instruction*);
extern  instruction             *rEXT_PUSH2(instruction*);
extern  instruction             *rCLRHI_R(instruction*);
extern  instruction             *rMOVOP2RES(instruction*);
extern  instruction             *rINTCOMP(instruction*);
extern  instruction             *rCDQ(instruction*);
extern  instruction             *rCYP_SEX(instruction*);
extern  instruction             *rFLIPSIGN(instruction*);
extern  instruction             *rTEMP2CONST(instruction*);
extern  instruction             *rSAVEFACE(instruction*);
extern  instruction             *rMULSAVEFACE(instruction*);
extern  instruction             *rDOLONGPUSH( instruction * );
extern  instruction             *rOP1CMEM( instruction * );
extern  instruction             *rOP2CMEM( instruction * );
extern  instruction             *rFSCONSCMP( instruction * );
extern  instruction             *rHIGHLOWMOVE( instruction * );
extern  instruction             *rMAKECYPMUL( instruction * );
extern  instruction             *rMAKESTRCMP( instruction * );
extern  instruction             *rMAKESTRMOVE( instruction * );
extern  instruction             *rMOVELOW( instruction * );
extern  instruction             *rMOVOP1MEM( instruction * );
extern  instruction             *rOP2CL( instruction * );
extern  instruction             *rOP2CX( instruction * );
extern  instruction             *rSPLITUNARY( instruction * );
extern  instruction             *rMULREGISTER( instruction * );
extern  instruction             *rDIVREGISTER( instruction * );
extern  instruction             *rCPSUB( instruction * );
extern  instruction             *rPTSUB( instruction * );
extern  instruction             *rU_TEST( instruction * );
extern  instruction             *rEXTPT( instruction * );
extern  instruction             *rMAYBSTRMOVE( instruction * );
extern  instruction             *rSEG_SEG( instruction * );
extern  instruction             *rCHPPT( instruction * );
extern  instruction             *rMOVRESMEM( instruction * );
extern  instruction             *rMAKEU4CONS( instruction * );
extern  instruction             *rEXT_PUSHC( instruction * );
extern  instruction             *rCONVERT_UP( instruction * );
extern  instruction             *rSPLIT8BIN( instruction * );
extern  instruction             *rSPLIT8NEG( instruction * );
extern  instruction             *rSPLIT8TST( instruction * );
extern  instruction             *rSPLIT8CMP( instruction * );
extern  instruction             *rMOVE8LOW( instruction * );
extern  instruction             *rCMPCP( instruction * );
extern  instruction             *rMOVPTI8( instruction * );
extern  instruction             *rMOVI8PT( instruction * );

/* forward declaration */
extern  void                    CnvOpToInt( instruction * ins, int op );

extern  opcode_entry    String[];
extern  opcode_entry    *Move2;
extern  opcode_entry    *Move4;
extern  type_class_def  DoubleClass[];
extern  bool            OptForSize;


instruction *(*ReduceTab[])( instruction * ) = {
/**************************************/

#undef _R_
#define _R_( x, f )     f
#include "r.h"

};


extern  bool    UnChangeable( instruction *ins ) {
/************************************************/

    return( ins->table == String );
}

extern instruction      *rSAVEFACE( instruction *ins ) {
/******************************************************/

    instruction         *new_ins;

    // we have a EDX:EAX op 1 or DX:AX op 1 here which the constant
    // folder was not able to catch, because of the weird regs
    new_ins = MakeMove( AllocRegName( _AX ), ins->result, ins->type_class );
    ReplIns( ins, new_ins );
    return( new_ins );
}

extern instruction      *rMULSAVEFACE( instruction *ins ) {
/*********************************************************/

    instruction         *new_ins;

    // we have a r1 mul 1 -> DX:AX here which the constant
    // folder was not able to catch, because of the weird regs
    new_ins = MakeMove( ins->operands[ 0 ], AllocRegName( _AX ), ins->type_class );
    ReplIns( ins, new_ins );
    return( new_ins );
}

extern instruction      *rMAKECYPMUL( instruction *ins ) {
/*******************************************************/


    HalfType( ins );
    return( ins );
}


extern instruction      *rSEG_SEG( instruction *ins ) {
/****************************************************/

    instruction         *new_ins;
    name                *name1;

    name1 = AllocTemp( U2 );
    new_ins = MakeMove( ins->operands[ 0 ], name1, U2 );
    ins->operands[ 0 ] = name1;
    PrefixIns( ins, new_ins );
    MarkPossible( ins, name1, RL_WORD );
    ins->u.gen_table = NULL;
    GiveRegister( NameConflict( ins, name1 ), TRUE );
    return( new_ins );
}


extern instruction      *rOP2CL( instruction *ins ) {
/**************************************************/

    instruction         *new_ins;
    name                *name1;

    name1 = AllocRegName( HW_CL );
    new_ins = MakeConvert( ins->operands[ 1 ], name1, U1,
                           ins->operands[ 1 ]->n.name_class );
    ins->operands[ 1 ] = name1;
    MoveSegOp( ins, new_ins, 0 );
    PrefixIns( ins, new_ins );
    return( new_ins );
}


extern instruction      *rOP2CX( instruction *ins ) {
/**************************************************/

    instruction         *new_ins;
    name                *name1;

    name1 = AllocRegName( HW_CX );
    new_ins = MakeConvert( ins->operands[ 1 ], name1, U2,
                           ins->operands[ 1 ]->n.name_class );
    ins->operands[ 1 ] = name1;
    MoveSegOp( ins, new_ins, 0 );
    PrefixIns( ins, new_ins );
    return( new_ins );
}


extern instruction      *rMULREGISTER( instruction *ins ) {
/********************************************************/

    instruction         *new_ins;
    instruction         *ins2;
    name                *name1;
    name                *name2;

    name1 = AllocRegName( Op1Reg( ins ) );
    new_ins = MakeMove( ins->operands[ 0 ], name1, ins->type_class );
    ins->operands[ 0 ] = name1;
    MoveSegOp( ins, new_ins, 0 );
    PrefixIns( ins, new_ins );
    name2 = AllocRegName( ResultReg( ins ) );
    ins2 = MakeUnary( OP_MOV, name1, ins->result, ins->type_class );
    ins2->base_type_class = DoubleClass[  ins->type_class  ];
    ins->result = name2;
    ins->zap = &AllocRegName( ZapReg( ins ) )->r;
    MoveSegRes( ins, ins2 );
    SuffixIns( ins, ins2 );
    return( new_ins );
}


extern instruction      *rDIVREGISTER( instruction *ins ) {
/********************************************************/

    instruction         *new_ins;
    instruction         *ins2;
    name                *name1;
    name                *name2;

    name1 = AllocRegName( Op1Reg( ins ) );
    new_ins = MakeConvert( ins->operands[ 0 ], name1,
                          DoubleClass[ins->type_class],
                          ins->type_class );
    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;
    ins->zap = &AllocRegName( ZapReg( ins ) )->r;
    MoveSegRes( ins, ins2 );
    SuffixIns( ins, ins2 );
    return( new_ins );
}

extern  name    *IntEquivalent( name *name ) {
/********************************************/

    constant_defn       *defn;
    unsigned_32         *value;

    defn = GetFloat( name, FS );
    value = (unsigned_32 *)defn->value;
    return( AllocConst( CFCnvU32F( _TargetBigInt( *value ) ) ) );
}

extern  name    *Int64Equivalent( name *name ) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?