386rgtbl.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,144 行 · 第 1/3 页
C
1,144 行
&QuadReg, /* I8*/
&FarPointerRegs, /* CP*/
&FarPointerRegs, /* PT*/
&DoubleParmRegs, /* FS*/
&QuadReg, /* FD*/
&Empty, /* FL*/
&Empty }; /* XX*/
static reg_list *ParmSets8087[] = {
/**************************************
define the set of register that a parameter of a given class could use
when generating 8087 code
*/
&ByteRegs, /* U1*/
&ByteRegs, /* I1*/
&WordRegs, /* U2*/
&WordRegs, /* I2*/
&DoubleParmRegs, /* U4*/
&DoubleParmRegs, /* I4*/
&QuadReg, /* U8*/
&QuadReg, /* I8*/
&FarPointerRegs, /* CP*/
&FarPointerRegs, /* PT*/
&STParmReg, /* FS*/
&STParmReg, /* FD*/
&STParmReg, /* FL*/
&Empty }; /* XX*/
static reg_set_index IsSets[] = {
/***********************************
define the normal register list associated with a given class
*/
RL_BYTE, /* U1*/
RL_BYTE, /* I1*/
RL_WORD, /* U2*/
RL_WORD, /* I2*/
RL_DOUBLE, /* U4*/
RL_DOUBLE, /* I4*/
RL_8, /* U8*/
RL_8, /* I8*/
RL_FAR_POINTER, /* CP*/
RL_FAR_POINTER, /* PT*/
RL_DOUBLE, /* FS*/
RL_8, /* FD*/
RL_, /* FL*/
RL_ }; /* XX*/
static reg_set_index ReturnSets[] = {
/***************************************
define the set a register normally used to return a given class
*/
RL_AL, /* U1*/
RL_AL, /* I1*/
RL_AX, /* U2*/
RL_AX, /* I2*/
RL_EAX, /* U4*/
RL_EAX, /* I4*/
RL_EDX_EAX, /* U8*/
RL_EDX_EAX, /* I8*/
RL_DX_EAX, /* CP*/
RL_, /* PT*/
RL_EAX, /* FS*/
RL_EDX_EAX, /* FD*/
RL_, /* FL*/
RL_ }; /* XX*/
static reg_set_index Return8087[] = {
/***************************************
define the set a register normally used to return a given class with 8087
*/
RL_AL, /* U1*/
RL_AL, /* I1*/
RL_AX, /* U2*/
RL_AX, /* I2*/
RL_EAX, /* U4*/
RL_EAX, /* I4*/
RL_EDX_EAX, /* U8*/
RL_EDX_EAX, /* I8*/
RL_DX_EAX, /* CP*/
RL_, /* PT*/
RL_ST0, /* FS*/
RL_ST0, /* FD*/
RL_ST0, /* FL*/
RL_ }; /* XX*/
static reg_set_index IndexSets[] = {
/**************************************
define the sets of index registers of a given class
*/
RL_, /* U1*/
RL_, /* I1*/
RL_, /* U2*/
RL_, /* I2*/
RL_DOUBLE, /* U4*/
RL_DOUBLE, /* I4*/
RL_, /* U8*/
RL_, /* I8*/
RL_LONG_INDEX, /* CP*/
RL_LONG_INDEX, /* PT*/
RL_, /* FS*/
RL_, /* FD*/
RL_,
RL_ }; /* XX*/
/*
Information for register set intersections
if sets are of different classes
intersection is empty
else
intersection given in square matrix for class
*/
typedef enum {
ONE_BYTE,
TWO_BYTE,
FOUR_BYTE,
SIX_BYTE,
EIGHT_BYTE,
FLOATING,
OTHER
} intersect_class;
typedef struct reg_class {
intersect_class class;
byte index;
} reg_class;
static reg_class IntersectInfo[] = {
#undef RL
#define RL(a,b,c,d) c,d
#include "rl.h"
OTHER, 0 }; /* RL_NUMBER_OF_SETS*/
static byte Width[] = {
4, /* ONE_BYTE */
7, /* TWO_BYTE */
6, /* FOUR_BYTE */
3, /* SIX_BYTE */
3, /* EIGHT_BYTE */
2, /* FLOATING */
0 }; /* OTHER */
static reg_set_index OneByteInter[] = {
/* AL AH CL BYTE */
RL_AL, RL_, RL_, RL_AL, /* AL*/
RL_, RL_AH, RL_, RL_AH, /* AH*/
RL_, RL_, RL_CL, RL_CL, /* CL*/
RL_AL, RL_AH, RL_CL, RL_BYTE /* BYTE*/
};
/* short forms used in this table*/
/* - RL_WD == RL_WORD*/
/* - RL_2B == RL_TWOBYTE*/
/* - RL_WS == RL_ANYWORD*/
/* - RL_SG == RL_SEG*/
static reg_set_index TwoByteInter[] = {
/*AX CX DX WD 2B SG WS*/
RL_AX, RL_, RL_, RL_AX, RL_AX, RL_, RL_AX, /* AX*/
RL_, RL_CX, RL_, RL_CX, RL_CX, RL_, RL_CX, /* CX*/
RL_, RL_, RL_DX, RL_DX, RL_DX, RL_, RL_DX, /* DX*/
RL_AX, RL_CX, RL_DX, RL_WD, RL_2B, RL_, RL_WD, /* WD*/
RL_AX, RL_CX, RL_CX, RL_2B, RL_2B, RL_, RL_2B, /* 2B*/
RL_, RL_, RL_, RL_, RL_, RL_SG, RL_SG, /* SG*/
RL_AX, RL_CX, RL_DX, RL_WD, RL_2B, RL_SG, RL_WS, /* WS*/
RL_ };
static reg_set_index FourByteInter[] = {
/* RL_EAX RL_EDX RL_DX_AX RL_DOUBLE RL_ABCD RL_ECX */
RL_EAX, RL_, RL_, RL_EAX, RL_EAX, RL_, /* RL_EAX */
RL_, RL_EDX, RL_, RL_EDX, RL_EDX, RL_, /* RL_EDX */
RL_, RL_, RL_DX_AX, RL_, RL_, RL_, /* RL_DX_AX */
RL_EAX, RL_EDX, RL_, RL_DOUBLE, RL_ABCD, RL_, /* RL_DOUBLE */
RL_EAX, RL_EDX, RL_, RL_ABCD, RL_ABCD, RL_, /* RL_ABCD */
RL_, RL_, RL_, RL_, RL_, RL_ECX /* RL_ECX */
};
static reg_set_index SixByteInter[] = {
/* RL_DX_EAX RL_LONG_INDEX RL_FAR_POINTER */
RL_DX_EAX, RL_, RL_DX_EAX, /* RL_DX_EAX */
RL_, RL_LONG_INDEX, RL_LONG_INDEX, /* RL_LONG_INDEX */
RL_DX_EAX, RL_LONG_INDEX, RL_FAR_POINTER /* RL_FAR_POINTER */
};
static reg_set_index EightByteInter[] = {
/* RL_EDX_EAX RL_FPPARM2 RL_8 */
RL_EDX_EAX, RL_, RL_EDX_EAX, /* RL_EDX_EAX */
RL_, RL_FPPARM2, RL_FPPARM2, /* RL_FPPARM2 */
RL_EDX_EAX, RL_FPPARM2, RL_8 /* RL_8 */
};
static reg_set_index FloatingInter[] = {
/* RL_ST0 RL_STI */
RL_ST0, RL_, /* RL_ST0 */
RL_, RL_STI }; /* RL_STI */
static reg_set_index OtherInter[] = {
RL_ };
static reg_set_index *InterTable[] = {
&OneByteInter, /* ONE_BYTE*/
&TwoByteInter, /* TWO_BYTE*/
&FourByteInter, /* FOUR_BYTE*/
&SixByteInter, /* SIX_BYTE*/
&EightByteInter, /* EIGHT_BYTE*/
&FloatingInter, /* FLOATING*/
&OtherInter }; /* others*/
extern void InitRegTbl() {
/*************************************
Initialize the tables.
*/
if( _FPULevel( FPU_87 ) ) {
HW_CAsgn( STParmReg[ Max87Stk ], HW_EMPTY );
}
if( _IsTargetModel( INDEXED_GLOBALS ) ) {
HW_CAsgn( FPParm2Reg[ 0 ], HW_ECX_ESI );
} else {
HW_CAsgn( FPParm2Reg[ 0 ], HW_ECX_EBX );
}
}
extern reg_set_index RegIntersect( reg_set_index s1, reg_set_index s2 ) {
/***************************************************************************
return the intersection of two register lists
*/
reg_class *set1;
reg_class *set2;
intersect_class class;
reg_set_index result;
set1 = & IntersectInfo[ s1 ];
set2 = & IntersectInfo[ s2 ];
class = set1->class;
if( class == set2->class ) {
result = InterTable[ class ]
[ set1->index * Width[ class ] + set2->index ];
} else if( s1 == RL_NUMBER_OF_SETS ) {
result = s2;
} else if( s2 == RL_NUMBER_OF_SETS ) {
result = s1;
} else {
result = RL_;
}
return( result );
}
extern reg_list *ParmChoices( type_class_def class ) {
/*************************************************************
return a list of register which could be used to return type "class"
*/
hw_reg_set *list;
if( _FPULevel( FPU_87 ) ) {
list = ParmSets8087[ class ];
} else {
list = ParmSets[ class ];
}
return( list );
}
extern hw_reg_set InLineParm( hw_reg_set regs, hw_reg_set used ) {
/***********************************************************************
for parm [ 8087 ]. returns the next available 8087 parameter register
*/
if( HW_COvlap( regs, HW_FLTS ) ) {
HW_CAsgn( regs, HW_EMPTY );
if( HW_COvlap( used, HW_ST4 ) ) {
/*regs = EMPTY;*/
} else if( HW_COvlap( used, HW_ST3 ) ) {
HW_CTurnOn( regs, HW_ST4 );
} else if( HW_COvlap( used, HW_ST2 ) ) {
HW_CTurnOn( regs, HW_ST3 );
} else if( HW_COvlap( used, HW_ST1 ) ) {
HW_CTurnOn( regs, HW_ST2 );
} else {
HW_CTurnOn( regs, HW_ST1 );
}
}
return( regs );
}
extern hw_reg_set StructReg() {
/***********************************/
return( HW_ESI );
}
extern hw_reg_set ReturnReg( type_class_def class, bool use_87 ) {
/***********************************************************************
return the "normal" return register used for type "class"
*/
hw_reg_set *list;
if( _FPULevel( FPU_87 ) && use_87 ) {
list = RegSets[ Return8087[ class ] ];
} else {
list = RegSets[ ReturnSets[ class ] ];
}
return( *list );
}
extern reg_set_index SegIndex() {
/**********************************/
return( RL_SEG );
}
extern reg_set_index NoSegments( reg_set_index idx ) {
/********************************************************
return a register list like "idx" that doesn't include any segment regs
*/
if( idx == RL_ANYWORD ) {
idx = RL_WORD;
}
return( idx );
}
extern reg_set_index IndexIntersect( reg_set_index curr,
type_class_def class,
bool is_temp_index ) {
/************************************************************
return the intersection of "curr" with the set of index
registers of type "class"
*/
is_temp_index = is_temp_index;
return( RegIntersect( curr, IndexSets[ class ] ) );
}
extern bool IsIndexReg( hw_reg_set reg, type_class_def class,
bool is_temp_index ) {
/*************************************************
return TRUE if "reg" can be used as an index of type "class"
*/
hw_reg_set *list;
is_temp_index = is_temp_index;
list = RegSets[ IndexSets[ class ] ];
while( !HW_CEqual( *list, HW_EMPTY ) ) {
if( HW_Equal( *list, reg ) ) break;
++ list;
}
return( HW_Equal( *list, reg ) );
}
static type_class_def NotFloatRegClass( hw_reg_set regs ) {
/***********************************************************/
hw_reg_set *possible;
type_class_def class;
class = U1;
for(;;) {
possible = RegSets[ ClassSets[ class ] ];
while( !HW_CEqual( *possible, HW_EMPTY ) ) {
if( HW_Equal( *possible, regs ) ) return( class );
++ possible;
}
++ class;
if( class == XX ) break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?