mipsconv.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 304 行

C
304
字号
/****************************************************************************
*
*                            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 machine type conversion routines.
*
****************************************************************************/


#include "standard.h"
#include "pattern.h"
#include "coderep.h"
#include "tables.h"
#include "opcodes.h"
#include "regset.h"
#include "funits.h"
#include "vergen.h"
#include "zoiks.h"
#include "model.h"

extern  name            *AllocS32Const( signed_32 );
extern  name            *AllocTemp( type_class_def );
extern  instruction     *MakeUnary( opcode_defs, name *, name *, type_class_def );
extern  instruction     *MakeBinary( opcode_defs, name *, name *, name *, type_class_def );
extern  instruction     *MakeConvert( name *, name *, type_class_def, type_class_def );
extern  void            PrefixIns( instruction *, instruction * );
extern  instruction*    MakeMove( name *, name *, type_class_def );
extern  void            ReplIns( instruction *, instruction * );
extern  opcode_entry    *OpcodeTable( table_def );
extern  void            UpdateLive( instruction *, instruction * );
extern  name            *TrimConst( name *, type_class_def );

extern  int     RoutineNum;


static  opcode_entry    FDTOSTable[] = {
/**************************************/
/*   from  to   eq        verify        gen             reg           fu*/
_Un( R,    R,   NONE ),   V_NO,         G_CVTTS,        RG_FLOAT,     FU_NO,
_Un( C,    ANY, NONE ),   V_NO,         R_FORCEOP1CMEM, RG_FLOAT,     FU_NO,
_Un( M,    ANY, NONE ),   V_NO,         R_MOVOP1TEMP,   RG_FLOAT,     FU_NO,
_Un( ANY,  M,   NONE ),   V_NO,         R_MOVRESTEMP,   RG_FLOAT,     FU_NO,
_Un( ANY,  ANY, NONE ),   V_NO,         G_UNKNOWN,      RG_FLOAT_NEED,FU_NO,
};


static instruction *cFDTOS( instruction *ins )
{
    ins->table = &FDTOSTable[0];
    return( ins );
}

static  opcode_entry    FSTODTable[] = {
/**************************************/
/*   from  to   eq        verify        gen             reg           fu*/
_Un( R,    R,   NONE ),   V_NO,         G_MOVE_FP,      RG_FLOAT,     FU_NO,
_Un( C,    ANY, NONE ),   V_NO,         R_FORCEOP1CMEM, RG_FLOAT,     FU_NO,
_Un( M,    ANY, NONE ),   V_NO,         R_MOVOP1TEMP,   RG_FLOAT,     FU_NO,
_Un( ANY,  M,   NONE ),   V_NO,         R_MOVRESTEMP,   RG_FLOAT,     FU_NO,
_Un( ANY,  ANY, NONE ),   V_NO,         G_UNKNOWN,      RG_FLOAT_NEED,FU_NO,
};


static instruction *cFSTOD( instruction *ins ) {

    ins->table = &FSTODTable[0];
    return( ins );
}

static  opcode_entry    FI8TODTable[] = {
/***************************************/
/*   from  to   eq        verify        gen             reg           fu*/
_Un( M,    R,   NONE ),   V_NO,         G_MI8TOFREG,    RG_FLOAT,     FU_NO,
_Un( M,    M,   NONE ),   V_NO,         R_MOVRESTEMP,   RG_FLOAT,     FU_NO,
_Un( R,    ANY, NONE ),   V_NO,         R_MOVOP1TEMP,   RG_QF,        FU_NO,
_Un( U,    R,   NONE ),   V_NO,         R_FORCEOP1MEM,  RG_,          FU_NO,
_Un( ANY,  ANY, NONE ),   V_NO,         G_UNKNOWN,      RG_FLOAT_NEED,FU_NO,
};


static instruction *cFI8TOD( instruction *ins )
{
    ins->table = &FI8TODTable[0];
    return( ins );
}


static instruction *cFI8TOS( instruction *ins )
{
    ins->table = &FI8TODTable[0];
    return( ins );
}

static  opcode_entry    FDTOI8Table[] = {
/***************************************/
/*   from  to   eq        verify        gen             reg           fu */
_Un( R,    M,   NONE ),   V_NO,         G_FREGTOMI8,    RG_FLOAT,     FU_NO,
_Un( M|C,  M,   NONE ),   V_NO,         R_MOVOP1REG,    RG_FLOAT,     FU_NO,
_Un( ANY,  R,   NONE ),   V_NO,         R_MOVRESTEMP,   RG_FQ,        FU_NO,
_Un( R,    U,   NONE ),   V_NO,         R_FORCERESMEM,  RG_,          FU_NO,
_Un( ANY,  ANY, NONE ),   V_NO,         G_UNKNOWN,      RG_FLOAT_NEED,FU_NO,
};

static instruction *cFDTOI8( instruction *ins )
{
    ins->table = &FDTOI8Table[0];
    return( ins );
}


static  opcode_entry    FDTOI4Table[] = {
/***************************************/
/*   from  to   eq        verify        gen             reg           fu */
_Un( R,    M,   NONE ),   V_NO,         G_FREGTOMI8,    RG_FLOAT,     FU_NO,
_Un( M|C,  M,   NONE ),   V_NO,         R_MOVOP1REG,    RG_FLOAT,     FU_NO,
_Un( ANY,  R,   NONE ),   V_NO,         R_MOVRESTEMP,   RG_FQ,        FU_NO,
_Un( R,    U,   NONE ),   V_NO,         R_FORCERESMEM,  RG_,          FU_NO,
_Un( ANY,  ANY, NONE ),   V_NO,         G_UNKNOWN,      RG_FLOAT_NEED,FU_NO,
};

static instruction *cFDTOI4( instruction *ins )
{
    ins->table = &FDTOI4Table[0];
    return( ins );
}


typedef enum {
    FIRST_METHOD = XX,  // last typeclass from typclass.h
    NA,
    OK,
    #define _C_( a )    a,
    #include "convert.h"
    #undef _C_
    LST
} conv_method;

typedef instruction *(*convert_rtn)( instruction * );

#define CONVERT_ROUTINE( x, gen, reg )                                                          \
static  opcode_entry    ctable_##x[] = {                                                        \
/**************************************/                                                        \
/*      from    to      eq              verify          gen             reg       fu */         \
_Un(    R,      R,      NONE ),         V_NO,           gen,            RG_##reg, FU_ALU,       \
_Un(    R,      M,      NONE ),         V_NO,           R_MOVRESREG,    RG_##reg, FU_NO,        \
_Un(    M,      ANY,    NONE ),         V_NO,           R_MOVOP1REG,    RG_##reg, FU_NO,        \
_Un(    ANY,    ANY,    NONE ),         V_NO,           G_UNKNOWN,      RG_##reg##_NEED, FU_NO, \
};                                                                                              \
static instruction *c##x( instruction *ins ) { ins->table = &ctable_##x[0]; return( ins ); }

CONVERT_ROUTINE( Z1TO2, G_ZERO, BW );
CONVERT_ROUTINE( Z1TO4, G_ZERO, BD );
CONVERT_ROUTINE( Z1TO8, G_ZERO, BQ );
CONVERT_ROUTINE( Z2TO4, G_ZERO, WD );
CONVERT_ROUTINE( Z2TO8, G_ZERO, WQ );
//CONVERT_ROUTINE( Z4TO8, G_ZERO, DQ );

CONVERT_ROUTINE( S1TO2, G_SIGN, BW );
CONVERT_ROUTINE( S1TO4, G_SIGN, BD );
CONVERT_ROUTINE( S1TO8, G_SIGN, BQ );
CONVERT_ROUTINE( S2TO4, G_SIGN, WD );
CONVERT_ROUTINE( S2TO8, G_SIGN, WQ );
//CONVERT_ROUTINE( S4TO8, G_SIGN, DQ );

CONVERT_ROUTINE( C8TO2, G_MOVE, QW );
CONVERT_ROUTINE( C8TO1, G_MOVE, QB );
CONVERT_ROUTINE( C4TO2, G_MOVE, DW );
CONVERT_ROUTINE( C4TO1, G_MOVE, DB );
CONVERT_ROUTINE( C2TO1, G_MOVE, WB );

static opcode_entry ctable_C8TO4[] = {
/************************************/
/*      from    to      eq              verify          gen             reg       fu */
_Un(    ANY,    ANY,    NONE ),         V_NO,           R_MOVELOW,      RG_,      FU_NO,
};

static instruction *cC8TO4( instruction *ins ) { ins->table = ctable_C8TO4; return( ins ); }

static opcode_entry ctable_S4TO8[] = {
/************************************/
/*      from    to      eq              verify          gen             reg       fu */
_Un(    ANY,    ANY,    NONE ),         V_NO,           R_SEX_4TO8,     RG_,      FU_NO,
};

static instruction *cS4TO8( instruction *ins ) { ins->table = ctable_S4TO8; return( ins ); }

static opcode_entry ctable_Z4TO8[] = {
/************************************/
/*      from    to      eq              verify          gen             reg       fu */
_Un(    ANY,    ANY,    NONE ),         V_NO,           R_CLRHI_4,      RG_,      FU_NO,
};

static instruction *cZ4TO8( instruction *ins ) { ins->table = ctable_Z4TO8; return( ins ); }

static convert_rtn ConvertRoutines[] = {
    #define _C_( a )    c##a,
    #include "convert.h"
    #undef _C_
};

static  conv_method         CvtTable[] = {
/*                               from*/
/*U1   I1     U2     I2     U4     I4     U8     I8     CP    PT    FS     FD     FL         to*/
OK,    OK,    C2TO1, C2TO1, C4TO1, C4TO1, C8TO1, C8TO1, C4TO1,C4TO1,U4,    U4,    U4,     /* U1*/
OK,    OK,    C2TO1, C2TO1, C4TO1, C4TO1, C8TO1, C8TO1, C4TO1,C4TO1,I4,    I4,    I4,     /* I1*/
Z1TO2, S1TO2, OK,    OK,    C4TO2, C4TO2, C8TO2, C8TO2, C4TO2,C4TO2,U4,    U4,    U4,     /* U2*/
Z1TO2, S1TO2, OK,    OK,    C4TO2, C4TO2, C8TO2, C8TO2, C4TO2,C4TO2,I4,    I4,    I4,     /* I2*/
Z1TO4, S1TO4, Z2TO4, S2TO4, OK,    OK,    C8TO4, C8TO4, OK,   OK,   FD,    NA,    NA,     /* U4*/
Z1TO4, S1TO4, Z2TO4, S2TO4, OK,    OK,    C8TO4, C8TO4, OK,   OK,   FD,    FDTOI4,NA,     /* I4*/
Z1TO8, S1TO8, Z2TO8, S2TO8, Z4TO8, S4TO8, OK,    OK,    S4TO8,S4TO8,NA,    NA,    NA,     /* U8*/
Z1TO8, S1TO8, Z2TO8, S2TO8, Z4TO8, S4TO8, OK,    OK,    S4TO8,S4TO8,FD,    FDTOI8,NA,     /* I8*/
NA,    NA,    NA,    NA,    OK,    OK,    NA,    NA,    OK,   OK,   NA,    NA,    NA,     /* CP*/
NA,    NA,    NA,    NA,    OK,    OK,    NA,    NA,    OK,   OK,   NA,    NA,    NA,     /* PT*/
I8,    I8,    I8,    I8,    I8,    I8,    NA,    FD,    NA,   NA,   OK,    FDTOS, FDTOS,  /* FS*/
I8,    I8,    I8,    I8,    I8,    I8,    NA,    FI8TOD,NA,   NA,   FSTOD, OK,    OK,     /* FD*/
I8,    I8,    I8,    I8,    I8,    I8,    NA,    FI8TOD,NA,   NA,   FSTOD, OK,    OK,     /* FL*/
};

extern conv_method AskHow( type_class_def fr, type_class_def to )
/****************************************************************
    return the conversion method required to convert from "fr" to "to"
*/
{
    if( to == XX || fr == XX ) {
        return( BAD );
    }
    return( CvtTable[fr + to * XX] );
}

extern bool CvtOk( type_class_def fr, type_class_def to )
/********************************************************
    return true if a conversion from "fr" to "to" can be done
*/
{
    if( fr == XX ) return( FALSE );
    if( to == XX ) return( FALSE );
    if( AskHow( fr, to ) != NA ) return( TRUE );
    return( FALSE );
}

extern instruction *rDOCVT( instruction *ins )
/********************************************/
{
    name        *src;
    name        *dst;
    name        *temp;
    instruction *new_ins;
    conv_method how;

    src = ins->operands[0];
    dst = ins->result;
    if( src->n.name_class != XX && ins->base_type_class == XX ) {
        ins->base_type_class = src->n.name_class;
    }
    ins->head.state = INS_NEEDS_WORK;
    if( src->n.class == N_CONSTANT && src->c.const_type == CONS_ABSOLUTE
     && ins->type_class != XX ) {
        src = TrimConst( src, ins->base_type_class );
        how = OK;
    } else {
        how = AskHow( ins->base_type_class, ins->type_class );
    }
    if( how < NA ) {
        temp = AllocTemp( how );
        new_ins = MakeConvert( src, temp, how, ins->base_type_class );
        ins->operands[0] = temp;
        ins->base_type_class = how;
        new_ins->table = NULL;
        PrefixIns( ins, new_ins );
        UpdateLive( new_ins, ins );
    } else if( how < LST && how > OK ) {
        new_ins = ConvertRoutines[how - OK - 1]( ins );
    } else {
        new_ins = MakeMove( src, dst, ins->type_class );
        ReplIns( ins, new_ins );
        if( how != OK ) {
            _Zoiks( ZOIKS_092 );
        }
    }
    return( new_ins );
}

⌨️ 快捷键说明

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