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 + -
显示快捷键?