addrfold.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 681 行 · 第 1/2 页
C
681 行
/****************************************************************************
*
* 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 <stdlib.h>
#include "standard.h"
#include "coderep.h"
#include "opcodes.h"
#include "cgdefs.h"
#include "model.h"
#include "addrname.h"
#include "procdef.h"
#include "sysmacro.h"
#include "zoiks.h"
#include "freelist.h"
#include "cfloat.h"
#include "addrfold.h"
extern type_class_def TypeClass(type_def*);
extern void AddrFree(an);
extern instruction *MakeUnary(opcode_defs,name*,name*,type_class_def);
extern name *STempOffset(name*,type_length,type_class_def,type_length);
extern void AddIns(instruction*);
extern name *AllocIndex(name*,name*,type_length,type_class_def);
extern name *ScaleIndex(name*,name*,type_length,type_class_def,type_length,int,i_flags);
extern void FPSetStack(name*);
extern cg_type NamePtrType(name*);
extern name *AllocIntConst(int);
extern name *AllocS32Const(signed_32);
extern name *SAllocMemory(pointer,type_length,cg_class,type_class_def,type_length);
extern name *AllocTemp(type_class_def);
extern name *AllocMemory(pointer,type_length,cg_class,type_class_def);
extern instruction *MakeBinary(opcode_defs,name*,name*,name*,type_class_def);
extern name *TempOffset(name*,type_length,type_class_def);
extern void BGDone(an);
extern void CheckPointer(an );
extern name *LoadTemp(name *,type_class_def);
extern name *LoadAddress(name*,name*,type_def*);
extern void Convert(an ,type_class_def );
extern an NewAddrName(void);
extern bool PointLess(an ,an );
extern void InsToAddr(an );
extern name *MaybeTemp(name *,type_class_def );
extern void MoveAddress(an ,an );
extern i_flags AlignmentToFlags( type_length );
static void LoadTempInt( an addr );
typedef enum {
/* actions which require further actions*/
UNEXPECTED, /* unexpected mode -- two addresses*/
TEMP_L, /* move value of left into temp*/
TEMP_R, /* move value of right into temp*/
#if WORD_SIZE == 2
SHRNK_L, /* convert left from I4 to I2*/
SHRNK_R, /* convert left from I4 to I2*/
#endif
XPAND_L, /* expand left from I2 to I4*/
XPAND_R, /* expand right from I2 to I4*/
#if WORD_SIZE == 2
XP_LC, /* expand left & move constant*/
XP_RC, /* expand right & move constant*/
#endif
/* actions which result in a finished address*/
IL, /* index by left temporary*/
IR, /* index by right temporary*/
ADD_LA, /* add right constant to left address*/
ADD_RA, /* add left constant to right address*/
ADD_LI, /* add right index to left*/
ADD_RI, /* add left index to right*/
ADD_I, /* add integers, creating*/
CODE /* generate normal code*/
} mode_action;
#if WORD_SIZE == 2
#define CL_VALUE CL_VALUE2
#else
#define CL_VALUE CL_VALUE4
#endif
#define ___ UNEXPECTED
#define _HaveMode( action ) ( (action) >= IL )
static mode_action AddTable[][9] = {
/***************************************/
/* left argument*/
#if WORD_SIZE == 2
/* &g+C &g+C[I] &t+C &t+C[I] &X->C TI2+C I2 I4 C2*/
{___, ___, ___, ___, ___, IL, TEMP_L, SHRNK_L,ADD_RA},//&g+C
{___, ___, ___, ___, ___, ADD_RI, ADD_RI, SHRNK_L,ADD_RA},//&g+Ci
{___, ___, ___, ___, ___, IL, TEMP_L, SHRNK_L,ADD_RA},//&t+C
{___, ___, ___, ___, ___, ADD_RI, ADD_RI, SHRNK_L,ADD_RA},//&t+Ci
{___, ___, ___, ___, ___, ADD_RI, ADD_RI, SHRNK_L,ADD_RA},//&X->C
{IR, ADD_LI, IR, ADD_LI, ADD_LI, ADD_I, ADD_I, XPAND_R,ADD_RA},//TI2+C
{TEMP_R, ADD_LI, TEMP_R, ADD_LI, ADD_LI, ADD_I, CODE, XPAND_R,TEMP_R},//I2
{SHRNK_R,SHRNK_R,SHRNK_R,SHRNK_R,SHRNK_R,XPAND_L,XPAND_L,CODE, CODE}, //I4
{ADD_LA, ADD_LA, ADD_LA, ADD_LA, ADD_LA, ADD_LA, TEMP_L, CODE, ADD_LA} //C2
#else
/* &g+C &g+C[I] &t+C &t+C[I] &X->C TI4+C I4 I2 C2*/
{___, ___, ___, ___, ___, IL, TEMP_L, XPAND_L,ADD_RA},//&g+C
{___, ___, ___, ___, ___, ADD_RI, ADD_RI, XPAND_L,ADD_RA},//&g+Ci
{___, ___, ___, ___, ___, IL, TEMP_L, XPAND_L,ADD_RA},//&t+C
{___, ___, ___, ___, ___, ADD_RI, ADD_RI, XPAND_L,ADD_RA},//&t+Ci
{___, ___, ___, ___, ___, ADD_RI, ADD_RI, XPAND_L,ADD_RA},//&X->C
{IR, ADD_LI, IR, ADD_LI, ADD_LI, ADD_I, ADD_I, XPAND_L,ADD_RA},//TI4+C
{TEMP_R, ADD_LI, TEMP_R, ADD_LI, ADD_LI, ADD_I, CODE, CODE, TEMP_R},//I4
{XPAND_R,XPAND_R,XPAND_R,XPAND_R,XPAND_R,XPAND_R,CODE, CODE, CODE}, //I2
{ADD_LA, ADD_LA, ADD_LA, ADD_LA, ADD_LA, ADD_LA, TEMP_L, CODE, ADD_LA} //C2
#endif
};
/*
* This is a kludge. I was too lazy to rearrange row and column in the
* tables so I just used this table to map CL constants onto the tables
*/
static byte Idx[] = {
0, /* CL_ADDR_GLOBAL */
2, /* CL_ADDR_TEMP */
4, /* CL_POINTER */
#if WORD_SIZE == 2
6, /* CL_VALUE2 */
7, /* CL_VALUE4 */
#else
7, /* CL_VALUE2 */
6, /* CL_VALUE4 */
#endif
8, /* CL_CONS2 */
#if WORD_SIZE == 2
0xFF, /* CL_CONS4 */
#else
8, /* CL_CONS4 */
#endif
1, /* CL_GLOBAL_INDEX */
3, /* CL_TEMP_INDEX */
5 /* CL_TEMP_OFFSET */
};
extern name *Points( an addr, type_def *tipe ) {
/**************************************************/
type_class_def class;
type_length size;
name *result;
i_flags flags;
CheckPointer( addr );
if( addr->format != NF_ADDR && addr->format != NF_CONS ) {
_Zoiks( ZOIKS_024 );
}
class = TypeClass( tipe );
size = tipe->length;
if( addr->base != NULL ) {
flags = X_FAKE_BASE;
} else {
flags = EMPTY;
}
if( addr->flags & VOLATILE ) {
flags |= X_VOLATILE;
}
if( addr->flags & CONSTANT ) {
flags |= X_CONSTANT;
}
if( addr->alignment != 0 ) {
flags |= AlignmentToFlags( addr->alignment );
}
switch( addr->class ) {
case CL_ADDR_GLOBAL:
if( addr->u.name->v.offset == addr->offset
&& addr->u.name->n.name_class == class
&& addr->u.name->n.size == size ) {
result = addr->u.name;
} else {
result = SAllocMemory( addr->u.name->v.symbol,
addr->offset,
addr->u.name->m.memory_type,
class, size );
}
if( addr->alignment != 0 ) {
// NOTE: This means all references to a memory operand must
// have the same alignment in a function (be conservative)
result->m.alignment = addr->alignment;
}
break;
case CL_ADDR_TEMP:
if( addr->u.name->v.offset == addr->offset
&& addr->u.name->n.name_class == class
&& addr->u.name->n.size == size ) {
result = addr->u.name;
} else {
result = STempOffset( addr->u.name, addr->offset, class, size );
}
break;
case CL_POINTER:
result = ScaleIndex( addr->index, addr->base, addr->offset, class,
size, 0, flags );
break;
case CL_GLOBAL_INDEX:
case CL_TEMP_INDEX:
result = ScaleIndex( addr->index, addr->u.name, addr->offset,
class, size, 0, flags & ~X_FAKE_BASE );
break;
case CL_TEMP_OFFSET:
result = ScaleIndex( addr->u.name, addr->base, addr->offset, class,
size, 0, flags );
break;
case CL_CONS2:
#if WORD_SIZE != 2
case CL_CONS4:
#endif
addr->u.name = AllocIntConst( addr->offset );
addr->class = CL_VALUE;
LoadTempInt( addr );
result = ScaleIndex( addr->u.name, addr->base, 0,
class, size, 0, flags );
break;
default:
LoadTempInt( addr );
result = ScaleIndex( addr->u.name, addr->base, 0,
class, size, 0, flags );
break;
}
if( addr->flags & VOLATILE ) {
if( result->n.class != N_INDEXED ) {
result->v.usage |= ( VAR_VOLATILE | USE_MEMORY | NEEDS_MEMORY );
}
}
if( addr->flags & CONSTANT ) {
if( result->n.class != N_INDEXED ) {
result->v.usage |= VAR_CONSTANT;
}
}
return( result );
}
extern an AddrName( name *op, type_def *tipe ) {
/******************************************************/
an addr;
addr = NewAddrName();
addr->tipe = tipe;
addr->u.name = op;
if( op->n.class == N_CONSTANT && op->c.const_type == CONS_ABSOLUTE ) {
addr->format = NF_CONS;
if( CFIsI16( op->c.value ) && tipe->length <= WORD_SIZE ) {
addr->class = CL_CONS2;
addr->offset = CFCnvF16( op->c.value );
} else {
addr->class = CL_VALUE4;
addr->offset = 0;
#if WORD_SIZE >= 4
if( CFIsI32( op->c.value ) ) {
addr->class = CL_CONS4;
addr->offset = CFCnvF32( op->c.value );
}
#endif
}
} else {
if( tipe->attr & TYPE_POINTER ) {
addr->u.name = op;
addr->format = NF_NAME;
} else if( tipe->length == WORD_SIZE ) {
addr->u.name = op;
addr->format = NF_ADDR;
if( op->n.class == N_TEMP ) {
addr->class = CL_TEMP_OFFSET;
} else {
addr->class = CL_VALUE;
}
#if WORD_SIZE == 2
} else if( tipe->length == 4 ) {
addr->u.name = op;
addr->format = NF_ADDR;
addr->class = CL_VALUE4;
#endif
} else {
addr->format = NF_NAME;
}
}
return( addr );
}
static void FixIndexClass( an addr ) {
/***********************************/
if( addr->u.name->n.class == N_TEMP ) {
addr->class = CL_TEMP_INDEX;
} else {
addr->class = CL_GLOBAL_INDEX;
}
}
static void LoadTempInt( an addr ) {
/**************************************/
addr->u.name = LoadTemp( addr->u.name, TypeClass( addr->tipe ) );
addr->index = NULL;
addr->offset = 0;
if( addr->class == CL_VALUE ) {
addr->class = CL_TEMP_OFFSET;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?