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