s37split.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 943 行 · 第 1/2 页

C
943
字号
/****************************************************************************
*
*                            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 "typedef.h"
#include "opcodes.h"
#include "pattern.h"
#include "regset.h"
#include "model.h"
#include "vergen.h"
#include "zoiks.h"
#include "conflict.h"
#include "cfloat.h"

#include "s37split.def"

extern  instruction     *MakeBinary(opcode_defs,name*,name*,name*,type_class_def);
extern  instruction     *MakeMove(name*,name*,type_class_def);
extern instruction      *MoveConst(unsigned_32 ,name *,type_class_def );
extern  instruction     *MakeUnary(opcode_defs,name*,name*,type_class_def);
extern  instruction     *MakeConvert(name*,name*,type_class_def,type_class_def);
extern  name            *AllocIntConst(int);
extern  name            *AllocS32Const(signed_32);
extern  name            *AllocConst(pointer);
extern  cfloat          *CFCnvU32F(unsigned_32);
extern  name            *AllocTemp(type_class_def);
extern  name            *SAllocTemp(type_class_def,type_length);
extern  name            *TempOffset(name*,type_length,type_class_def);
extern  void            PrefixIns(instruction*,instruction*);
extern  void            ReplIns(instruction*,instruction*);
extern  void            SuffixIns(instruction*,instruction*);
extern  name            *AllocAddrConst(name*,int,constant_class,type_class_def);
extern  void            ChangeType(instruction*,type_class_def);
extern  name            *ScaleIndex(name*,name*,type_length,type_class_def,type_length,int,i_flags);
extern  name            *AllocRegName(hw_reg_set);
extern  conflict_node   *GiveRegister(conflict_node*,bool);
extern  conflict_node   *NameConflict(instruction*,name*);
extern  hw_reg_set      LowReg(hw_reg_set);
extern  void            MarkPossible(instruction*,name*,reg_set_index);
extern  void            UpdateLive(instruction*,instruction*);
extern  name            *STempOffset(name*,type_length,type_class_def,type_length);
extern  memory_name     *SAllocMemory(pointer,type_length,cg_class,type_class_def,type_length);
extern  void            DoNothing(instruction*);
extern  name            *IndexToTemp(instruction*,name*);
extern  conflict_node   *IndexSplit(instruction*,name*);

extern  instruction     *rMOVRESREG(instruction*);
extern  instruction     *rLOADOP2(instruction*);
extern  instruction     *rSWAPCMP(instruction*);
extern  instruction     *rSWAPOPS(instruction*);
extern  instruction     *rUSEREGISTER(instruction*);
extern  instruction     *rDOCVT(instruction*);
extern  instruction     *rOP1REG(instruction*);
extern  instruction     *rOP1RESTEMP(instruction*);
extern  instruction     *rOP1MEM(instruction*);
extern  instruction     *rOP2MEM(instruction*);
extern  instruction     *rFORCERESMEM(instruction*);
extern  instruction     *rMOVEINDEX(instruction*);
extern  instruction     *rMAKEADD(instruction*);
extern  instruction     *rMAKEMOVE(instruction*);
extern  instruction     *rMAKENEG(instruction*);
extern  instruction     *rMAKESUB(instruction*);
extern  instruction     *rMOVOP2(instruction*);

extern    reg_list      *RegSets[];
extern    op_regs       RegList[];
extern    byte          OptForSize;
extern    opcode_entry  MVCL[];
extern    opcode_entry  MVC[];
extern    opcode_entry  NC[];
extern    opcode_entry  OC[];
extern    opcode_entry  XC[];
extern    opcode_entry  CLC[];
extern    opcode_entry  Mul4G[];
extern    opcode_entry  Mul4I2G[];
extern    opcode_entry  Add4I2G[];
extern    opcode_entry  Sub4I2G[];
extern    opcode_entry  Mod4G[];
extern    opcode_entry  Div4G[];
extern    opcode_entry  S4to8G[];
extern    opcode_entry  S1to4G[];
extern    opcode_entry  S2to4G[];
extern    opcode_entry  Z1to4G[];
extern    opcode_entry  Z2to4G[];
extern    opcode_entry  CNormF[];
extern    type_length   TypeClassSize[];


extern instruction *(* ReduceTab[])() = {
/***************************************/

    rMOVRESREG,
    rLOADOP2,
    rSWAPCMP,
    rSWAPOPS,
    rUSEREGISTER,
    rPREPMUL,
    rPREPDIV,
    rDOCVT,
    rPREPCONV8,
    rCLRMOV8,
    rCLRMOV,
    rMOVEXT,
    rOP1REG,
    rPREPS1TO4,
    rPREPS2TO4,
    rPREPZ1TO4,
    rPREPZ2TO4,
    rMOVEADDR,
    rBIN2INT,
    rUN2INT,
    rSIDE2INT,
    rNEGDEC,
    rNOT2XOR,
    rOP1RESTEMP,
    rPREPMOD,
    rOP1MEM,
    rOP2MEM,
    rFORCERESMEM,
    rMVCL,
    rMOVEINDEX,
    rMAKEADD,
    rMAKEMOVE,
    rMAKENEG,
    rMAKESUB,
    rMOVOP2,
    rMAKEAND,
    rTEST1,
    rSTOD,
    rDTOS,
    rPREPI4I2,
    rPREPITOD,
    rPREPUTOD,
    rMEMDOWN,
    rMVC,
    rXC,
    rCLC,
    NULL
};


extern  name  *HighPart( name *tosplit, type_class_def class ) {
/*************************************************************/

    class = class; tosplit = tosplit;
    return( NULL );
}


extern  name  *LowPart( name *tosplit, type_class_def class ) {
/*************************************************************/

    class = class; tosplit = tosplit;
    return( NULL );
}


extern void CheckCC( instruction *ins1, instruction *ins ) {
/*********************************************************/

    ins1 = ins1; ins = ins;
}


extern  bool    UnChangeable( instruction *ins ) {
/************************************************/

    return( ins->table == MVCL );
}


static instruction *rPREPMUL( instruction *ins ) {
/***********************************************/

    instruction         *ins1;
    instruction         *ins2;
    name                *name1;
    name                *low;

    name1 = SAllocTemp( XX, 8 );
    low =  TempOffset( name1, WORD_SIZE, WD );
    ins1 = MakeMove( ins->operands[0], low, WD );
    ins->operands[0] = low;
    PrefixIns( ins, ins1 );
    ins2 = MakeMove( low, ins->result, WD );
    ins->result = name1;
    SuffixIns( ins, ins2 );
    ins->table = Mul4G;
    ins->u.gen_table = NULL;
    _SetTrue( NameConflict( ins, name1 ), NEVER_TOO_GREEDY );
    return( ins1 );
}

static instruction *rPREPI4I2( instruction *ins ) {
/**********************************************
    If you I4 op I2 is handled then send to a I4I2 table
*/
    if( ins->head.opcode == OP_MUL ){
        ins->table = Mul4I2G;
    }else if( ins->head.opcode == OP_ADD ){
        ins->table = Add4I2G;
    }else if( ins->head.opcode == OP_SUB ){
        ins->table = Sub4I2G;
    }else{
        Zoiks( ZOIKS_019 );
        ins->table = NULL;
    }
    ins->u.gen_table = NULL;
    return( ins );
}


static instruction *PrepModDiv( instruction *ins, int off, opcode_entry *tbl ) {
/******************************************************************************/

    instruction         *ins1;
    instruction         *ins2;
    name                *name1;
    name                *low;

    name1 = SAllocTemp( XX, 8 );
    ins1 = MakeConvert( ins->operands[0], name1, XX, ins->type_class );
    ins->operands[0] = name1;
    PrefixIns( ins, ins1 );
    low =  TempOffset( name1, off, WD );
    ins2 = MakeMove( low, ins->result, WD );
    ins->result = name1;
    SuffixIns( ins, ins2 );
    ins->table = tbl;
    _SetTrue( NameConflict( ins, name1 ), NEVER_TOO_GREEDY );
    return( ins1 );
}


static instruction *rPREPDIV( instruction *ins ) {
/***********************************************/

    return( PrepModDiv( ins, WORD_SIZE, Div4G ) );
}

static instruction *rPREPMOD( instruction *ins ) {
/***********************************************/

    return( PrepModDiv( ins, 0, Mod4G ) );
}

static instruction *rPREPCONV8( instruction *ins ) {
/**************************************************/
    instruction         *ins1;
    name                *high;

    high =  TempOffset( ins->result, 0, WD );
    ins1 = MakeMove( ins->operands[0], high, WD );
    ins->operands[0] = high;
    PrefixIns( ins, ins1 );
    ins->table = S4to8G; /* set to gen table */
    return( ins1 );
}


static instruction *rCLRMOV8( instruction *ins ) {
/**************************************************/

/* change a CONV to a clear high word move U4 to low */

    instruction         *ins1;
    instruction         *ins2;
    name                *high;
    name                *low;

    high =  TempOffset( ins->result, 0, WD );
    ins1 = MakeMove( AllocIntConst( 0 ), high, WD );
    PrefixIns( ins, ins1 );
    low =  TempOffset( ins->result, WORD_SIZE, WD );
    ins2 = MakeMove( ins->operands[0], low, WD );
    ReplIns( ins, ins2 );
    return( ins1 );
}


static instruction *rCLRMOV( instruction *ins ) {
/**************************************************/

/*  Assume unsigned CONV clear result then move value in */

    instruction         *ins1;
    instruction         *ins2;

    ins1 = MakeMove( AllocIntConst( 0 ), ins->result, ins->type_class );
    PrefixIns( ins, ins1 );
    ins2 = MakeMove( ins->operands[0], ins->result, ins->base_type_class );
    ReplIns( ins, ins2 );
    return( ins1 );
}


static instruction *rMOVEXT( instruction *ins ) {
/**************************************************/

/*  Assume CONV move then extend in */

    instruction         *ins1;
    instruction         *ins2;
    int                 shift;

    ins1 = MakeMove( ins->operands[0], ins->result, ins->base_type_class );
    PrefixIns( ins, ins1 );
    shift = (ins->result->n.size - ins->operands[0]->n.size)*8;
    /* mjc a bit sys dependent */
    ins2 = MakeBinary( OP_RSHIFT, ins->result, AllocIntConst( shift ),
                       ins->result, ins->type_class );
    ReplIns( ins, ins2 );
    return( ins1 );
}



static instruction *PrepCnvUp( instruction *ins, opcode_entry *table ) {
/**********************************************************************/

    name        *temp;
    instruction *new_ins;

    temp = AllocTemp( WD );
    new_ins = MakeMove( temp, ins->result, WD );
    ins->result = temp;
    SuffixIns( ins, new_ins );
    ins->table = table;
    ins->u.gen_table = NULL;
    _SetTrue( NameConflict( ins, temp ), NEVER_TOO_GREEDY );
    return( ins );
}


static instruction *rPREPS1TO4( instruction *ins ) {
/*************************************************/

    return( PrepCnvUp( ins, S1to4G ) );
}


static instruction *rPREPS2TO4( instruction *ins ) {
/*************************************************/

    return( PrepCnvUp( ins, S2to4G ) );
}


static instruction *rPREPZ1TO4( instruction *ins ) {
/*************************************************/

    return( PrepCnvUp( ins, Z1to4G ) );
}


static instruction *rPREPZ2TO4( instruction *ins ) {
/*************************************************/
    #if 0
    name        *temp;
    instruction *new_ins;

    temp = ins->operands[0];
    if( temp->n.class == N_TEMP ){
        ins =  rOP1MEM(ins);
    }
    if( temp->n.class == N_REGISTER ){
        temp = AllocTemp( U2 );
        temp->v.usage |= USE_MEMORY | NEEDS_MEMORY;
         new_ins = MakeMove( ins->operands[0], temp, U2 );
        ins->operands[ 0 ] = temp;
        PrefixIns( ins, new_ins );
        temp->v.usage |= USE_MEMORY | NEEDS_MEMORY;
        new_ins = ins;
    }
    #endif
    ins = PrepCnvUp( ins, Z2to4G );
    return( ins );
}


extern name  *FArea = NULL;
static  name *InitItoF( void ) {
/************************************************
    Add the ItoF work area used by converion routines
*/
    extern block *HeadBlock;
    instruction *start;
    instruction *ins;
    name        *low;
    name        *dwork;

    start = HeadBlock->ins.hd.next;
    dwork = SAllocTemp( FD, 8 );
    dwork->v.usage |= USE_MEMORY | NEEDS_MEMORY;
    low =  TempOffset( dwork, 0, WD );
    ins = MoveConst(  0x4E000000, low, WD );
    PrefixIns( start, ins );
    return( dwork );
}

static name *ItoFArea( void ){
    if( FArea == NULL ){
        FArea = InitItoF();
    }
    return( FArea );
}

static instruction *rPREPITOD( instruction *ins ) {
/*************************************************
    CONV    FD I4  op1 -> result =>
    XOR     op1 0X80000000 ->temp
    MOV     0x4E000000 -> high part of FD in mem
    MOV     temp -> low
    MOV     FD  -> temp FD
    SUB     TEMP - (FD)0X80000000 ->result
*/
    instruction         *ins1;
    instruction         *ins2;
    name                *dwork;
    name                *ipart;
    name                *temp;
    name                *theconst;

    temp = AllocTemp( WD );
    theconst =  AllocConst( CFCnvU32F(0x80000000  ) );
    ins1 = MakeBinary( OP_XOR, ins->operands[0],
                       theconst,
                       temp, WD );
    ins->operands[0] = temp;
    PrefixIns( ins, ins1 );
 #if 0    /* if we haven't pre-allocated a work area */
    dwork = SAllocTemp( FD, 8 );
    dwork->v.usage |= USE_MEMORY | NEEDS_MEMORY;
    ipart =  TempOffset( dwork, 0, WD );
    ins2 = MoveConst(  0x4E000000, ipart, WD );
    PrefixIns( ins, ins2 );
#else
    dwork = ItoFArea();
#endif
    ipart =  TempOffset( dwork, WORD_SIZE, WD );
    ins2 = MakeMove( temp, ipart, WD );
    ins->operands[0] = ipart;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?