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