disaxp.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 594 行 · 第 1/2 页
C
594 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Instruction decoding for Alpha AXP architecture.
*
****************************************************************************/
#include <string.h>
#include <ctype.h>
#include "distypes.h"
#include "dis.h"
extern long SEX( unsigned long v, unsigned bit );
extern const dis_range AXPRangeTable[];
extern const int AXPRangeTablePos[];
extern const unsigned char AXPMaxInsName;
typedef union {
unsigned_32 full;
struct {
unsigned_32 code : 26;
unsigned_32 opcode : 6;
} pal;
struct {
unsigned_32 disp : 21;
unsigned_32 ra : 5;
unsigned_32 opcode : 6;
} branch;
struct {
unsigned_32 disp : 16;
unsigned_32 rb : 5;
unsigned_32 ra : 5;
unsigned_32 opcode : 6;
} memory;
struct {
unsigned_32 rc : 5;
unsigned_32 fnc : 4;
unsigned_32 src : 2;
unsigned_32 rnd : 2;
unsigned_32 trp : 3;
unsigned_32 rb : 5;
unsigned_32 ra : 5;
unsigned_32 opcode : 6;
} fp_operate;
struct {
unsigned_32 rc : 5;
unsigned_32 func : 7;
unsigned_32 lit_flag : 1;
unsigned_32 : 3;
unsigned_32 rb : 5;
unsigned_32 ra : 5;
unsigned_32 opcode : 6;
} reg_operate;
struct {
unsigned_32 rc : 5;
unsigned_32 func : 7;
unsigned_32 lit_flag : 1;
unsigned_32 lit : 8;
unsigned_32 ra : 5;
unsigned_32 opcode : 6;
} lit_operate;
} axp_ins;
dis_handler_return AXPPal( dis_handle *h, void *d, dis_dec_ins *ins )
{
axp_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_IMMED;
ins->op[0].value = code.pal.code;
ins->num_ops = 1;
return( DHR_DONE );
}
dis_handler_return AXPMemory( dis_handle *h, void *d, dis_dec_ins *ins )
{
axp_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.memory.ra + DR_AXP_r0;
ins->op[1].type = DO_MEMORY_ABS;
ins->op[1].value = SEX( code.memory.disp, 15 );
ins->op[1].base = code.memory.rb + DR_AXP_r0;
ins->num_ops = 2;
switch( code.memory.opcode & 0x0b ) {
case 0x00:
ins->op[1].ref_type = DRT_AXP_FFLOAT;
break;
case 0x01:
ins->op[1].ref_type = DRT_AXP_GFLOAT;
break;
case 0x02:
ins->op[1].ref_type = DRT_AXP_SFLOAT;
break;
case 0x03:
ins->op[1].ref_type = DRT_AXP_TFLOAT;
break;
case 0x08:
case 0x0a:
ins->op[1].ref_type = DRT_AXP_LWORD;
break;
case 0x09:
case 0x0b:
ins->op[1].ref_type = DRT_AXP_QWORD;
break;
}
return( DHR_DONE );
}
dis_handler_return AXPFPMemory( dis_handle *h, void *d, dis_dec_ins *ins )
{
AXPMemory( h, d, ins );
ins->op[0].base += DR_AXP_f0 - DR_AXP_r0;
return( DHR_DONE );
}
dis_handler_return AXPMemoryLA( dis_handle *h, void *d, dis_dec_ins *ins )
{
AXPMemory( h, d, ins );
ins->op[1].type = DO_ABSOLUTE;
ins->op[1].ref_type = DR_NONE;
return( DHR_DONE );
}
dis_handler_return AXPMemoryFC( dis_handle *h, void *d, dis_dec_ins *ins )
{
axp_ins code;
code.full = ins->opcode;
switch( ins->type ) {
case DI_AXP_FETCH:
case DI_AXP_FETCH_M:
ins->op[0].type = DO_MEMORY_ABS;
ins->op[0].base = code.memory.rb + DR_AXP_r0;
ins->num_ops = 1;
break;
case DI_AXP_RPCC:
ins->op[0].type = DO_REG;
ins->op[0].base = code.memory.rb + DR_AXP_r0;
ins->num_ops = 1;
default:
break;
}
return( DHR_DONE );
}
dis_handler_return AXPJump( dis_handle *h, void *d, dis_dec_ins *ins )
{
axp_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.memory.ra + DR_AXP_r0;
ins->op[1].type = DO_ABSOLUTE;
ins->op[1].base = code.memory.rb + DR_AXP_r0;
ins->op[1].value = 0;
ins->op[2].type = DO_IMMED;
ins->op[2].value = code.memory.disp & 0x3fff;
ins->num_ops = 3;
return( DHR_DONE );
}
dis_handler_return AXPBranch( dis_handle *h, void *d, dis_dec_ins *ins )
{
axp_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.branch.ra + DR_AXP_r0;
ins->op[1].type = DO_RELATIVE;
ins->op[1].value = (SEX( code.branch.disp, 20 ) + 1) * sizeof( unsigned_32 );
ins->num_ops = 2;
return( DHR_DONE );
}
dis_handler_return AXPFPBranch( dis_handle *h, void *d, dis_dec_ins *ins )
{
AXPBranch( h, d, ins );
ins->op[0].base += DR_AXP_f0 - DR_AXP_r0;
return( DHR_DONE );
}
dis_handler_return AXPOperate( dis_handle *h, void *d, dis_dec_ins *ins )
{
axp_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.reg_operate.ra + DR_AXP_r0;
if( code.reg_operate.lit_flag ) {
ins->op[1].type = DO_IMMED;
ins->op[1].value = code.lit_operate.lit;
} else {
ins->op[1].type = DO_REG;
ins->op[1].base = code.reg_operate.rb + DR_AXP_r0;
}
ins->op[2].type = DO_REG;
ins->op[2].base = code.reg_operate.rc + DR_AXP_r0;
ins->num_ops = 3;
return( DHR_DONE );
}
dis_handler_return AXPOperateV( dis_handle *h, void *d, dis_dec_ins *ins )
{
AXPOperate( h, d, ins );
if( ins->opcode & (1 << 11) ) {
ins->flags |= DIF_AXP_V;
}
return( DHR_DONE );
}
dis_handler_return AXPFPOperate( dis_handle *h, void *d, dis_dec_ins *ins )
{
axp_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.fp_operate.ra + DR_AXP_f0;
ins->op[1].type = DO_REG;
ins->op[1].base = code.fp_operate.rb + DR_AXP_f0;
ins->op[2].type = DO_REG;
ins->op[2].base = code.fp_operate.rc + DR_AXP_f0;
ins->num_ops = 3;
return( DHR_DONE );
}
dis_handler_return AXPFPConvert( dis_handle *h, void *d, dis_dec_ins *ins )
{
axp_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.fp_operate.rb + DR_AXP_f0;
ins->op[1].type = DO_REG;
ins->op[1].base = code.fp_operate.rc + DR_AXP_f0;
if( ins->opcode & (1 << 13) ) {
ins->flags |= DIF_AXP_V;
}
if( ins->opcode & (1 << 14) ) {
ins->flags |= DIF_AXP_S;
}
ins->num_ops = 2;
return( DHR_DONE );
}
static dis_handler_return SetIEEEFlags( dis_dec_ins *ins )
{
axp_ins code;
code.full = ins->opcode;
switch( code.fp_operate.trp ) {
case 0x2:
case 0x3:
case 0x6:
return( DHR_INVALID );
}
if( code.fp_operate.trp & 0x1 ) {
if( code.fp_operate.fnc == 0xf ) {
ins->flags |= DIF_AXP_V;
} else {
ins->flags |= DIF_AXP_U;
}
}
if( code.fp_operate.trp & 0x2 ) {
ins->flags |= DIF_AXP_I;
}
if( code.fp_operate.trp & 0x4 ) {
ins->flags |= DIF_AXP_S;
}
switch( code.fp_operate.rnd ) {
case 0x0:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?