alphains.c

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

C
647
字号
    INS( "negt",    0x16,   0x00A1,     IT_PSEUDO_NEGF,         ENUM_IEEE_ADDS ),
    INS( "fneg",    0x17,   0x0021,     IT_PSEUDO_FNEG,         ENUM_NONE ),
    INS( "fnegf",   0x17,   0x0021,     IT_PSEUDO_FNEG,         ENUM_NONE ),
    INS( "fnegg",   0x17,   0x0021,     IT_PSEUDO_FNEG,         ENUM_NONE ),
    INS( "fnegs",   0x17,   0x0021,     IT_PSEUDO_FNEG,         ENUM_NONE ),
    INS( "fnegt",   0x17,   0x0021,     IT_PSEUDO_FNEG,         ENUM_NONE ),
    INS( "not",     0x11,   0x0028,     IT_PSEUDO_NOT,          ENUM_NONE ),
    INS( "or",      0x11,   0x0020,     IT_OPERATE,             ENUM_NONE ),
    INS( "andnot",  0x11,   0x0008,     IT_OPERATE,             ENUM_NONE ),
    INS( "xornot",  0x11,   0x0048,     IT_OPERATE,             ENUM_NONE ),
    INS( "fabs",    0x17,   0x0020,     IT_PSEUDO_NEGF,         ENUM_NONE ),
    INS( "sextl",   0x10,   0x0000,     IT_PSEUDO_NOT,          ENUM_NONE ),
 // The following pseudo-instructions might emit multiple real instructions
    INS( "mov",     0x11,   0x0020,     IT_PSEUDO_MOV,          ENUM_NONE ),
    // abs pseudo ins (opcode & funccode are from subl/v, subq/v)
    INS( "absl",    0x10,   0x0049,     IT_PSEUDO_ABS,          ENUM_NONE ),
    INS( "absq",    0x10,   0x0069,     IT_PSEUDO_ABS,          ENUM_NONE ),

#if 0
 // NYI: (more pseudo-ins that are in MS asaxp)
 //--------------------------------------------
    // Load instructions that emits more than one instructions
    INS( "ldb",     0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    INS( "ldbu",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    INS( "ldw",     0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    INS( "ldwu",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    INS( "uldw",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    INS( "uldwu",   0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    INS( "uldl",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    INS( "uldq",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    // Store instructions that emits more than one instructions
    INS( "stb",     0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    INS( "stw",     0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    INS( "ustw",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    INS( "ustl",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    INS( "ustq",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    // Integer divide and remainder instructions that are unsupported in
    // hardward level.
    // (MS asaxp does this by generating bsr to some _div function elsewhere)
    INS( "divl",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    INS( "divlu",   0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    INS( "divq",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    INS( "divqu",   0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    INS( "reml",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    INS( "remlu",   0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    INS( "remq",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
    INS( "remqu",   0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ),
#endif
};

#define MAX_NAME_LEN    20  // maximum length of an Alpha instruction mnemonic

static void addInstructionSymbol( qualifier_flags flags, ins_table *table_entry ) {
//*********************************************************************************
// Given an instruction name for which the optional bits in flags
// are turned on, add a symbol for it to the symbol table.

    sym_handle  sym;
    ins_symbol  *entry;
    char        buffer[ MAX_NAME_LEN ];

    strcpy( buffer, table_entry->name );
    if( flags ) {
        strcat( buffer, "/" );
        if( flags & QF_S ) strcat( buffer, "s" );

        if( flags & QF_U ) strcat( buffer, "u" );   // u & v are mutually
        if( flags & QF_V ) strcat( buffer, "v" );   // exclusive

        if( flags & QF_I ) strcat( buffer, "i" );

        if( flags & QF_C ) strcat( buffer, "c" );   // c, m, & d are
        if( flags & QF_M ) strcat( buffer, "m" );   // mutually exclusive
        if( flags & QF_D ) strcat( buffer, "d" );
    }

    entry = MemAlloc( sizeof( ins_symbol ) );
    entry->table_entry = table_entry;
    entry->flags = flags;

    // link it into our list of symbols for this table entry
    entry->next = table_entry->symbols;
    table_entry->symbols = entry;

    sym = SymAdd( buffer, SYM_INSTRUCTION );
    SymSetLink( sym, (void *)entry );
}

static void enum_NONE( ins_enum_method method, uint_32 mask, uint_8 level, void (*func)( qualifier_flags, ins_table * ), void *parm ) {
//********************************************************************************************************************************

    method = method;
    level = level;
    mask = mask;
    func( QF_NONE, parm );
}

static void enum_OF_ADDL( ins_enum_method method, uint_32 mask, uint_8 level, void (*func)( qualifier_flags, ins_table * ), void *parm ) {
//***********************************************************************************************************************************

    method = method;
    level = level;
    mask = mask;
    func( QF_NONE, parm );
    func( QF_V, parm );
}

static void enum_DTI_CVTQL( ins_enum_method method, uint_32 mask, uint_8 level, void (*func)( qualifier_flags, ins_table * ), void *parm ) {
//*************************************************************************************************************************************

    method = method;
    level = level;
    mask = mask;
    func( QF_NONE, parm );
    func( QF_V, parm );
    func( QF_S | QF_V, parm );
}

static void enum_IEEE_CMPTEQ( ins_enum_method method, uint_32 mask, uint_8 level, void (*func)( qualifier_flags, ins_table * ), void *parm ) {
//***************************************************************************************************************************************

    method = method;
    level = level;
    mask = mask;
    func( QF_NONE, parm );
    func( QF_S | QF_U, parm );
}

static void enum_IEEE_CVTQS( ins_enum_method method, uint_32 mask, uint_8 level, void (*func)( qualifier_flags, ins_table * ), void *parm ) {
//**************************************************************************************************************************************

    assert( level < 2 );
    switch( level ) {
    case 0:
        enum_IEEE_CVTQS( method, mask, level + 1, func, parm );
        mask |= ( QF_S | QF_U | QF_I );
        enum_IEEE_CVTQS( method, mask, level + 1, func, parm );
        break;
    case 1:
        func( mask, parm );
        mask |= QF_C;
        func( mask, parm );
        mask &= ~QF_C;
        mask |= QF_M;
        func( mask, parm );
        mask &= ~QF_M;
        mask |= QF_D;
        func( mask, parm );
        break;
    }
}

static void enum_VAX_ADDF_or_CVTGQ( ins_enum_method method, uint_32 mask, uint_8 level, void (*func)( qualifier_flags, ins_table * ), void *parm ) {
//*********************************************************************************************************************************************

    assert( level < 3 );
    switch( level ) {
    case 0:
        enum_VAX_ADDF_or_CVTGQ( method, mask, level + 1, func, parm );
        mask |= QF_S;
        enum_VAX_ADDF_or_CVTGQ( method, mask, level + 1, func, parm );
        break;
    case 1:
        enum_VAX_ADDF_or_CVTGQ( method, mask, level + 1, func, parm );
        mask |= ( ( method == ENUM_VAX_ADDF ) ? QF_U : QF_V );
        enum_VAX_ADDF_or_CVTGQ( method, mask, level + 1, func, parm );
        break;
    case 2:
        func( mask, parm );
        mask |= QF_C;
        func( mask, parm );
        break;
    }
}

static void enum_VAX_CMPGEQ( ins_enum_method method, uint_32 mask, uint_8 level, void (*func)( qualifier_flags, ins_table * ), void *parm ) {
//**************************************************************************************************************************************

    method = method;
    level = level;
    mask = mask;
    func( QF_NONE, parm );
    func( QF_S, parm );
}

static void enum_VAX_CVTQF( ins_enum_method method, uint_32 mask, uint_8 level, void (*func)( qualifier_flags, ins_table * ), void *parm ) {
//*************************************************************************************************************************************

    method = method;
    level = level;
    mask = mask;
    func( QF_NONE, parm );
    func( QF_C, parm );
}

static void enum_IEEE_ADDS_or_CVTTQ( ins_enum_method method, uint_32 mask, uint_8 level, void (*func)( qualifier_flags, ins_table * ), void *parm ) {
//**********************************************************************************************************************************************

    assert( level < 4 );
    switch( level ) {
    case 0:
        enum_IEEE_ADDS_or_CVTTQ( method, mask, level + 1, func, parm );
        mask |= QF_S;
        enum_IEEE_ADDS_or_CVTTQ( method, mask, level + 1, func, parm );
        break;
    case 1:
        if( !mask ) {
            enum_IEEE_ADDS_or_CVTTQ( method, mask, level + 1, func, parm );
        }
        mask |= ( ( method == ENUM_IEEE_ADDS ) ? QF_U : QF_V );
        enum_IEEE_ADDS_or_CVTTQ( method, mask, level + 1, func, parm );
        break;
    case 2:
        enum_IEEE_ADDS_or_CVTTQ( method, mask, level + 1, func, parm );
        if( mask & QF_S ) {
            mask |= QF_I;

⌨️ 快捷键说明

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