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