rscver.c

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

C
284
字号
/****************************************************************************
*
*                            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:  Instruction verification routines for RISC architectures.
*
****************************************************************************/


#include <assert.h>
#include <stdlib.h>
#include "standard.h"
#include "coderep.h"
#include "opcodes.h"
#include "vergen.h"
#include "model.h"
#include "feprotos.h"

extern  type_length     FlagsToAlignment( i_flags );

extern  bool    OtherVerify( vertype, instruction *, name *, name *, name * );

extern  type_length     TypeClassSize[];
extern  type_class_def  Unsigned[];

static  bool    ByteConst( name *operand )
/****************************************/
{
    if( operand->n.class == N_CONSTANT ) {
        if( operand->c.const_type == CONS_ABSOLUTE ) {
            if( operand->c.int_value_2 == 0 ) {
                return( operand->c.int_value >= 0 &&
                        operand->c.int_value <= 255 );
            }
        }
    }
    return( FALSE );
}

static  bool    HalfWordConst( name *operand )
/********************************************/
{
    if( operand->n.class == N_CONSTANT ) {
        if( operand->c.const_type == CONS_ABSOLUTE ) {
            if( operand->c.int_value_2 == 0 ) {
                return( operand->c.int_value >= -32768 &&
                            operand->c.int_value <= 32767 );
            } else {
                return( operand->c.int_value_2 == -1 &&
                    operand->c.int_value <= 0 &&
                    operand->c.int_value >= -32768 );
            }
        }
    }
    return( FALSE );
}

static  bool    UHalfWordConst( name *operand )
/*********************************************/
{
    if( operand->n.class == N_CONSTANT ) {
        if( operand->c.const_type == CONS_ABSOLUTE ) {
            if( operand->c.int_value_2 == 0 ) {
                return( operand->c.int_value >= 0 &&
                            operand->c.int_value <= 0xffff );
            }
        }
    }
    return( FALSE );
}

static  bool    Is64BitConst( name *operand )
/*******************************************/
{
    // Return TRUE if constant is not a 32-bit (canonical) const
    // A canonical 64-bit constant is one whose bits 63:32 == bit 31
    if( operand->c.const_type == CONS_ABSOLUTE ) {
        if( operand->c.int_value_2 != (operand->c.int_value >> 31) ) {
            return( TRUE );
        }
    }
    return( FALSE );
}

static  bool    Symmetric( opcode_defs opcode )
/*********************************************/
{
    switch( opcode ) {
    case OP_ADD:
    case OP_EXT_ADD:
    case OP_MUL:
    case OP_EXT_MUL:
    case OP_AND:
    case OP_OR:
    case OP_XOR:
        return( TRUE );
    }
    return( FALSE );
}

static  type_class_def  InsTypeClass( instruction *ins )
/******************************************************/
{
    if( ins->head.opcode == OP_CONVERT ) {
        return( ins->base_type_class );
    }
    return( ins->type_class );
}

static  bool    Aligned( name *op, type_length align, type_class_def tipe )
/*************************************************************************/
{
    type_length         natural;
    type_length         actual;

    assert( align <= 8 );
    assert( op->n.class == N_TEMP || op->n.class == N_MEMORY || op->n.class == N_INDEXED );
    if( tipe == XX ) {
        natural = 1;    // FIXME - should be largest element of this structure
    } else {
        natural = TypeClassSize[ tipe ];
    }
    if( natural == 2 ) {
        if( _IsntTargetModel( ALIGNED_SHORT ) ) {
            return( FALSE );
        }
    }
    switch( op->n.class ) {
    case N_MEMORY:
        if( op->m.alignment != 0 ) {
            return( align <= op->m.alignment );
        }
        // Note: this assumes we always put global elements on 8-byte
        // boundaries
        // correction - front end only puts globals on 4-byte boundaries
        if( align == 8 ) return( FALSE );
        /* fall through */
    case N_TEMP:
        // Note: this assumes we are not packing elements of size < 8 into
        // 8-byte chunks of the stack - we may do this in the future
        return( ( op->v.offset % align ) == 0 );
    case N_INDEXED:
        actual = natural;
        if( HasAlignment( op ) ) {
            actual = FlagsToAlignment( op->i.index_flags );
        }
        if( ( op->i.constant % 8 ) != 0 ) {
            actual = min( actual, op->i.constant & 0x07 );
        }
        return( align <= actual );
    }
    return( FALSE );
}

extern  bool    DoVerify( vertype kind, instruction *ins )
/********************************************************/
{
    name                *op;

    switch( kind ) {
    case V_BYTECONST2:
        return( ByteConst( ins->operands[ 1 ] ) );
    case V_BYTECONST1:
        return( ByteConst( ins->operands[ 0 ] ) );
    case V_SYMMETRIC:
        return( Symmetric( ins->head.opcode ) );
    case V_OP1HIGHADDR:
        return( ( ins->operands[ 0 ]->n.class == N_CONSTANT ) &&
                ( ins->operands[ 0 ]->c.const_type == CONS_HIGH_ADDR ) );
    case V_UHALFWORDCONST2:
        return( UHalfWordConst( ins->operands[ 1 ] ) );
    case V_UHALFWORDCONST1:
        return( UHalfWordConst( ins->operands[ 0 ] ) );
    case V_HALFWORDCONST2:
#if _TARGET & _TARG_AXP
        if( ins->type_class == Unsigned[ ins->type_class ] &&
            ( ins->operands[ 1 ]->c.int_value & 0x8000 ) &&
            TypeClassSize[ ins->type_class ] >= 4 ) return( FALSE );
#endif
        return( HalfWordConst( ins->operands[ 1 ] ) );
    case V_HALFWORDCONST1:
#if _TARGET & _TARG_AXP
        if( ins->type_class == Unsigned[ ins->type_class ] &&
            ( ins->operands[ 0 ]->c.int_value & 0x8000 ) &&
            TypeClassSize[ ins->type_class ] >= 4 ) return( FALSE );
#endif
        return( HalfWordConst( ins->operands[ 0 ] ) );
    case V_AXPBRANCH:   // FIXME: appears to be unused!
        op = ins->operands[ 1 ];
        return( ins->result == NULL && op->n.class == N_CONSTANT &&
                op->c.const_type == CONS_ABSOLUTE && op->c.int_value == 0 );
    case V_MIPSBRANCH:
        return( ins->result == NULL && (ins->head.opcode == OP_CMP_EQUAL
                || ins->head.opcode == OP_CMP_NOT_EQUAL) );
    case V_RESNOTNULL:
        return( ins->result != NULL );
    case V_RESNULL:
        return( ins->result == NULL );
    case V_WORD_OR_QUAD:
        return( TypeClassSize[ ins->type_class ] == 4 ||
                    TypeClassSize[ ins->type_class ] == 8 );
    case V_FLOAT:
        return( _IsFloating( ins->type_class ) );
    case V_REG_SIZE:
        assert( ins->type_class == XX );
        // FIXME: Alignment of structs not guaranteed to be equal to size
        switch( ins->operands[ 0 ]->n.size ) {
        case 1:
        case 2:
        case 4:
        case 8:
            return( TRUE );
        }
        return( FALSE );
    case V_BASE_8:
        switch( ins->base_type_class ) {
        case I8:
        case U8:
            return( TRUE );
        }
        return( FALSE );
    case V_BASE_4:
        switch( ins->base_type_class ) {
        case I4:
        case U4:
        case CP:
        case PT:
            return( TRUE );
        }
        return( FALSE );
    case V_UNSIGNED:
        return( Unsigned[ ins->type_class ] == ins->type_class );
    case V_OP1_AL2:
        return( Aligned( ins->operands[ 0 ], 2, InsTypeClass( ins ) ) );
    case V_OP1_AL4:
        return( Aligned( ins->operands[ 0 ], 4, InsTypeClass( ins ) ) );
    case V_OP1_AL8:
        return( Aligned( ins->operands[ 0 ], 8, InsTypeClass( ins ) ) );
    case V_RES_AL2:
        return( Aligned( ins->result, 2, ins->type_class ) );
    case V_RES_AL4:
        return( Aligned( ins->result, 4, ins->type_class ) );
    case V_RES_AL8:
        return( Aligned( ins->result, 8, ins->type_class ) );
    case V_OP1_RES_AL8:
        return( Aligned( ins->operands[ 0 ], 8, InsTypeClass( ins ) ) &&
                Aligned( ins->result, 8, InsTypeClass( ins ) ) );
    case V_OP1_RES_AL4:
        return( Aligned( ins->operands[ 0 ], 4, InsTypeClass( ins ) ) &&
                Aligned( ins->result, 4, InsTypeClass( ins ) ) );
    case V_RES_TEMP:
        return( ins->result->n.class == N_TEMP && ins->result->t.alias == NULL );
    case V_RESCONSTTEMP:
        return( _ConstTemp( ins->result ) );
    case V_OP164BITCONST:
        assert( ins->operands[ 0 ]->n.class == N_CONSTANT );
        return( Is64BitConst( ins->operands[ 0 ] ) );
    default:
        return( OtherVerify( kind, ins, ins->operands[ 0 ], ins->operands[ 1 ], ins->result ) );
    }
}

⌨️ 快捷键说明

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