s37table.c

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

C
818
字号
/****************************************************************************
*
*                            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 "vergen.h"
#include "pattern.h"
#include "funits.h"
#include "regset.h"
#include "model.h"
#include "tables.h"

#include "s37table.def"

/**************************************************************************/
/**************************************************************************/
/*                             ARITH                                      */
/**************************************************************************/
/**************************************************************************/

#define _BinCommutes( type ) \
_Bin(   R,    ANY,  R,    EQ_R1 ), V_NO,        G_UNKNOWN,      RG_##type,FU_NO,\
_Bin(   R|M|C,R,    R,    EQ_R2 ), V_NO,        R_SWAPOPS,      RG_##type,FU_NO,\
_Bin(   R,    ANY,  ANY,  NONE ),  V_SWAP_GOOD, R_SWAPOPS,      RG_##type,FU_NO,\
_Bin(   M,    C,    R|M,  NONE ),  V_NO,        R_SWAPOPS,      RG_##type,FU_NO,\
_Bin(   R|M|C,R|M|C,R|M,  NONE ),  V_NO,        R_USEREGISTER,  RG_##type,FU_NO,\
_Bin(   ANY,  ANY,  ANY,  NONE ),  V_NO,        G_UNKNOWN,      RG_##type##_NEED,FU_NO

#define _BinNoCommute( type ) \
_Bin(   R,    C,    R,    EQ_R1 ), V_NO,        R_LOADOP2,      RG_##type,FU_NO,\
_Bin(   R|M|C,R|M|C,R|M,  NONE ),  V_NO,        R_USEREGISTER,  RG_##type,FU_NO,\
_Bin(   ANY,  ANY,  ANY,  NONE ),  V_NO,        G_UNKNOWN,      RG_##type##_NEED,FU_NO

#define _GenBinary( op, type, cc ) \
_Bin##cc( R,  R,    R,    EQ_R1),  V_NO,        G_##op##R,       RG_##type,FU_NO,\
_Bin##cc( R,  M|C,  R,    EQ_R1),  V_NO,        G_##op,          RG_##type,FU_NO

#define _GenHalf( op ) \
_BinCC( R,    M,    R,    EQ_R1),  V_OP2I2,     G_##op##H,       RG_WORDOP1,FU_NO,\
_BinCC( R,    C,    R,    EQ_R1),  V_OP2I2CON,  G_##op##H,       RG_WORD,FU_NO

#define _MoveOp1IfOp2Zero \
_Bin(   ANY,  C,    ANY,  NONE),   V_OP2ZERO,   R_MAKEMOVE,      RG_,FU_NO

#define _MoveOp1IfOp2One \
_Bin(   ANY,  C,    ANY,  NONE),   V_OP2ONE,    R_MAKEMOVE,      RG_,FU_NO

#define _MoveZeroIfOp2Zero \
_Bin(   ANY,  C,    ANY,  NONE),   V_OP2ZERO,   R_MOVOP2,        RG_,FU_NO

#define _NegIfOp1Zero \
_Bin(   C,    ANY,  ANY,  NONE),   V_OP1ZERO,   R_MAKENEG,       RG_,FU_NO

#define _SubIfOp2Neg \
_Bin(   ANY,  C,    ANY,  NONE),   V_OP2NEG,    R_MAKESUB,       RG_,FU_NO

#define _AddIfOp2Neg \
_Bin(   ANY,  C,    ANY,  NONE),   V_OP2NEG,    R_MAKEADD,       RG_,FU_NO

/**************************************************************************/
/*                             ADD                                        */
/**************************************************************************/

#define _OptimizeAdd \
    _SubIfOp2Neg,\
    _MoveOp1IfOp2Zero

#define _AddUnsigned \
    _OptimizeAdd,\
    _GenBinary( AL, WORD, CC ),\
    _BinCommutes( WORD )

static  opcode_entry    AddPT[] = {
_Bin(   R,    C,    R,    NONE  ), V_LA2,      G_LA2,        RG_WORD,FU_NO,
_AddUnsigned
};

static  opcode_entry    AddU4[] = {
/************************/
_AddUnsigned
};

static  opcode_entry    AddI4[] = {
/************************/
_OptimizeAdd,
_Bin(   ANY,  M|U,  ANY,  NONE ),  V_OP2I2,        R_PREPI4I2, RG_,FU_NO,
_Bin(   ANY,  C,    ANY,  NONE ),  V_OP2I2CON,     R_PREPI4I2, RG_,FU_NO,
_GenBinary( A, WORD, CC ),
_BinCommutes( WORD )
};

extern  opcode_entry    Add4I2G[] = {
/************************/
_BinPP( R,    M,    R,    EQ_R1),  V_NO,           G_AH,         RG_WORDRES,FU_NO,
_BinPP( R,    C,    R,    EQ_R1),  V_NO,           G_AH,         RG_WORDRES,FU_NO,
_Bin(   R|M|C,M|C,  R|M,  NONE ),  V_NO,           R_USEREGISTER,RG_WORDRES,FU_NO,
_Bin(   ANY,  ANY,  ANY,  NONE ),  V_NO,           G_UNKNOWN,    RG_WORDRES_NEED,FU_NO
};

static  opcode_entry    AddFS[] = {
/************************/
_OptimizeAdd,
_GenBinary( AE, SINGLE, CC ),
_BinCommutes( SINGLE )
};

static  opcode_entry    AddFD[] = {
/************************/
_OptimizeAdd,
_GenBinary( AD, DOUBLE, CC ),
_BinCommutes( DOUBLE )
};

/**************************************************************************/
/*                             SUB                                        */
/**************************************************************************/

#define _OptimizeSub \
    _AddIfOp2Neg,\
    _MoveOp1IfOp2Zero,\
    _NegIfOp1Zero

static  opcode_entry    SubI4[] = {
/************************/
_OptimizeSub,
_BinPP( R,    C,    R,    EQ_R1 ),  V_OP2ONE,      G_BCTR,       RG_WORD,FU_NO,
_Bin(   ANY,  M|U,  ANY,  NONE ),  V_OP2I2,        R_PREPI4I2, RG_,FU_NO,
_Bin(   ANY,  C,    ANY,  NONE ),  V_OP2I2CON,     R_PREPI4I2, RG_,FU_NO,
_GenBinary( S, WORD, CC ),
_BinNoCommute( WORD )
};

extern  opcode_entry    Sub4I2G[] = {
/************************/
_BinPP( R,    M,    R,    EQ_R1),  V_NO,           G_SH,         RG_WORDRES,FU_NO,
_BinPP( R,    C,    R,    EQ_R1),  V_NO,           G_SH,         RG_WORDRES,FU_NO,
_Bin(   R|M|C,M|C,  R|M,  NONE ),  V_NO,           R_USEREGISTER,RG_WORDRES,FU_NO,
_Bin(   ANY,  ANY,  ANY,  NONE ),  V_NO,           G_UNKNOWN,    RG_WORDRES_NEED,FU_NO
};

static  opcode_entry    SubU4[] = {
/************************/
_OptimizeSub,
_BinPP( R,    C,    R,    EQ_R1 ),  V_OP2ONE,      G_BCTR,       RG_WORD,FU_NO,
_GenBinary( SL, WORD, CC ),
_BinNoCommute( WORD )
};

static  opcode_entry    SubFS[] = {
/************************/
_OptimizeSub,
_GenBinary( SE, SINGLE, CC ),
_BinNoCommute( SINGLE )
};

static  opcode_entry    SubFD[] = {
/************************/
_OptimizeSub,
_GenBinary( SD, DOUBLE, CC ),
_BinNoCommute( DOUBLE )
};

/**************************************************************************/
/*                             MUL                                        */
/**************************************************************************/

#define _OptimizeMul \
    _MoveOp1IfOp2One,\
    _MoveZeroIfOp2Zero

static  opcode_entry    Mul4[] = {
/************************/
/*       op1   op2   res   eq      verify          gen           reg*/
_OptimizeMul,
_Bin(   ANY,  M|U,  ANY,  NONE ),  V_OP2I2,        R_PREPI4I2, RG_,FU_NO,
_Bin(   ANY,  C,    ANY,  NONE ),  V_OP2I2CON,     R_PREPI4I2, RG_,FU_NO,
_Bin(   ANY,  ANY,  ANY,  NONE ),  V_NO,           R_PREPMUL,    RG_,FU_NO
};

extern opcode_entry    Mul4I2G[] = {
/************************/
/*       op1   op2   res   eq      verify          gen           reg*/
_BinPP( R,    M,    R,    EQ_R1),  V_NO,           G_MH,         RG_WORDRES,FU_NO,
_BinPP( R,    C,    R,    EQ_R1),  V_NO,           G_MH,         RG_WORDRES,FU_NO,
_Bin(   R|M|C,M|C,  R|M,  NONE ),  V_NO,           R_USEREGISTER,RG_WORDRES,FU_NO,
_Bin(   ANY,  ANY,  ANY,  NONE ),  V_NO,           G_UNKNOWN,    RG_WORDRES_NEED,FU_NO
};

opcode_entry    Mul4G[] = {
/************************/
/*       op1   op2   res   eq      verify          gen           reg*/
_OptimizeMul,
_BinPP( R,    R,    R,    NONE ),  V_MULPAIR,      G_MR,         RG_MUL,FU_NO,
_BinPP( R,    M,    R,    NONE ),  V_MULPAIR,      G_M,          RG_MUL,FU_NO,
_Bin(   R,    C,    R,    NONE ),  V_MULPAIR,      R_LOADOP2,    RG_MUL,FU_NO,
_Bin(   ANY,  ANY,  ANY,  NONE ),  V_NO,           G_UNKNOWN,    RG_MUL_NEED,FU_NO
};

static  opcode_entry    MulFS[] = {
/************************/
/*       op1   op2   res   eq      verify          gen           reg*/
_OptimizeMul,
_GenBinary( ME, SINGLE, PP ),
_BinCommutes( SINGLE )
};

static  opcode_entry    MulFD[] = {
/************************/
/*       op1   op2   res   eq      verify          gen           reg*/
_OptimizeMul,
_GenBinary( MD, DOUBLE, PP ),
_BinCommutes( DOUBLE )
};


/**************************************************************************/
/*                             MOD/DIV                                    */
/**************************************************************************/

static  opcode_entry    Mod4[] = {
/************************/
/*       op1   op2   res   eq      verify          gen           reg*/
_Bin(   ANY,  ANY,  ANY,  NONE ),  V_NO,           R_PREPMOD,    RG_,FU_NO
};

static  opcode_entry    Div4[] = {
/************************/
/*       op1   op2   res   eq      verify          gen           reg*/
_MoveOp1IfOp2One,
_Bin(   ANY,  ANY,  ANY,  NONE ),  V_NO,           R_PREPDIV,    RG_,FU_NO
};

#define _DivMod4G \
_BinPP( R,    R,    R,    EQ_R1 ), V_NO,           G_DR,         RG_DIV,FU_NO,\
_BinPP( R,    M,    R,    EQ_R1 ), V_NO,           G_D,          RG_DIV,FU_NO,\
_Bin(   R,    C,    R,    EQ_R1 ), V_NO,           R_LOADOP2,    RG_DIV,FU_NO,\
_Bin(   ANY,  ANY,  ANY,  NONE ),  V_NO,           G_UNKNOWN,    RG_DIV_NEED,FU_NO

opcode_entry    Div4G[] = {
/************************/
/*       op1   op2   res   eq      verify          gen           reg*/
_Bin(   R,    C,    R,    EQ_R1 ), V_OP2POW2,      G_DIVPOW2,    RG_DIV,FU_NO,\
_DivMod4G,
};

⌨️ 快捷键说明

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