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