i86conv.c

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

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


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

extern  name    *       AllocTemp(type_class_def);
extern  instruction*    MakeUnary(opcode_defs,name*,name*,type_class_def);
extern  void            MoveSegOp(instruction*,instruction*,int);
extern  void            PrefixIns(instruction*,instruction*);
extern  instruction*    MakeMove(name*,name*,type_class_def);
extern  void            DupSeg(instruction*,instruction*);
extern  void            ReplIns(instruction*,instruction*);
extern  bool            IsTrickyPointerConv( instruction *ins );

extern    int   RoutineNum;


static  opcode_entry    C2to1[] = {
/*********************************/
/*    from  to    eq       verify        gen             reg fu*/
{_Un( R,    ANY,  NONE ),  V_NO,       R_MOVELOW,        RG_TWOBYTE,FU_NO},
{_Un( R,    ANY,  NONE ),  V_NO,       R_MOVOP1TEMP,     RG_,    FU_NO},
{_Un( U,    ANY,  NONE ),  V_CONSTTEMP, G_UNKNOWN,       RG_,    FU_NO},
{_Un( C,    ANY,  NONE ),  V_OP1RELOC, R_MOVOP1TEMP,     RG_,    FU_NO},
{_Un( ANY,  ANY,  NONE ),  V_NO,       R_MOVELOW,        RG_,    FU_NO},
};


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


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


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


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


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


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


static  opcode_entry    SExt1[] = {
/*********************************/
/*    from  to    eq          verify          gen             reg fu*/
{_Un( R,    R,    NONE ),     V_NO,           G_SIGNEX,       RG_BYTE_EXT,FU_ALU1},
{_Un( ANY,  ANY,  NONE ),     V_NO,           R_OP1RESREG,    RG_BYTE_EXT,FU_NO},
};


static  opcode_entry    SExt2[] = {
/*********************************/
/*    from  to    eq          verify          gen             reg fu*/
{_Un( R,    R,    NONE ),     V_NO,           G_SIGNEX,       RG_WORD_EXT,FU_ALU1},
{_Un( ANY,  ANY,  NONE ),     V_NO,           R_OP1RESREG,    RG_WORD_EXT,FU_NO},
};

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


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


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

static opcode_entry     *CvtAddr[] = {
        C2to1,
        C4to1,
        C4to2,
        C8to4,
        Ext1,
        Ext2,
        Ext4,
        SExt1,
        SExt2,
        SExt4,
        ExtPT
        };

static  rt_class         CvtTable[] = {
/*                               from*/
/*U1    I1     U2     I2     U4     I4     U8     I8     CP     PT     FS     FD    FL       to*/
OK,    OK,    C2TO1, C2TO1, C4TO1, C4TO1, C4TO1, C4TO1, CU4,   CU4,   CU4,   CU4,  CU4,     /* U1*/
OK,    OK,    C2TO1, C2TO1, C4TO1, C4TO1, C4TO1, C4TO1, CU4,   CU4,   CI4,   CI4,  CI4,     /* I1*/
EXT1,  S_EXT1,OK,    OK,    C4TO2, C4TO2, C4TO2, C4TO2, CU4,   CU4,   CU4,   CU4,  CU4,     /* U2*/
EXT1,  S_EXT1,OK,    OK,    C4TO2, C4TO2, C4TO2, C4TO2, CU4,   CU4,   CI4,   CI4,  CI4,     /* I2*/
CU2,   CI2,   EXT2,  S_EXT2,OK,    OK,    C8TO4, C8TO4, OK,    OK,    C_S_U, C_D_U,C_D_U,   /* U4*/
CU2,   CI2,   EXT2,  S_EXT2,OK,    OK,    C8TO4, C8TO4, OK,    OK,    C_S_4, C_D_4,C_D_4,   /* I4*/
CU4,   CI4,   CU4,   CI4,   EXT4,  S_EXT4,OK,    OK,    EXT4,  EXT4,  C_S_U8,C_D_U8,C_D_U8, /* U8*/
CU4,   CI4,   CU4,   CI4,   EXT4,  S_EXT4,OK,    OK,    EXT4,  EXT4,  C_S_I8,C_D_I8,C_D_I8, /* I8*/
CU4,   CI4,   EXT_PT,CI4,   OK,    OK,    OK,    OK,    OK,    OK,    BAD,   BAD,  BAD,     /* CP*/
CU4,   CI4,   EXT_PT,CI4,   OK,    OK,    OK,    OK,    OK,    OK,    BAD,   BAD,  BAD,     /* PT*/
CU4,   CI4,   CU4,   CI4,   C_U4_S,C_I4_S,C_U8_S,C_I8_S,BAD,   BAD,   OK,    C_D_S,C_D_S,   /* FS*/
CU4,   CI4,   CU4,   CI4,   C_U4_D,C_I4_D,C_U8_D,C_I8_D,BAD,   BAD,   C_S_D, OK,   OK,      /* FD*/
CU4,   CI4,   CU4,   CI4,   C_U4_D,C_I4_D,C_U8_D,C_I8_D,BAD,   BAD,   C_S_D, OK,   OK,      /* FL*/
};

static  rt_class FPCvtTable[] = {
/*                               from*/
/*U1    I1     U2     I2     U4     I4     U8     I8     CP     PT     FS     FD    FL       to*/
OK,    OK,    C2TO1, C2TO1, C4TO1, C4TO1, C4TO1, C4TO1, CU4,   CU4,   CI2,   CI2,   CI2,     /* U1*/
OK,    OK,    C2TO1, C2TO1, C4TO1, C4TO1, C4TO1, C4TO1, CU4,   CU4,   CI2,   CI2,   CI2,     /* I1*/
EXT1,  S_EXT1,OK,    OK,    C4TO2, C4TO2, C4TO2, C4TO2, CU4,   CU4,   CI4,   CI4,   CI4,     /* U2*/
EXT1,  S_EXT1,OK,    OK,    C4TO2, C4TO2, C4TO2, C4TO2, CU4,   CU4,   FPOK,  FPOK,  FPOK,    /* I2*/
CU2,   CI2,   EXT2,  S_EXT2,OK,    OK,    C8TO4, C8TO4, OK,    OK,    FPOK,  FPOK,  FPOK,    /* U4*/
CU2,   CI2,   EXT2,  S_EXT2,OK,    OK,    C8TO4, C8TO4, OK,    OK,    FPOK,  FPOK,  FPOK,    /* I4*/
CU4,   CI4,   CU4,   CI4,   EXT4,  S_EXT4,OK,    OK,    EXT4,  EXT4,  C7S_U8,C7D_U8,C7D_U8,  /* U8*/
CU4,   CI4,   CU4,   CI4,   EXT4,  S_EXT4,OK,    OK,    EXT4,  EXT4,  FPOK,  FPOK,  FPOK,    /* I8*/
CU4,   CI4,   EXT_PT,CI4,   OK,    OK,    OK,    OK,    OK,    OK,    BAD,   BAD,   BAD,     /* CP*/
CU4,   CI4,   EXT_PT,CI4,   OK,    OK,    OK,    OK,    OK,    OK,    BAD,   BAD,   PT,      /* PT*/
CI2,   CI2,   CI4,   FPOK,  FPOK,  FPOK,  C7U8_S,FPOK,  BAD,   BAD,   FPOK,  FPOK,  FPOK,    /* FS*/
CI2,   CI2,   CI4,   FPOK,  FPOK,  FPOK,  C7U8_D,FPOK,  BAD,   BAD,   FPOK,  FPOK,  FPOK,    /* FD*/
CI2,   CI2,   CI4,   FPOK,  FPOK,  FPOK,  C7U8_D,FPOK,  BAD,   BAD,   FPOK,  FPOK,  FPOK,    /* FL*/
};

extern  rt_class        AskHow( type_class_def fr, type_class_def to ) {
/**********************************************************************/

    if( _FPULevel( FPU_87 ) ) {
        return( FPCvtTable[  fr + to * XX  ] );
    } else {
        return( CvtTable[  fr + to * XX  ] );
    }
}


extern  bool    CvtOk( type_class_def fr, type_class_def to ) {
/*************************************************************/

    if( fr == XX ) return( FALSE );
    if( to == XX ) return( FALSE );
    if( AskHow( fr, to ) != BAD ) return( TRUE );
    return( FALSE );
}


extern  instruction     *rDOCVT( instruction *ins ) {
/**************************************************/

    name        *src;
    name        *dst;
    name        *name;
    instruction *new_ins;
    rt_class    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
      && !IsTrickyPointerConv( ins ) ) {
        how = OK;
    } else {
        how = AskHow( ins->base_type_class, ins->type_class );
    }
    if( how < OK ) {
        name = AllocTemp( how );
        new_ins = MakeUnary( ins->head.opcode, src, name, how );
        new_ins->base_type_class = ins->base_type_class;
        new_ins->type_class = how;
        ins->base_type_class = how;
        ins->table = NULL;
        ins->operands[ 0 ] = name;
        MoveSegOp(ins,new_ins,0);
        PrefixIns( ins, new_ins );
    } else if( how == OK ) {
        new_ins = MakeMove( src, dst, ins->type_class );
        DupSeg(ins,new_ins);
        ReplIns( ins, new_ins );
    } else if( how == FPOK ) {
        ins->head.opcode = OP_MOV;
        ins->table = NULL;
        ins->u.gen_table = NULL;
        new_ins = ins;
        if( !_IsFloating( ins->type_class ) ) {
            ins->type_class = ins->base_type_class;
        }
    } else if( how <= EXT_PT ) {
        ins->table = CvtAddr[  how - ( OK + 1 )  ];
        new_ins = ins;
    } else {
        ins->table = CRtn;
        RoutineNum = how - BEG_RTNS;
        new_ins = ins;
    }
    return( new_ins );
}

⌨️ 快捷键说明

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