alphains.c

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

C
647
字号
            enum_IEEE_ADDS_or_CVTTQ( method, mask, level + 1, func, parm );
        }
        break;
    case 3:
        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;
    }
}

typedef void (*enumFunc_t)( ins_enum_method, uint_32, uint_8, void (*func)( qualifier_flags, ins_table * ), void * );

#define PICK( a, b )    b,
static enumFunc_t enumFunc[] = {
#include "insenum.inc"
};
#undef PICK

static void enumInstructions( ins_enum_method method, void (*func)( qualifier_flags set, ins_table *parm ), void *parm ) {
//************************************************************************************************
// Depending on which enum_method it belongs to, different instruction-
// enumeration functions will be called to generate all the possible
// instructions with the different qualifiers attached.

    enumFunc[method]( method, QF_NONE, 0, func, parm );
}

#ifdef _STANDALONE_
#ifndef NDEBUG
static char *itStrings[] = {
#define PICK( a, b, c, d, e ) #a,
#include "alphafmt.inc"
#undef PICK
};

extern void DumpITString( ins_template template ) {
    printf( itStrings[ template ] );
}

static char *insEnumStrings[] = {
#define PICK( a, b ) #a,
#include "insenum.inc"
#undef PICK
};

extern void DumpInsEnumMethod( ins_enum_method method ) {
//*******************************************************

    printf( insEnumStrings[ method ] );
}

extern void DumpInsTableEntry( ins_table *table_entry ) {
//*******************************************************

    ins_symbol  *symbol;

    printf( "%s: 0x%x(0x%x) ", table_entry->name, table_entry->opcode, table_entry->funccode );
    DumpITString( table_entry->template );
    printf( ", " );
    DumpInsEnumMethod( table_entry->method );
    printf( "\n\tSymbol entries: " );
    symbol = table_entry->symbols;
    while( symbol != NULL ) {
        printf( " %x", symbol );
        symbol = symbol->next;
    }
    printf( "\n" );
}

extern void DumpInsTables() {
//***************************

    ins_table   *curr;
    int         i, n;

    n = sizeof( AlphaTable ) / sizeof( AlphaTable[0] );
    for( i = 0; i < n; i++ ) {
        curr = &AlphaTable[ i ];
        DumpInsTableEntry( curr );
    }
}
#endif
#endif

extern void InsInit() {
//*********************

    ins_table   *curr;
    int         i, n;

    n = sizeof( AlphaTable ) / sizeof( AlphaTable[0] );
    for( i = 0; i < n; i++ ) {
        curr = &AlphaTable[ i ];
        /* for each possible symbol generated by this instruction, add a symbol table entry */
        enumInstructions( curr->method, addInstructionSymbol, curr );
    }
#ifndef NDEBUG
    #ifdef _STANDALONE_
    if( _IsOption( DUMP_INS_TABLE ) ) DumpInsTables();
    #endif
#endif
}

extern instruction *InsCreate( sym_handle op_sym ) {
//**************************************************
// Allocate an instruction and initialize it.

    instruction *ins;

    ins = MemAlloc( sizeof( instruction ) );
    ins->opcode_sym = op_sym;
    ins->format = SymGetLink( op_sym );
    ins->num_operands = 0;
    return( ins );
}

extern void InsAddOperand( instruction *ins, ins_operand *op ) {
//**********************************************************
// Add an operand to the given instruction.

    if( ins->num_operands == MAX_OPERANDS ) {
        if( !insErrFlag ) {
            Error( MAX_NUMOP_EXCEEDED );
            insErrFlag = TRUE;
        }
        MemFree( op );
        return;
    }
    if( insErrFlag) insErrFlag = FALSE;
    ins->operands[ ins->num_operands++ ] = op;
}

extern void InsEmit( instruction *ins ) {
//***************************************
// Check an instruction to make sure operands match
// and encode it. The encoded instruction is emitted
// to the current OWL section.

#ifndef NDEBUG
    #ifdef _STANDALONE_
    if( _IsOption( DUMP_INSTRUCTIONS ) ) {
        DumpIns( ins );
    }
    #endif
#endif
    if( insErrFlag == FALSE && AlphaValidate( ins ) ) {
        #ifdef _STANDALONE_
        AlphaEmit( CurrentSection, ins );
        #else
        AlphaEmit( ins );
        #endif
    }
}

extern void InsDestroy( instruction *ins ) {
//******************************************
// Free up an instruction and all operands which
// are hanging off of it.

    int         i;

    for( i = 0; i < ins->num_operands; i++ ) {
        MemFree( ins->operands[ i ] );
    }
    MemFree( ins );
}

extern void InsFini() {
//*********************

    ins_table   *curr;
    ins_symbol  *next;
    ins_symbol  *entry;
    int         i, n;
    extern instruction *AsCurrIns; // from as.y

    if( AsCurrIns != NULL ) {
        InsDestroy( AsCurrIns );
        AsCurrIns = NULL;
    }
    n = sizeof( AlphaTable ) / sizeof( AlphaTable[0] );
    for( i = 0; i < n; i++ ) {
        curr = &AlphaTable[ i ];
        for( entry = curr->symbols; entry != NULL; entry = next ) {
            next = entry->next;
            MemFree( entry );
        }
        curr->symbols = NULL;   // need to reset this pointer
    }
}

#ifdef _STANDALONE_
#ifndef NDEBUG
extern void DumpIns( instruction *ins ) {
//***************************************

    int         i;

    printf( "%-11s", SymName( ins->opcode_sym ) );
    for( i = 0; i < ins->num_operands; i++ ) {
        if( i != 0 ) printf( ", " );
        DumpOperand( ins->operands[ i ] );
    }
    printf( "\n" );
}
#endif
#endif

⌨️ 快捷键说明

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