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