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