dismips.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 677 行 · 第 1/2 页
C
677 行
/****************************************************************************
*
* 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 MIPS R4000 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 MIPSRangeTable[];
extern const int MIPSRangeTablePos[];
extern const unsigned char MIPSMaxInsName;
typedef union {
unsigned_32 full;
#ifdef __BIG_ENDIAN__
struct {
unsigned_32 op : 6;
unsigned_32 rs : 5;
unsigned_32 rt : 5;
unsigned_32 immediate : 16;
} itype;
struct {
unsigned_32 op : 6;
unsigned_32 target : 26;
} jtype;
struct {
unsigned_32 op : 6;
unsigned_32 rs : 5;
unsigned_32 rt : 5;
unsigned_32 rd : 5;
unsigned_32 sa : 5;
unsigned_32 funct : 6;
} rtype;
struct {
unsigned_32 op : 6;
unsigned_32 fmt : 5;
unsigned_32 ft : 5;
unsigned_32 fs : 5;
unsigned_32 fd : 5;
unsigned_32 funct : 6;
} frtype;
struct {
unsigned_32 op : 6;
unsigned_32 code : 20;
unsigned_32 funct : 6;
} break_t;
struct {
unsigned_32 op : 6;
unsigned_32 rs : 5;
unsigned_32 rt : 5;
unsigned_32 code : 10;
unsigned_32 op2 : 6;
} trap_t;
#else
struct {
unsigned_32 immediate : 16;
unsigned_32 rt : 5;
unsigned_32 rs : 5;
unsigned_32 op : 6;
} itype;
struct {
unsigned_32 target : 26;
unsigned_32 op : 6;
} jtype;
struct {
unsigned_32 funct : 6;
unsigned_32 sa : 5;
unsigned_32 rd : 5;
unsigned_32 rt : 5;
unsigned_32 rs : 5;
unsigned_32 op : 6;
} rtype;
struct {
unsigned_32 funct : 6;
unsigned_32 fd : 5;
unsigned_32 fs : 5;
unsigned_32 ft : 5;
unsigned_32 fmt : 5;
unsigned_32 op : 6;
} frtype;
struct {
unsigned_32 funct : 6;
unsigned_32 code : 20;
unsigned_32 op : 6;
} break_t;
struct {
unsigned_32 op2 : 6;
unsigned_32 code : 10;
unsigned_32 rt : 5;
unsigned_32 rs : 5;
unsigned_32 op : 6;
} trap_t;
#endif
} mips_ins;
static dis_format_flags MIPSFloatFmt( unsigned_32 fmt )
{
dis_format_flags flags;
switch( fmt ) {
case 16:
flags = DIF_MIPS_FF_S;
break;
case 17:
flags = DIF_MIPS_FF_D;
break;
case 20:
flags = DIF_MIPS_FF_W;
break;
case 21:
flags = DIF_MIPS_FF_L;
break;
case 22:
flags = DIF_MIPS_FF_PS;
break;
default:
flags = 0;
}
return( flags );
}
dis_handler_return MIPSNull( dis_handle *h, void *d, dis_dec_ins *ins )
{
ins->num_ops = 0;
return( DHR_DONE );
}
dis_handler_return MIPSJType( dis_handle *h, void *d, dis_dec_ins *ins )
{
mips_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_ABSOLUTE;
ins->op[0].value = code.jtype.target << 2;
ins->num_ops = 1;
if( code.jtype.op & 1 )
ins->flags |= DIF_MIPS_LINK;
return( DHR_DONE );
}
dis_handler_return MIPSCode( dis_handle *h, void *d, dis_dec_ins *ins )
{
mips_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_IMMED;
ins->op[0].value = code.break_t.code;
if( code.break_t.code ) // hide zero "opcode"
ins->num_ops = 1;
else
ins->num_ops = 0;
return( DHR_DONE );
}
dis_handler_return MIPSImmed1( dis_handle *h, void *d, dis_dec_ins *ins )
{
mips_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.itype.rt + DR_MIPS_r0;
ins->op[1].type = DO_IMMED;
ins->op[1].value = code.itype.immediate;
ins->num_ops = 2;
return( DHR_DONE );
}
dis_handler_return MIPSImmed2( dis_handle *h, void *d, dis_dec_ins *ins )
{
mips_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.itype.rt + DR_MIPS_r0;
ins->op[1].type = DO_REG;
ins->op[1].base = code.itype.rs + DR_MIPS_r0;
ins->op[2].type = DO_IMMED;
ins->op[2].value = SEX( code.itype.immediate, 15 );
ins->num_ops = 3;
return( DHR_DONE );
}
dis_handler_return MIPSImmed2U( dis_handle *h, void *d, dis_dec_ins *ins )
{
mips_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.itype.rt + DR_MIPS_r0;
ins->op[1].type = DO_REG;
ins->op[1].base = code.itype.rs + DR_MIPS_r0;
ins->op[2].type = DO_IMMED;
ins->op[2].value = code.itype.immediate;
ins->num_ops = 3;
return( DHR_DONE );
}
dis_handler_return MIPSShift( dis_handle *h, void *d, dis_dec_ins *ins )
{
mips_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.rtype.rd + DR_MIPS_r0;
ins->op[1].type = DO_REG;
ins->op[1].base = code.rtype.rt + DR_MIPS_r0;
ins->op[2].type = DO_IMMED;
ins->op[2].value = code.rtype.sa;
ins->num_ops = 3;
return( DHR_DONE );
}
dis_handler_return MIPSTrap1( dis_handle *h, void *d, dis_dec_ins *ins )
{
mips_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.itype.rs + DR_MIPS_r0;
ins->op[1].type = DO_IMMED;
ins->op[1].value = SEX( code.itype.immediate, 15 );
ins->num_ops = 2;
return( DHR_DONE );
}
dis_handler_return MIPSTrap2( dis_handle *h, void *d, dis_dec_ins *ins )
{
mips_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.trap_t.rs + DR_MIPS_r0;
ins->op[1].type = DO_REG;
ins->op[1].base = code.trap_t.rt + DR_MIPS_r0;
// What do we do with 'code'?
// ins->op[2].type = DO_IMMED;
// ins->op[2].value = code.trap_t.code;
// ins->num_ops = 3;
ins->num_ops = 2;
return( DHR_DONE );
}
dis_handler_return MIPSRegD( dis_handle *h, void *d, dis_dec_ins *ins )
{
mips_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.rtype.rd + DR_MIPS_r0;
ins->num_ops = 1;
return( DHR_DONE );
}
dis_handler_return MIPSRegS( dis_handle *h, void *d, dis_dec_ins *ins )
{
mips_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.rtype.rs + DR_MIPS_r0;
ins->num_ops = 1;
return( DHR_DONE );
}
dis_handler_return MIPSReg2( dis_handle *h, void *d, dis_dec_ins *ins )
{
mips_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.rtype.rt + DR_MIPS_r0;
ins->op[1].type = DO_REG;
ins->op[1].base = code.rtype.rd + DR_MIPS_r0;
ins->num_ops = 2;
return( DHR_DONE );
}
dis_handler_return MIPSReg3( dis_handle *h, void *d, dis_dec_ins *ins )
{
mips_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.rtype.rd + DR_MIPS_r0;
ins->op[1].type = DO_REG;
ins->op[1].base = code.rtype.rs + DR_MIPS_r0;
ins->op[2].type = DO_REG;
ins->op[2].base = code.rtype.rt + DR_MIPS_r0;
ins->num_ops = 3;
return( DHR_DONE );
}
dis_handler_return MIPSMulDiv( dis_handle *h, void *d, dis_dec_ins *ins )
{
mips_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.rtype.rs + DR_MIPS_r0;
ins->op[1].type = DO_REG;
ins->op[1].base = code.rtype.rt + DR_MIPS_r0;
ins->num_ops = 2;
return( DHR_DONE );
}
dis_handler_return MIPSCache( dis_handle *h, void *d, dis_dec_ins *ins )
{
mips_ins code;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?