fixindex.c

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

C
442
字号
/****************************************************************************
*
*                            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:  Reduce memory references to one per instruction.
*
****************************************************************************/


#include "standard.h"
#include "coderep.h"
#include "opcodes.h"

extern  block           *HeadBlock;

extern  bool            FPIsStack(name*);
extern  bool            IndexOkay(instruction*,name*);
extern  bool            RTLeaveOp2(instruction*);
extern  instruction     *MakeMove(name*,name*,type_class_def);
extern  name            *AllocTemp(type_class_def);
extern  name            *ScaleIndex(name*,name*,type_length,type_class_def,type_length,int,i_flags);
extern  void            FPSetStack(name*);
extern  void            FixFPConsts(instruction*);
extern  void            PrefixIns(instruction*,instruction*);
extern  void            SuffixIns(instruction*,instruction*);
extern  type_class_def  FPInsClass(instruction*);

static byte NumTab[LAST_OP-FIRST_OP+1] = {
/*****************************************
    Give the number of operand for each opcode. Anything above this
    is probably a segment override tagging along for the ride.
*/
        0,                                      /* OP_NOP*/
        2,                                      /* OP_ADD*/
        2,                                      /* OP_EXT_ADD*/
        2,                                      /* OP_SUB*/
        2,                                      /* OP_EXT_SUB*/
        2,                                      /* OP_MUL*/
        2,                                      /* OP_EXT_MUL*/
        2,                                      /* OP_DIV*/
        2,                                      /* OP_MOD*/
        2,                                      /* OP_AND*/
        2,                                      /* OP_OR*/
        2,                                      /* OP_XOR*/
        2,                                      /* OP_RSHIFT*/
        2,                                      /* OP_LSHIFT*/
        2,                                      /* OP_POW */
        2,                                      /* OP_P5DIV */
        2,                                      /* OP_ATAN2 */
        2,                                      /* OP_FMOD */
        1,                                      /* OP_NEGATE*/
        1,                                      /* OP_COMPLEMENT*/
        1,                                      /* OP_LOG*/
        1,                                      /* OP_COS*/
        1,                                      /* OP_SIN*/
        1,                                      /* OP_TAN*/
        1,                                      /* OP_SQRT*/
        1,                                      /* OP_FABS*/
        1,                                      /* OP_ACOS */
        1,                                      /* OP_ASIN */
        1,                                      /* OP_ATAN */
        1,                                      /* OP_COSH */
        1,                                      /* OP_EXP */
        1,                                      /* OP_LOG10 */
        1,                                      /* OP_SINH */
        1,                                      /* OP_TANH */
        1,                                      /* OP_PTR_TO_NATIVE */
        1,                                      /* OP_PTR_TO_FOREIGN */
        0,                                      /* OP_SLACK_19 */
        1,                                      /* OP_CONVERT*/
        1,                                      /* OP_LA*/
        1,                                      /* OP_CAREFUL_LA*/
        1,                                      /* OP_ROUND*/
        1,                                      /* OP_MOV*/
        3,                                      /* OP_CALL_INDIRECT*/
        1,                                      /* OP_PUSH*/
        0,                                      /* OP_POP*/
        0,                                      /* OP_PARM_DEF*/
        1,                                      /* OP_SELECT*/
        2,                                      /* OP_BIT_TEST_TRUE*/
        2,                                      /* OP_BIT_TEST_FALSE*/
        2,                                      /* OP_CMP_EQUAL*/
        2,                                      /* OP_CMP_NOT_EQUAL*/
        2,                                      /* OP_CMP_GREATER*/
        2,                                      /* OP_CMP_LESS_EQUAL*/
        2,                                      /* OP_CMP_LESS*/
        2,                                      /* OP_CMP_GREATER_EQUAL*/
        2,                                      /* OP_CALL*/
        2,                                      /* OP_SET_EQUAL*/
        2,                                      /* OP_SET_NOT_EQUAL*/
        2,                                      /* OP_SET_GREATER*/
        2,                                      /* OP_SET_LESS_EQUAL*/
        2,                                      /* OP_SET_LESS*/
        2,                                      /* OP_SET_GREATER_EQUAL*/
        0,                                      /* OP_DEBUG_INFO */
        0,                                      /* OP_CHEAP_NOP */
        1,                                      /* OP_LOAD_UNALIGNED */
        1,                                      /* OP_STORE_UNALIGNED */
        2,                                      /* OP_EXTRACT_LOW */
        2,                                      /* OP_EXTRACT_HIGH */
        2,                                      /* OP_INSERT_LOW */
        2,                                      /* OP_INSERT_HIGH */
        2,                                      /* OP_MASK_LOW */
        2,                                      /* OP_MASK_HIGH */
        2,                                      /* OP_ZAP */
        2,                                      /* OP_ZAP_NOT */
        0,                                      /* OP_STK_ALLOC */
        1,                                      /* OP_VA_START */
        0,0,0,0,0,0,0,0,0,                      /* OP_SLACK_31 .. 39 */
        0                                       /* OP_BLOCK*/
};


extern  int     NumOperands( instruction *ins ) {
/************************************************
    see NumTab
*/

    return( NumTab[ ins->head.opcode ] );
}


extern void     ReplaceOperand( instruction *ins, name *old, name *new ) {
/*************************************************************************
    Replace all occurences of operand/result "old" with "new" in "ins".
*/

    int                 i;

    i = ins->num_operands;
    while( --i >= 0 ) {
        if( ins->operands[ i ] == old ) {
            ins->operands[ i ] = new;
        }
    }
    if( ins->result == old ) {
        ins->result = new;
    }
}


extern  name    *IndexToTemp( instruction * ins, name * index ) {
/****************************************************************
        change
                 OP      foo[x], ...
        into
                 MOV     x => temp
                 OP      foo[temp], ...

*/

    name                *temp;
    instruction         *new_ins;
    name                *new_idx;
    name                *name;
    type_class_def      class;

    name = index->i.index;
    if( name->n.class == N_CONSTANT ) {
        class = WD;
    } else {
        class = name->n.name_class;
    }
    temp = AllocTemp( class );
    new_ins = MakeMove( name, temp, class );
    new_idx = ScaleIndex( temp, index->i.base,
                           index->i.constant, index->n.name_class,
                           index->n.size, index->i.scale,
                           index->i.index_flags );
    ReplaceOperand( ins, index, new_idx );
    PrefixIns( ins, new_ins );
    return( temp );
}


extern  name    *FindIndex( instruction *ins ) {
/***********************************************
    Find an N_INDEXED operand of "ins" that is not OK (Needs index
    to be split out into a temporary)
*/

    name        *index;
    int         i;

    i = 0;
    while( i < ins->num_operands ) {
        index = ins->operands[ i ];
        if( index->n.class == N_INDEXED && !IndexOkay( ins, index ) ) {
            return( index );
        }
        ++ i;
    }
    index = ins->result;
    if( index == NULL ) return( NULL );
    if( index->n.class != N_INDEXED ) return( NULL );
    if( IndexOkay( ins, index ) ) return( NULL );
    return( index );
}

⌨️ 快捷键说明

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