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