mipsins.c

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

C
594
字号
    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_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;
            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 "mipsfmt.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( MIPSTable ) / sizeof( MIPSTable[0] );
    for( i = 0; i < n; i++ ) {
        curr = &MIPSTable[i];
        DumpInsTableEntry( curr );
    }
}
#endif
#endif

extern void InsInit()
//*******************
{
    ins_table   *curr;
    int         i, n;

    n = sizeof( MIPSTable ) / sizeof( MIPSTable[0] );
    for( i = 0; i < n; i++ ) {
        curr = &MIPSTable[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 && MIPSValidate( ins ) ) {
#ifdef _STANDALONE_
        MIPSEmit( CurrentSection, ins );
#else
        MIPSEmit( 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( MIPSTable ) / sizeof( MIPSTable[0] );
    for( i = 0; i < n; i++ ) {
        curr = &MIPSTable[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 + -
显示快捷键?