386splt2.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 750 行 · 第 1/2 页
C
750 行
/****************************************************************************
*
* 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"
#include "cfloat.h"
#include "conflict.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 *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 instruction *MakeConvert(name*,name*,type_class_def,type_class_def);
extern void HalfType(instruction*);
extern hw_reg_set High64Reg(hw_reg_set);
extern hw_reg_set High48Reg(hw_reg_set);
extern hw_reg_set High32Reg(hw_reg_set);
extern hw_reg_set High16Reg(hw_reg_set);
extern hw_reg_set Low64Reg(hw_reg_set);
extern hw_reg_set Low48Reg(hw_reg_set);
extern hw_reg_set Low32Reg(hw_reg_set);
extern hw_reg_set Low16Reg(hw_reg_set);
extern name *AllocMemory(pointer,type_length,cg_class,type_class_def);
extern name *TempOffset(name*,type_length,type_class_def);
extern name *AllocRegName(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 name *ScaleIndex(name*,name*,type_length,type_class_def,type_length,int,i_flags);
extern name *AllocS32Const(signed_32);
extern name *OpAdjusted( name *, int, type_class_def );
extern int NumOperands(instruction*);
extern bool Overlaps( name *, name * );
extern void CnvOpToInt( instruction *, int );
extern name *Int64Equivalent( name * );
extern type_class_def HalfClass[];
extern type_class_def Unsigned[];
extern name *LowPart( name *tosplit, type_class_def class ) {
/************************************************************/
name *new;
signed_8 s8;
unsigned_8 u8;
signed_16 s16;
unsigned_16 u16;
unsigned_32 u32;
constant_defn *floatval;
switch( tosplit->n.class ) {
case N_CONSTANT:
if( tosplit->c.const_type == CONS_ABSOLUTE ) {
if( class == U1 ) {
u8 = tosplit->c.int_value & 0xff;
new = AllocUIntConst( u8 );
} else if( class == I1 ) {
s8 = tosplit->c.int_value & 0xff;
new = AllocIntConst( s8 );
} else if( class == U2 ) {
u16 = tosplit->c.int_value & 0xffff;
new = AllocUIntConst( u16 );
} else if( class == I2 ) {
s16 = tosplit->c.int_value & 0xffff;
new = AllocIntConst( s16 );
} else if( class == I4 ) {
new = AllocS32Const( tosplit->c.int_value );
} else if( class == U4 ) {
new = AllocUIntConst( tosplit->c.int_value );
} else if( class == FL ) {
_Zoiks( ZOIKS_129 );
} else { /* FD */
floatval = GetFloat( tosplit, FD );
u32 = (unsigned_32)floatval->value[ 1 ] << 16;
u32 += floatval->value[ 0 ];
new = AllocConst( CFCnvU32F( _TargetLongInt( u32 ) ) );
}
} else if( tosplit->c.const_type == CONS_ADDRESS ) {
new = AddrConst( tosplit->c.value,
tosplit->c.int_value, CONS_OFFSET );
} else {
_Zoiks( ZOIKS_044 );
}
break;
case N_REGISTER:
if( class == U1 || class == I1 ) {
new = AllocRegName( Low16Reg( tosplit->r.reg ) );
} else if( class == U2 || class == I2 ) {
new = AllocRegName( Low32Reg( tosplit->r.reg ) );
} else {
new = AllocRegName( Low64Reg( tosplit->r.reg ) );
}
break;
case N_TEMP:
new = TempOffset( tosplit, 0, class );
if( new->t.temp_flags & CONST_TEMP ) {
name *cons = tosplit->v.symbol;
if( tosplit->n.name_class == FD ) {
cons = Int64Equivalent( cons );
}
new->v.symbol = LowPart( cons, class );
}
break;
case N_MEMORY:
new = AllocMemory( tosplit->v.symbol, tosplit->v.offset,
tosplit->m.memory_type, class );
new->v.usage = tosplit->v.usage;
break;
case N_INDEXED:
new = ScaleIndex( tosplit->i.index, tosplit->i.base,
tosplit->i.constant, class,
0, tosplit->i.scale, tosplit->i.index_flags );
break;
}
return( new );
}
extern name *OffsetPart( name *tosplit ) {
/********************************************/
name *new;
switch( tosplit->n.class ) {
case N_REGISTER:
return( AllocRegName( Low48Reg( tosplit->r.reg) ) );
case N_CONSTANT:
if( tosplit->c.const_type == CONS_ABSOLUTE ) {
return( tosplit );
} else if( tosplit->c.const_type == CONS_ADDRESS ) {
return( AddrConst( tosplit->c.value,
tosplit->c.int_value, CONS_OFFSET ) );
} else {
_Zoiks( ZOIKS_044 );
return( tosplit );
}
case N_TEMP:
new = LowPart( tosplit, U4 );
if( new->t.temp_flags & CONST_TEMP ) {
new->v.symbol = OffsetPart( tosplit->v.symbol );
}
return( new );
case N_MEMORY:
case N_INDEXED:
return( LowPart( tosplit, U4 ) );
default:
_Zoiks( ZOIKS_129 );
return( NULL );
}
}
extern name *SegmentPart( name *tosplit ) {
/**********************************************/
name *new;
name *seg;
switch( tosplit->n.class ) {
case N_CONSTANT:
if( tosplit->c.const_type == CONS_ABSOLUTE ) {
return( AllocIntConst( 0 ) );
} else if( tosplit->c.const_type == CONS_ADDRESS ) {
return( AddrConst( tosplit->c.value,
tosplit->c.int_value, CONS_SEGMENT ) );
} else {
_Zoiks( ZOIKS_044 );
return( NULL );
}
break;
case N_REGISTER:
return( AllocRegName( High48Reg( tosplit->r.reg ) ) );
case N_TEMP:
new = TempOffset( tosplit, 4, U2 );
if( new->t.temp_flags & CONST_TEMP ) {
seg = SegmentPart( tosplit->v.symbol );
if( seg->n.class == N_REGISTER ) return( seg );
new->v.symbol = seg;
}
return( new );
case N_MEMORY:
new = AllocMemory( tosplit->v.symbol,
tosplit->v.offset + 4,
tosplit->m.memory_type, U2 );
new->v.usage = tosplit->v.usage;
return( new );
case N_INDEXED:
new = ScaleIndex( tosplit->i.index, tosplit->i.base,
tosplit->i.constant+ 4, U2, 0,
tosplit->i.scale, tosplit->i.index_flags );
return( new );
default:
_Zoiks( ZOIKS_129 );
return( NULL );
}
}
extern name *HighPart( name *tosplit, type_class_def class ) {
/*************************************************************/
name *new;
signed_8 s8;
unsigned_8 u8;
signed_16 s16;
unsigned_16 u16;
unsigned_32 u32;
constant_defn *floatval;
switch( tosplit->n.class ) {
case N_CONSTANT:
if( tosplit->c.const_type == CONS_ABSOLUTE ) {
if( class == U1 ) {
u8 = ( tosplit->c.int_value >> 8 ) & 0xff;
new = AllocUIntConst( u8 );
} else if( class == I1 ) {
s8 = ( tosplit->c.int_value >> 8 ) & 0xff;
new = AllocIntConst( s8 );
} else if( class == U2 ) {
u16 = ( tosplit->c.int_value >> 16 ) & 0xffff;
new = AllocUIntConst( u16 );
} else if( class == I2 ) {
s16 = ( tosplit->c.int_value >> 16 ) & 0xffff;
new = AllocIntConst( s16 );
} else if( class == I4 ) {
new = AllocS32Const( tosplit->c.int_value_2 );
} else if( class == U4 ) {
new = AllocUIntConst( tosplit->c.int_value_2 );
} else if( class == FL ) {
_Zoiks( ZOIKS_129 );
} else { /* FD */
floatval = GetFloat( tosplit, FD );
u32 = (unsigned_32)floatval->value[ 3 ] << 16;
u32 += floatval->value[ 2 ];
new = AllocConst( CFCnvU32F( _TargetLongInt( u32 ) ) );
}
} else if( tosplit->c.const_type == CONS_ADDRESS ) {
new = AddrConst( tosplit->c.value,
tosplit->c.int_value, CONS_SEGMENT );
} else {
_Zoiks( ZOIKS_044 );
}
break;
case N_REGISTER:
if( class == U1 || class == I1 ) {
new = AllocRegName( High16Reg( tosplit->r.reg ) );
} else if( class == U2 || class == I2 ) {
new = AllocRegName( High32Reg( tosplit->r.reg ) );
} else {
new = AllocRegName( High64Reg( tosplit->r.reg ) );
}
break;
case N_TEMP:
new = TempOffset( tosplit, tosplit->n.size/2, class );
if( new->t.temp_flags & CONST_TEMP ) {
name *cons = tosplit->v.symbol;
if( tosplit->n.name_class == FD ) {
cons = Int64Equivalent( cons );
}
new->v.symbol = HighPart( cons, class );
}
break;
case N_MEMORY:
new = AllocMemory( tosplit->v.symbol,
tosplit->v.offset + tosplit->n.size/2,
tosplit->m.memory_type, class );
new->v.usage = tosplit->v.usage;
break;
case N_INDEXED:
new = ScaleIndex( tosplit->i.index, tosplit->i.base,
tosplit->i.constant+ tosplit->n.size/2, class,
0, tosplit->i.scale, tosplit->i.index_flags );
break;
}
return( new );
}
extern instruction *SplitUnary( instruction *ins ) {
/*******************************************************/
/* Pushing floating point */
instruction *new_ins;
name *high_res;
name *low_res;
HalfType( ins );
if( ins->result == NULL ) {
high_res = NULL;
low_res = NULL;
} else {
high_res = HighPart( ins->result, ins->type_class );
low_res = LowPart( ins->result, ins->type_class );
}
new_ins = MakeUnary( ins->head.opcode,
LowPart( ins->operands[ 0 ], ins->type_class ),
low_res, ins->type_class );
ins->operands[ 0 ] = HighPart( ins->operands[ 0 ],ins->type_class );
ins->result = high_res;
if( ins->head.opcode == OP_PUSH ) {
DupSeg( ins, new_ins );
SuffixIns( ins, new_ins );
new_ins = ins;
} else {
DupSeg( ins, new_ins );
PrefixIns( ins, new_ins );
}
return( new_ins );
}
extern instruction *rSPLITPUSH( instruction *ins ) {
/*******************************************************/
/* Pushing a 6 byte pointer */
instruction *new_ins;
instruction *ins2;
name *op;
name *temp;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?