mipssplit.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 427 行 · 第 1/2 页
C
427 行
/****************************************************************************
*
* 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: MIPS specific instruction reductions.
*
****************************************************************************/
#include "standard.h"
#include "coderep.h"
#include "opcodes.h"
#include "vergen.h"
#include "tables.h"
#include "pattern.h"
#include "rtclass.h"
#include "zoiks.h"
#include "model.h"
#include "procdef.h"
#include <assert.h>
extern name *AllocMemory( pointer, type_length, cg_class, type_class_def );
extern name *AllocIndex( name *, name *, type_length, type_class_def );
extern name *AllocS32Const( signed_32 );
extern name *AllocRegName( hw_reg_set );
extern name *AllocTemp( type_class_def );
extern name *AllocAddrConst( name *, int, constant_class, type_class_def );
extern name *ScaleIndex( name *, name *, type_length, type_class_def, type_length, int, i_flags );
extern name *STempOffset( name *, type_length, type_class_def, type_length );
extern hw_reg_set StackReg( void );
extern hw_reg_set ScratchReg( void );
extern hw_reg_set ReturnAddrReg( void );
extern void SuffixIns( instruction *, instruction * );
extern void PrefixIns( instruction *, instruction * );
extern void ReplIns( instruction *, instruction * );
extern label_handle RTLabel( int );
extern void ChangeType( instruction *, type_class_def );
extern void FreeIns( instruction * );
extern instruction *MakeNary( opcode_defs, name *, name *, name *, type_class_def, type_class_def, int );
extern instruction *MakeBinary( opcode_defs, name *, name *, name *, type_class_def );
extern instruction *MakeMove( name*, name *, type_class_def );
extern instruction *MakeConvert( name *, name *, type_class_def, type_class_def );
extern instruction *MakeUnary( opcode_defs, name *, name *, type_class_def );
extern instruction *MakeCondition( opcode_defs, name *, name *, int, int, type_class_def );
extern instruction *NewIns( int );
extern instruction *rSWAPCMP( instruction * );
extern void UpdateLive( instruction *, instruction * );
extern name *OffsetMem( name *, type_length, type_class_def );
extern opcode_entry *OpcodeTable( table_def );
extern type_length TypeClassSize[];
extern type_class_def Unsigned[];
extern type_length MaxStack;
extern proc_def *CurrProc;
extern instruction *rMOVEXX_8( instruction *ins )
/************************************************/
{
name *bit_mask;
name *temp;
name *temp_2;
name *src;
name *dst;
type_length curr; // which quad word we are currently on
type_length size; // size of the structure
type_length quads; // number of full quad-word writes to use
type_length rem; // number of bytes to write after last quad
instruction *new_ins;
instruction *first_ins;
instruction *last_ins;
/*
* Bust up a MOVXX into a series of 8-byte moves - we are guaranteed
* that both the source and dest are 8-byte aligned.
*/
assert( ins->operands[0]->n.class == N_TEMP || ins->operands[0]->n.class == N_INDEXED );
temp = AllocTemp( U8 );
size = ins->operands[0]->n.size;
first_ins = NULL;
last_ins = NULL;
curr = 0;
quads = size / 8;
rem = size % 8;
if( rem ) {
if( ins->result->n.class == N_TEMP ) {
if( ( ins->result->t.temp_flags & ALIAS ) == EMPTY ) {
// we have a write to a struct on the stack which is a master
// since we don't 'pack' anything into the empty space after
// this struct, we can safely overwrite it and not bother
// doing the non-destructive last quad-word write
quads += 1;
rem = 0;
}
}
}
while( quads ) {
src = OffsetMem( ins->operands[0], curr, U8 );
dst = OffsetMem( ins->result, curr, U8 );
curr += 8;
quads -= 1;
new_ins = MakeMove( src, temp, U8 );
PrefixIns( ins, new_ins );
if( first_ins == NULL ) {
first_ins = new_ins;
}
new_ins = MakeMove( temp, dst, U8 );
if( quads == 0 && rem == 0 ) {
ReplIns( ins, new_ins );
last_ins = new_ins;
} else {
PrefixIns( ins, new_ins );
}
}
if( rem != 0 ) {
if( rem == 4 ) {
src = OffsetMem( ins->operands[0], curr, U4 );
dst = OffsetMem( ins->result, curr, U4 );
temp_2 = AllocTemp( U4 );
new_ins = MakeMove( src, temp_2, U4 );
PrefixIns( ins, new_ins );
if( first_ins == NULL ) {
first_ins = new_ins;
}
new_ins = MakeMove( temp_2, dst, U4 );
ReplIns( ins, new_ins );
last_ins = new_ins;
} else {
src = OffsetMem( ins->operands[0], curr, U8 );
dst = OffsetMem( ins->result, curr, U8 );
temp_2 = AllocTemp( U8 );
bit_mask = AllocS32Const( ( 1 << rem ) - 1 );
new_ins = MakeMove( src, temp, U8 );
PrefixIns( ins, new_ins );
if( first_ins == NULL ) {
first_ins = new_ins;
}
new_ins = MakeMove( dst, temp_2, U8 );
PrefixIns( ins, new_ins );
new_ins = MakeBinary( OP_ZAP_NOT, temp, bit_mask, temp, U8 );
PrefixIns( ins, new_ins );
new_ins = MakeBinary( OP_ZAP, temp_2, bit_mask, temp_2, U8 );
PrefixIns( ins, new_ins );
new_ins = MakeBinary( OP_OR, temp_2, temp, temp, U8 );
PrefixIns( ins, new_ins );
new_ins = MakeMove( temp, dst, U8 );
ReplIns( ins, new_ins );
last_ins = new_ins;
}
}
UpdateLive( first_ins, last_ins );
return( first_ins );
}
extern instruction *rCONSTLOAD( instruction *ins )
/************************************************/
{
unsigned_32 low;
unsigned_32 high;
unsigned_32 c;
name *high_part;
name *temp;
instruction *first_ins;
instruction *new_ins;
type_class_def class;
assert( ins->operands[0]->n.class == N_CONSTANT );
assert( ins->operands[0]->c.const_type == CONS_ABSOLUTE );
class = ins->type_class;
c = ins->operands[0]->c.int_value;
high = ( c >> 16 ) & 0xffff;
low = c & 0xffff;
high_part = AllocAddrConst( NULL, high, CONS_HIGH_ADDR, class );
temp = AllocTemp( class );
first_ins = MakeMove( high_part, temp, class );
PrefixIns( ins, first_ins );
new_ins = MakeBinary( OP_OR, temp, AllocS32Const( low ), ins->result, class );
ReplIns( ins, new_ins );
UpdateLive( first_ins, new_ins );
return( first_ins );
}
extern instruction *rLOAD_4U( instruction *ins )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?