i86half.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 456 行 · 第 1/2 页
C
456 行
/****************************************************************************
*
* 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 "opcodes.h"
#include "pattern.h"
#include "regset.h"
#include "model.h"
#include "vergen.h"
#include "system.h"
#include "zoiks.h"
extern void ChangeType(instruction*,type_class_def);
extern name *IntEquivalent(name*);
extern void DupSegOp(instruction*,instruction*,int);
extern name *AllocTemp(type_class_def);
extern opcode_entry *CodeTable(instruction*);
extern bool SameThing(name*,name*);
extern instruction *MakeConvert(name*,name*,type_class_def,type_class_def);
extern instruction *MoveConst(unsigned_32,name*,type_class_def);
extern instruction *MakeMove(name*,name*,type_class_def);
extern constant_defn *GetFloat(name*,type_class_def);
extern void UpdateLive(instruction*,instruction*);
extern void DupSegRes(instruction*,instruction*);
extern void MoveSegOp(instruction*,instruction*,int);
extern instruction *MakeBinary(opcode_defs,name*,name*,name*,type_class_def);
extern void SuffixIns(instruction*,instruction*);
extern instruction *MakeUnary(opcode_defs,name*,name*,type_class_def);
extern void HalfType(instruction*);
extern hw_reg_set High32Reg(hw_reg_set);
extern hw_reg_set High16Reg(hw_reg_set);
extern name *AllocMemory(pointer,type_length,cg_class,type_class_def);
extern name *TempOffset(name*,type_length,type_class_def);
extern hw_reg_set Low32Reg(hw_reg_set);
extern name *AllocRegName(hw_reg_set);
extern hw_reg_set Low16Reg(hw_reg_set);
extern name *AddrConst(name*,int,constant_class);
extern name *AllocIntConst(int);
extern name *AllocUIntConst(uint);
extern name *AllocConst(pointer);
extern instruction *MakeCondition(opcode_defs,name*,name*,int,int,type_class_def);
extern void ReplIns(instruction*,instruction*);
extern void PrefixIns(instruction*,instruction*);
extern void DupSeg(instruction*,instruction*);
extern name *SegName(name*);
extern void DelSeg(instruction*);
extern name *ScaleIndex(name*,name*,type_length,type_class_def,type_length,int,i_flags);
extern name *AllocIntConst(int);
extern bool Overlaps( name *, name * );
extern instruction *MakeNop(void);
extern name *LowPart( name *, type_class_def );
extern name *HighPart( name *, type_class_def );
extern void CnvOpToInt( instruction *, int );
extern type_class_def HalfClass[];
extern type_class_def Unsigned[];
static bool IndexOverlaps( instruction *ins, int i ) {
/********************************************************/
if( ins->operands[ i ]->n.class != N_INDEXED ) return( FALSE );
if( SameThing( ins->operands[ i ]->i.index, ins->result ) ) return( TRUE );
return( FALSE );
}
#if _TARGET & _TARG_80386
#define WORD U4
#define HALF_WORD U2
#define LONG_WORD U8
#define LONG_WORD_S I8
#define HIGH_WORD( x ) ( (x)->c.int_value_2 )
#else
#define WORD U2
#define HALF_WORD U1
#define LONG_WORD U4
#define LONG_WORD_S I4
#define HIGH_WORD(x) ( ( ((x)->c.int_value) >> 16 ) & 0xffff )
#endif
extern instruction *rSPLITOP( instruction *ins ) {
/****************************************************/
instruction *new_ins;
instruction *ins2;
name *temp;
if( IndexOverlaps( ins, 0 ) || IndexOverlaps( ins, 1 ) ) {
temp = AllocTemp( LONG_WORD );
HalfType( ins );
new_ins = MakeBinary( ins->head.opcode,
LowPart( ins->operands[ 0 ], WORD ),
LowPart( ins->operands[ 1 ], WORD ),
LowPart( temp, WORD ),
WORD );
ins2 = MakeBinary( ins->head.opcode,
HighPart( ins->operands[ 0 ], WORD ),
HighPart( ins->operands[ 1 ], WORD ),
HighPart( temp, WORD ),
WORD );
if( ins->head.opcode == OP_ADD ) {
ins2->head.opcode = OP_EXT_ADD;
} else if( ins->head.opcode == OP_SUB ) {
ins2->head.opcode = OP_EXT_SUB;
}
ins2->table = CodeTable( ins2 );
new_ins->table = ins2->table;
DupSegOp( ins, new_ins, 0 );
DupSegOp( ins, ins2, 0 );
DupSegOp( ins, new_ins, 1 );
DupSegOp( ins, ins2, 1 );
ins->operands[ 0 ] = temp;
ins->operands[ 1 ] = temp;
PrefixIns( ins, new_ins );
PrefixIns( ins, ins2 );
ins2 = MakeMove( LowPart( temp, WORD ), LowPart( ins->result, WORD ), WORD );
DupSegRes( ins, ins2 );
PrefixIns( ins, ins2 );
ins2 = MakeMove( HighPart( temp, WORD ),
HighPart( ins->result, WORD ), WORD );
DupSegRes( ins, ins2 );
ReplIns( ins, ins2 );
} else {
HalfType( ins );
new_ins = MakeBinary( ins->head.opcode,
LowPart( ins->operands[ 0 ], ins->type_class ),
LowPart( ins->operands[ 1 ], ins->type_class ),
LowPart( ins->result, ins->type_class ),
ins->type_class );
DupSeg( ins, new_ins );
ins->operands[ 0 ] = HighPart( ins->operands[ 0 ], ins->type_class );
ins->operands[ 1 ] = HighPart( ins->operands[ 1 ], ins->type_class );
ins->result = HighPart( ins->result, ins->type_class );
if( ins->head.opcode == OP_ADD ) {
ins->head.opcode = OP_EXT_ADD;
} else if( ins->head.opcode == OP_SUB ) {
ins->head.opcode = OP_EXT_SUB;
}
/* Assign fake reduce table (from OP_EXT) to new_ins; default reduce table
can generate INC and DEC which'll not set condition codes
*/
ins->table = CodeTable( ins );
new_ins->table = ins->table;
PrefixIns( ins, new_ins );
}
new_ins->ins_flags |= INS_CC_USED;
return( new_ins );
}
extern instruction *rSPLITMOVE( instruction *ins ) {
/******************************************************/
instruction *new_ins;
instruction *ins2;
name *temp;
CnvOpToInt( ins, 0 );
if( IndexOverlaps( ins, 0 ) ) {
temp = AllocTemp( LONG_WORD );
new_ins = MakeMove( LowPart( ins->operands[ 0 ], WORD ),
LowPart( temp, WORD ), WORD );
ins2 = MakeMove( HighPart( ins->operands[ 0 ], WORD ),
HighPart( temp, WORD ), WORD );
DupSegOp( ins, new_ins, 0 );
DupSegOp( ins, ins2, 0 );
ins->operands[ 0 ] = temp;
PrefixIns( ins, new_ins );
PrefixIns( ins, ins2 );
ins2 = MakeMove( LowPart( temp, WORD ), LowPart( ins->result, WORD ), WORD );
DupSegRes( ins, ins2 );
PrefixIns( ins, ins2 );
ins2 = MakeMove( HighPart( temp, WORD ),
HighPart( ins->result, WORD ), WORD );
ReplIns( ins, ins2 );
} else {
HalfType( ins );
new_ins = MakeMove( LowPart( ins->operands[ 0 ], ins->type_class ),
LowPart( ins->result, ins->type_class ),
ins->type_class );
DupSeg( ins, new_ins );
ins->operands[ 0 ] = HighPart( ins->operands[ 0 ], ins->type_class );
ins->result = HighPart( ins->result, ins->type_class );
if( new_ins->result->n.class == N_REGISTER
&& ins->operands[ 0 ]->n.class == N_REGISTER
&& HW_Ovlap( new_ins->result->r.reg, ins->operands[ 0 ]->r.reg ) ) {
SuffixIns( ins, new_ins );
new_ins = ins;
} else {
PrefixIns( ins, new_ins );
}
}
return( new_ins );
}
#if _TARGET & _TARG_IAPX86
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?