mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2567 lines
63 KiB
2567 lines
63 KiB
/***********************************************************************
|
|
* Microsoft Puma
|
|
*
|
|
* Microsoft Confidential. Copyright 1994-1996 Microsoft Corporation.
|
|
*
|
|
* Component:
|
|
*
|
|
* File: axpdis.cpp
|
|
*
|
|
* File Comments:
|
|
*
|
|
*
|
|
***********************************************************************/
|
|
|
|
#include "pumap.h"
|
|
|
|
#include "axp.h"
|
|
|
|
#include <ctype.h>
|
|
#include <iomanip.h>
|
|
#include <limits.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <strstrea.h>
|
|
|
|
|
|
const TRMT DISAXP::mptrmtaxptrmt[] =
|
|
{
|
|
trmtUnknown, // trmtaxpUnknown
|
|
trmtFallThrough, // trmtaxpFallThrough
|
|
trmtBra, // trmtaxpBra
|
|
trmtBraInd, // trmtaxpBraInd
|
|
trmtBraCc, // trmtaxpBraCc
|
|
trmtCall, // trmtaxpCall
|
|
trmtCallInd, // trmtaxpCallInd
|
|
trmtTrapCc, // trmtaxpTrapCc
|
|
};
|
|
|
|
|
|
// -----------------------------------------------------------------
|
|
// Instruction class definitions
|
|
// -----------------------------------------------------------------
|
|
|
|
#define DEFCLS(trmtaxp_, opcls1, opcls2, opcls3) \
|
|
{ trmtaxp ## trmtaxp_, { opcls ## opcls1, opcls ## opcls2, opcls ## opcls3 } }
|
|
|
|
const DISAXP::CLS DISAXP::rgcls[] =
|
|
{
|
|
DEFCLS(Unknown, None, None, None ), // iclsInvalid
|
|
DEFCLS(FallThrough, Ra_w, Mem, None ), // iclsLoadAddr
|
|
DEFCLS(FallThrough, Ra_w, MemHigh, None ), // iclsLoadAddrH
|
|
DEFCLS(FallThrough, Ra_w, Mem_r, None ), // iclsLoad
|
|
DEFCLS(FallThrough, Ra_r, Mem_w, None ), // iclsStore
|
|
DEFCLS(FallThrough, Ra_m, Mem_w, None ), // iclsStoreCc
|
|
DEFCLS(Call, Ra_w, Bra, None ), // iclsCall
|
|
DEFCLS(BraCc, Ra_r, Bra, None ), // iclsBraCc
|
|
DEFCLS(BraInd, Ra_w, Jmp, Hint1 ), // iclsJmp
|
|
DEFCLS(FallThrough, Ra_r, RbLb, Rc_w ), // iclsReg
|
|
DEFCLS(TrapCc, Ra_r, RbLb, Rc_w ), // iclsRegTrap
|
|
DEFCLS(FallThrough, Fa_w, Mem_r, None ), // iclsLoadFp
|
|
DEFCLS(FallThrough, Fa_r, Mem_w, None ), // iclsStoreFp
|
|
DEFCLS(BraCc, Fa_r, Bra, None ), // iclsBraCcFp
|
|
DEFCLS(FallThrough, Fa_r, Fb_r, Fc_w ), // iclsRegFp
|
|
DEFCLS(FallThrough, Fa_r, Fb_r, Fc_w ), // iclsRegFp1
|
|
DEFCLS(FallThrough, Fa_r, Fb_r, Fc_w ), // iclsRegFp2
|
|
DEFCLS(FallThrough, Fa_r, Fb_r, Fc_w ), // iclsRegFp5
|
|
DEFCLS(FallThrough, Fb_r, Fc_w, None ), // iclsReg2Fp
|
|
DEFCLS(FallThrough, Fb_r, Fc_w, None ), // iclsReg2Fp1
|
|
DEFCLS(FallThrough, Fb_r, Fc_w, None ), // iclsReg2Fp3
|
|
DEFCLS(FallThrough, Fb_r, Fc_w, None ), // iclsReg2Fp4
|
|
DEFCLS(FallThrough, Fb_r, Fc_w, None ), // iclsReg2Fp6
|
|
DEFCLS(FallThrough, Fb_r, Fc_w, None ), // iclsReg2Fp7
|
|
DEFCLS(FallThrough, Fb_r, Fc_w, None ), // iclsCvtql
|
|
DEFCLS(FallThrough, Fa_r, Fb_r, Fc_w ), // iclsFpcr
|
|
DEFCLS(FallThrough, Pal, None, None ), // iclsPal
|
|
DEFCLS(FallThrough, Fetch, None, None ), // iclsFetch
|
|
DEFCLS(FallThrough, None, None, None ), // iclsNone (MB, TRAPB)
|
|
DEFCLS(FallThrough, Ra_w, None, None ), // iclsRa_w (RC, RS)
|
|
DEFCLS(BraInd, None, None, None ), // iclsEv4Rei
|
|
DEFCLS(FallThrough, Ra_r, Rb_r, None ), // iclsEv4Pr UNDONE
|
|
DEFCLS(FallThrough, Ra_r, Ev4Mem_r, None ), // iclsEv4Load
|
|
DEFCLS(FallThrough, Ra_r, Ev4Mem_w, None ), // iclsEv4Store
|
|
|
|
// Classes for pseudo-ops
|
|
|
|
DEFCLS(Unknown, Bra, None, None ), // iclsBra
|
|
DEFCLS(Unknown, Rc_w, None, None ), // iclsReg1
|
|
DEFCLS(Unknown, Mem, Ra_w, None ), // iclsMov
|
|
DEFCLS(Unknown, RbLb, Rc_w, None ), // iclsReg2
|
|
DEFCLS(Unknown, RbLb, Rc_w, None ), // iclsReg2Trap
|
|
DEFCLS(Unknown, Fc_w, None, None ), // iclsReg1Fp
|
|
|
|
DEFCLS(Unknown, Ra_w, Jmp, Hint2 ), // iclsRet1
|
|
DEFCLS(Unknown, Ra_w, Jmp, None ), // iclsRet2
|
|
DEFCLS(Unknown, Ra_w, Hint2, None ), // iclsRet3
|
|
DEFCLS(Unknown, Ra_w, None, None ), // iclsRet4
|
|
DEFCLS(Unknown, Jmp, Hint2, None ), // iclsRet5
|
|
DEFCLS(Unknown, Jmp, None, None ), // iclsRet6
|
|
DEFCLS(Unknown, Hint2, None, None ), // iclsRet7
|
|
DEFCLS(Unknown, None, None, None ), // iclsRet8
|
|
};
|
|
|
|
|
|
// -----------------------------------------------------------------
|
|
// Instruction Opcode Definitions
|
|
// -----------------------------------------------------------------
|
|
|
|
#define DEFOPCD(szMnemonic, icls_) { szMnemonic, icls ## icls_ }
|
|
#define INVOPCD() DEFOPCD(NULL, Invalid)
|
|
|
|
// Main group identified by bits 31-26 of the instruction
|
|
|
|
const DISAXP::OPCD DISAXP::rgopcd[] =
|
|
{
|
|
DEFOPCD("call_pal", Pal ), // 0x0000 CALLPAL_OP 0x00 // ALPHA_CALLPAL
|
|
INVOPCD(), // 0x0001 (Reserved)
|
|
INVOPCD(), // 0x0002 (Reserved)
|
|
INVOPCD(), // 0x0003 (Reserved)
|
|
INVOPCD(), // 0x0004 (Reserved)
|
|
INVOPCD(), // 0x0005 (Reserved)
|
|
INVOPCD(), // 0x0006 (Reserved)
|
|
INVOPCD(), // 0x0007 (Reserved)
|
|
DEFOPCD("~lda", LoadAddr ), // 0x0008
|
|
DEFOPCD("ldah", LoadAddrH ), // 0x0009
|
|
DEFOPCD("ldbu", Load ), // 0x000A
|
|
DEFOPCD("ldq_u", Load ), // 0x000B
|
|
DEFOPCD("ldwu", Load ), // 0x000C
|
|
DEFOPCD("stw", Load ), // 0x000D
|
|
DEFOPCD("stb", Load ), // 0x000E
|
|
DEFOPCD("stq_u", Load ), // 0x000F
|
|
INVOPCD(), // 0x0010 => ARITH
|
|
INVOPCD(), // 0x0011 => BIT
|
|
INVOPCD(), // 0x0012 => BYTE
|
|
INVOPCD(), // 0x0013 => MUL
|
|
INVOPCD(), // 0x0014 (Reserved)
|
|
INVOPCD(), // 0x0015 => VAXFP
|
|
INVOPCD(), // 0x0016 => IEEEFP
|
|
INVOPCD(), // 0x0017 => FPOP
|
|
INVOPCD(), // 0x0018 => MEMSPC
|
|
DEFOPCD("hw_mfpr", Ev4Pr ), // 0x0019 MFPR_OP 0x19 // ALPHA_EV4_PR
|
|
INVOPCD(), // 0x001A => JMP
|
|
DEFOPCD("hw_ld", Ev4Load ), // 0x001B HWLD_OP 0x1B // ALPHA_EV4_MEM
|
|
INVOPCD(), // 0x001C => SEXT
|
|
DEFOPCD("hw_mtpr", Ev4Pr ), // 0x001D MTPR_OP 0x1D // ALPHA_EV4_PR
|
|
DEFOPCD("hw_rei", Ev4Rei ), // 0x001E REI_OP 0x1E // ALPHA_EV4_REI
|
|
DEFOPCD("hw_st", Ev4Store ), // 0x001F HWST_OP 0x1F // ALPHA_EV4_MEM
|
|
DEFOPCD("ldf", LoadFp ), // 0x0020
|
|
DEFOPCD("ldg", LoadFp ), // 0x0021
|
|
DEFOPCD("lds", LoadFp ), // 0x0022
|
|
DEFOPCD("ldt", LoadFp ), // 0x0023
|
|
DEFOPCD("stf", StoreFp ), // 0x0024
|
|
DEFOPCD("stg", StoreFp ), // 0x0025
|
|
DEFOPCD("sts", StoreFp ), // 0x0026
|
|
DEFOPCD("stt", StoreFp ), // 0x0027
|
|
DEFOPCD("ldl", Load ), // 0x0028
|
|
DEFOPCD("ldq", Load ), // 0x0029
|
|
DEFOPCD("ldl_l", Load ), // 0x002A
|
|
DEFOPCD("ldq_l", Load ), // 0x002B
|
|
DEFOPCD("stl", Store ), // 0x002C
|
|
DEFOPCD("stq", Store ), // 0x002D
|
|
DEFOPCD("stl_c", StoreCc ), // 0x002E
|
|
DEFOPCD("stq_c", StoreCc ), // 0x002F
|
|
DEFOPCD("~br", Call ), // 0x0030
|
|
DEFOPCD("fbeq", BraCcFp ), // 0x0031
|
|
DEFOPCD("fblt", BraCcFp ), // 0x0032
|
|
DEFOPCD("fble", BraCcFp ), // 0x0033
|
|
DEFOPCD("bsr", Call ), // 0x0034
|
|
DEFOPCD("fbne", BraCcFp ), // 0x0035
|
|
DEFOPCD("fbge", BraCcFp ), // 0x0036
|
|
DEFOPCD("fbgt", BraCcFp ), // 0x0037
|
|
DEFOPCD("blbc", BraCc ), // 0x0038
|
|
DEFOPCD("beq", BraCc ), // 0x0039
|
|
DEFOPCD("blt", BraCc ), // 0x003A
|
|
DEFOPCD("ble", BraCc ), // 0x003B
|
|
DEFOPCD("blbs", BraCc ), // 0x003C
|
|
DEFOPCD("bne", BraCc ), // 0x003D
|
|
DEFOPCD("bge", BraCc ), // 0x003E
|
|
DEFOPCD("bgt", BraCc ), // 0x003F
|
|
};
|
|
|
|
|
|
// ARITH group identified by bits 11-5 of the instruction
|
|
|
|
const DISAXP::OPCD DISAXP::rgopcdArith[] =
|
|
{
|
|
DEFOPCD("~addl", Reg ), // 0x0000
|
|
INVOPCD(), // 0x0001
|
|
DEFOPCD("s4addl", Reg ), // 0x0002
|
|
INVOPCD(), // 0x0003
|
|
INVOPCD(), // 0x0004
|
|
INVOPCD(), // 0x0005
|
|
INVOPCD(), // 0x0006
|
|
INVOPCD(), // 0x0007
|
|
INVOPCD(), // 0x0008
|
|
DEFOPCD("~subl", Reg ), // 0x0009
|
|
INVOPCD(), // 0x000A
|
|
DEFOPCD("s4subl", Reg ), // 0x000B
|
|
INVOPCD(), // 0x000C
|
|
INVOPCD(), // 0x000D
|
|
INVOPCD(), // 0x000E
|
|
DEFOPCD("cmpbge", Reg ), // 0x000F
|
|
INVOPCD(), // 0x0010
|
|
INVOPCD(), // 0x0011
|
|
DEFOPCD("s8addl", Reg ), // 0x0012
|
|
INVOPCD(), // 0x0013
|
|
INVOPCD(), // 0x0014
|
|
INVOPCD(), // 0x0015
|
|
INVOPCD(), // 0x0016
|
|
INVOPCD(), // 0x0017
|
|
INVOPCD(), // 0x0018
|
|
INVOPCD(), // 0x0019
|
|
INVOPCD(), // 0x001A
|
|
DEFOPCD("s8subl", Reg ), // 0x001B
|
|
INVOPCD(), // 0x001C
|
|
DEFOPCD("cmpult", Reg ), // 0x001D
|
|
INVOPCD(), // 0x001E
|
|
INVOPCD(), // 0x001F
|
|
DEFOPCD("addq", Reg ), // 0x0020
|
|
INVOPCD(), // 0x0021
|
|
DEFOPCD("s4addq", Reg ), // 0x0022
|
|
INVOPCD(), // 0x0023
|
|
INVOPCD(), // 0x0024
|
|
INVOPCD(), // 0x0025
|
|
INVOPCD(), // 0x0026
|
|
INVOPCD(), // 0x0027
|
|
INVOPCD(), // 0x0028
|
|
DEFOPCD("~subq", Reg ), // 0x0029
|
|
INVOPCD(), // 0x002A
|
|
DEFOPCD("s4subq", Reg ), // 0x002B
|
|
INVOPCD(), // 0x002C
|
|
DEFOPCD("cmpeq", Reg ), // 0x002D
|
|
INVOPCD(), // 0x002E
|
|
INVOPCD(), // 0x002F
|
|
INVOPCD(), // 0x0030
|
|
INVOPCD(), // 0x0031
|
|
DEFOPCD("s8addq", Reg ), // 0x0032
|
|
INVOPCD(), // 0x0033
|
|
INVOPCD(), // 0x0034
|
|
INVOPCD(), // 0x0035
|
|
INVOPCD(), // 0x0036
|
|
INVOPCD(), // 0x0037
|
|
INVOPCD(), // 0x0038
|
|
INVOPCD(), // 0x0039
|
|
INVOPCD(), // 0x003A
|
|
DEFOPCD("s8subq", Reg ), // 0x003B
|
|
INVOPCD(), // 0x003C
|
|
DEFOPCD("cmpule", Reg ), // 0x003D
|
|
INVOPCD(), // 0x003E
|
|
INVOPCD(), // 0x003F
|
|
DEFOPCD("addl/v", RegTrap ), // 0x0040
|
|
INVOPCD(), // 0x0041
|
|
INVOPCD(), // 0x0042
|
|
INVOPCD(), // 0x0043
|
|
INVOPCD(), // 0x0044
|
|
INVOPCD(), // 0x0045
|
|
INVOPCD(), // 0x0046
|
|
INVOPCD(), // 0x0047
|
|
INVOPCD(), // 0x0048
|
|
DEFOPCD("~subl/v", RegTrap ), // 0x0049
|
|
INVOPCD(), // 0x004A
|
|
INVOPCD(), // 0x004B
|
|
INVOPCD(), // 0x004C
|
|
DEFOPCD("cmplt", Reg ), // 0x004D
|
|
INVOPCD(), // 0x004E
|
|
INVOPCD(), // 0x004F
|
|
INVOPCD(), // 0x0050
|
|
INVOPCD(), // 0x0051
|
|
INVOPCD(), // 0x0052
|
|
INVOPCD(), // 0x0053
|
|
INVOPCD(), // 0x0054
|
|
INVOPCD(), // 0x0055
|
|
INVOPCD(), // 0x0056
|
|
INVOPCD(), // 0x0057
|
|
INVOPCD(), // 0x0058
|
|
INVOPCD(), // 0x0059
|
|
INVOPCD(), // 0x005A
|
|
INVOPCD(), // 0x005B
|
|
INVOPCD(), // 0x005C
|
|
INVOPCD(), // 0x005D
|
|
INVOPCD(), // 0x005E
|
|
INVOPCD(), // 0x005F
|
|
DEFOPCD("addq/v", RegTrap ), // 0x0060
|
|
INVOPCD(), // 0x0061
|
|
INVOPCD(), // 0x0062
|
|
INVOPCD(), // 0x0063
|
|
INVOPCD(), // 0x0064
|
|
INVOPCD(), // 0x0065
|
|
INVOPCD(), // 0x0066
|
|
INVOPCD(), // 0x0067
|
|
INVOPCD(), // 0x0068
|
|
DEFOPCD("~subq/v", RegTrap ), // 0x0069
|
|
INVOPCD(), // 0x006A
|
|
INVOPCD(), // 0x006B
|
|
INVOPCD(), // 0x006C
|
|
DEFOPCD("cmple", Reg ), // 0x006D
|
|
INVOPCD(), // 0x006E
|
|
INVOPCD(), // 0x006F
|
|
INVOPCD(), // 0x0070
|
|
INVOPCD(), // 0x0071
|
|
INVOPCD(), // 0x0072
|
|
INVOPCD(), // 0x0073
|
|
INVOPCD(), // 0x0074
|
|
INVOPCD(), // 0x0075
|
|
INVOPCD(), // 0x0076
|
|
INVOPCD(), // 0x0077
|
|
INVOPCD(), // 0x0078
|
|
INVOPCD(), // 0x0079
|
|
INVOPCD(), // 0x007A
|
|
INVOPCD(), // 0x007B
|
|
INVOPCD(), // 0x007C
|
|
INVOPCD(), // 0x007D
|
|
INVOPCD(), // 0x007E
|
|
INVOPCD(), // 0x007F
|
|
};
|
|
|
|
|
|
// BIT group identified by bits 11-5 of the instruction
|
|
|
|
const DISAXP::OPCD DISAXP::rgopcdBit[] =
|
|
{
|
|
DEFOPCD("and", Reg ), // 0x0000
|
|
INVOPCD(), // 0x0001
|
|
INVOPCD(), // 0x0002
|
|
INVOPCD(), // 0x0003
|
|
INVOPCD(), // 0x0004
|
|
INVOPCD(), // 0x0005
|
|
INVOPCD(), // 0x0006
|
|
INVOPCD(), // 0x0007
|
|
DEFOPCD("bic", Reg ), // 0x0008
|
|
INVOPCD(), // 0x0009
|
|
INVOPCD(), // 0x000A
|
|
INVOPCD(), // 0x000B
|
|
INVOPCD(), // 0x000C
|
|
INVOPCD(), // 0x000D
|
|
INVOPCD(), // 0x000E
|
|
INVOPCD(), // 0x000F
|
|
INVOPCD(), // 0x0010
|
|
INVOPCD(), // 0x0011
|
|
INVOPCD(), // 0x0012
|
|
INVOPCD(), // 0x0013
|
|
DEFOPCD("cmovlbs", Reg ), // 0x0014
|
|
INVOPCD(), // 0x0015
|
|
DEFOPCD("cmovlbc", Reg ), // 0x0016
|
|
INVOPCD(), // 0x0017
|
|
INVOPCD(), // 0x0018
|
|
INVOPCD(), // 0x0019
|
|
INVOPCD(), // 0x001A
|
|
INVOPCD(), // 0x001B
|
|
INVOPCD(), // 0x001C
|
|
INVOPCD(), // 0x001D
|
|
INVOPCD(), // 0x001E
|
|
INVOPCD(), // 0x001F
|
|
DEFOPCD("~bis", Reg ), // 0x0020
|
|
INVOPCD(), // 0x0021
|
|
INVOPCD(), // 0x0022
|
|
INVOPCD(), // 0x0023
|
|
DEFOPCD("cmoveq", Reg ), // 0x0024
|
|
INVOPCD(), // 0x0025
|
|
DEFOPCD("cmovne", Reg ), // 0x0026
|
|
INVOPCD(), // 0x0027
|
|
DEFOPCD("~ornot", Reg ), // 0x0028
|
|
INVOPCD(), // 0x0029
|
|
INVOPCD(), // 0x002A
|
|
INVOPCD(), // 0x002B
|
|
INVOPCD(), // 0x002C
|
|
INVOPCD(), // 0x002D
|
|
INVOPCD(), // 0x002E
|
|
INVOPCD(), // 0x002F
|
|
INVOPCD(), // 0x0030
|
|
INVOPCD(), // 0x0031
|
|
INVOPCD(), // 0x0032
|
|
INVOPCD(), // 0x0033
|
|
INVOPCD(), // 0x0034
|
|
INVOPCD(), // 0x0035
|
|
INVOPCD(), // 0x0036
|
|
INVOPCD(), // 0x0037
|
|
INVOPCD(), // 0x0038
|
|
INVOPCD(), // 0x0039
|
|
INVOPCD(), // 0x003A
|
|
INVOPCD(), // 0x003B
|
|
INVOPCD(), // 0x003C
|
|
INVOPCD(), // 0x003D
|
|
INVOPCD(), // 0x003E
|
|
INVOPCD(), // 0x003F
|
|
DEFOPCD("xor", Reg ), // 0x0040
|
|
INVOPCD(), // 0x0041
|
|
INVOPCD(), // 0x0042
|
|
INVOPCD(), // 0x0043
|
|
DEFOPCD("cmovlt", Reg ), // 0x0044
|
|
INVOPCD(), // 0x0045
|
|
DEFOPCD("cmovge", Reg ), // 0x0046
|
|
INVOPCD(), // 0x0047
|
|
DEFOPCD("eqv", Reg ), // 0x0048
|
|
INVOPCD(), // 0x0049
|
|
INVOPCD(), // 0x004A
|
|
INVOPCD(), // 0x004B
|
|
INVOPCD(), // 0x004C
|
|
INVOPCD(), // 0x004D
|
|
INVOPCD(), // 0x004E
|
|
INVOPCD(), // 0x004F
|
|
INVOPCD(), // 0x0050
|
|
INVOPCD(), // 0x0051
|
|
INVOPCD(), // 0x0052
|
|
INVOPCD(), // 0x0053
|
|
INVOPCD(), // 0x0054
|
|
INVOPCD(), // 0x0055
|
|
INVOPCD(), // 0x0056
|
|
INVOPCD(), // 0x0057
|
|
INVOPCD(), // 0x0058
|
|
INVOPCD(), // 0x0059
|
|
INVOPCD(), // 0x005A
|
|
INVOPCD(), // 0x005B
|
|
INVOPCD(), // 0x005C
|
|
INVOPCD(), // 0x005D
|
|
INVOPCD(), // 0x005E
|
|
INVOPCD(), // 0x005F
|
|
INVOPCD(), // 0x0060
|
|
INVOPCD(), // 0x0061
|
|
INVOPCD(), // 0x0062
|
|
INVOPCD(), // 0x0063
|
|
DEFOPCD("cmovle", Reg ), // 0x0064
|
|
INVOPCD(), // 0x0065
|
|
DEFOPCD("cmovgt", Reg ), // 0x0066
|
|
INVOPCD(), // 0x0067
|
|
INVOPCD(), // 0x0068
|
|
INVOPCD(), // 0x0069
|
|
INVOPCD(), // 0x006A
|
|
INVOPCD(), // 0x006B
|
|
INVOPCD(), // 0x006C
|
|
INVOPCD(), // 0x006D
|
|
INVOPCD(), // 0x006E
|
|
INVOPCD(), // 0x006F
|
|
INVOPCD(), // 0x0070
|
|
INVOPCD(), // 0x0071
|
|
INVOPCD(), // 0x0072
|
|
INVOPCD(), // 0x0073
|
|
INVOPCD(), // 0x0074
|
|
INVOPCD(), // 0x0075
|
|
INVOPCD(), // 0x0076
|
|
INVOPCD(), // 0x0077
|
|
INVOPCD(), // 0x0078
|
|
INVOPCD(), // 0x0079
|
|
INVOPCD(), // 0x007A
|
|
INVOPCD(), // 0x007B
|
|
INVOPCD(), // 0x007C
|
|
INVOPCD(), // 0x007D
|
|
INVOPCD(), // 0x007E
|
|
INVOPCD(), // 0x007F
|
|
};
|
|
|
|
|
|
// BYTE group identified by bits 11-5 of the instruction
|
|
|
|
const DISAXP::OPCD DISAXP::rgopcdByte[] =
|
|
{
|
|
INVOPCD(), // 0x0000
|
|
INVOPCD(), // 0x0001
|
|
DEFOPCD("mskbl", Reg ), // 0x0002
|
|
INVOPCD(), // 0x0003
|
|
INVOPCD(), // 0x0004
|
|
INVOPCD(), // 0x0005
|
|
DEFOPCD("extbl", Reg ), // 0x0006
|
|
INVOPCD(), // 0x0007
|
|
INVOPCD(), // 0x0008
|
|
INVOPCD(), // 0x0009
|
|
INVOPCD(), // 0x000A
|
|
DEFOPCD("insbl", Reg ), // 0x000B
|
|
INVOPCD(), // 0x000C
|
|
INVOPCD(), // 0x000D
|
|
INVOPCD(), // 0x000E
|
|
INVOPCD(), // 0x000F
|
|
INVOPCD(), // 0x0010
|
|
INVOPCD(), // 0x0011
|
|
DEFOPCD("mskwl", Reg ), // 0x0012
|
|
INVOPCD(), // 0x0013
|
|
INVOPCD(), // 0x0014
|
|
INVOPCD(), // 0x0015
|
|
DEFOPCD("extwl", Reg ), // 0x0016
|
|
INVOPCD(), // 0x0017
|
|
INVOPCD(), // 0x0018
|
|
INVOPCD(), // 0x0019
|
|
INVOPCD(), // 0x001A
|
|
DEFOPCD("inswl", Reg ), // 0x001B
|
|
INVOPCD(), // 0x001C
|
|
INVOPCD(), // 0x001D
|
|
INVOPCD(), // 0x001E
|
|
INVOPCD(), // 0x001F
|
|
INVOPCD(), // 0x0020
|
|
INVOPCD(), // 0x0021
|
|
DEFOPCD("mskll", Reg ), // 0x0022
|
|
INVOPCD(), // 0x0023
|
|
INVOPCD(), // 0x0024
|
|
INVOPCD(), // 0x0025
|
|
DEFOPCD("extll", Reg ), // 0x0026
|
|
INVOPCD(), // 0x0027
|
|
INVOPCD(), // 0x0028
|
|
INVOPCD(), // 0x0029
|
|
INVOPCD(), // 0x002A
|
|
DEFOPCD("insll", Reg ), // 0x002B
|
|
INVOPCD(), // 0x002C
|
|
INVOPCD(), // 0x002D
|
|
INVOPCD(), // 0x002E
|
|
INVOPCD(), // 0x002F
|
|
DEFOPCD("zap", Reg ), // 0x0030
|
|
DEFOPCD("zapnot", Reg ), // 0x0031
|
|
DEFOPCD("mskql", Reg ), // 0x0032
|
|
INVOPCD(), // 0x0033
|
|
DEFOPCD("srl", Reg ), // 0x0034
|
|
INVOPCD(), // 0x0035
|
|
DEFOPCD("extql", Reg ), // 0x0036
|
|
INVOPCD(), // 0x0037
|
|
INVOPCD(), // 0x0038
|
|
DEFOPCD("sll", Reg ), // 0x0039
|
|
INVOPCD(), // 0x003A
|
|
DEFOPCD("insql", Reg ), // 0x003B
|
|
DEFOPCD("sra", Reg ), // 0x003C
|
|
INVOPCD(), // 0x003D
|
|
INVOPCD(), // 0x003E
|
|
INVOPCD(), // 0x003F
|
|
INVOPCD(), // 0x0040
|
|
INVOPCD(), // 0x0041
|
|
INVOPCD(), // 0x0042
|
|
INVOPCD(), // 0x0043
|
|
INVOPCD(), // 0x0044
|
|
INVOPCD(), // 0x0045
|
|
INVOPCD(), // 0x0046
|
|
INVOPCD(), // 0x0047
|
|
INVOPCD(), // 0x0048
|
|
INVOPCD(), // 0x0049
|
|
INVOPCD(), // 0x004A
|
|
INVOPCD(), // 0x004B
|
|
INVOPCD(), // 0x004C
|
|
INVOPCD(), // 0x004D
|
|
INVOPCD(), // 0x004E
|
|
INVOPCD(), // 0x004F
|
|
INVOPCD(), // 0x0050
|
|
INVOPCD(), // 0x0051
|
|
DEFOPCD("mskwh", Reg ), // 0x0052
|
|
INVOPCD(), // 0x0053
|
|
INVOPCD(), // 0x0054
|
|
INVOPCD(), // 0x0055
|
|
INVOPCD(), // 0x0056
|
|
DEFOPCD("inswh", Reg ), // 0x0057
|
|
INVOPCD(), // 0x0058
|
|
INVOPCD(), // 0x0059
|
|
DEFOPCD("extwh", Reg ), // 0x005A
|
|
INVOPCD(), // 0x005B
|
|
INVOPCD(), // 0x005C
|
|
INVOPCD(), // 0x005D
|
|
INVOPCD(), // 0x005E
|
|
INVOPCD(), // 0x005F
|
|
INVOPCD(), // 0x0060
|
|
INVOPCD(), // 0x0061
|
|
DEFOPCD("msklh", Reg ), // 0x0062
|
|
INVOPCD(), // 0x0063
|
|
INVOPCD(), // 0x0064
|
|
INVOPCD(), // 0x0065
|
|
INVOPCD(), // 0x0066
|
|
DEFOPCD("inslh", Reg ), // 0x0067
|
|
INVOPCD(), // 0x0068
|
|
INVOPCD(), // 0x0069
|
|
DEFOPCD("extlh", Reg ), // 0x006A
|
|
INVOPCD(), // 0x006B
|
|
INVOPCD(), // 0x006C
|
|
INVOPCD(), // 0x006D
|
|
INVOPCD(), // 0x006E
|
|
INVOPCD(), // 0x006F
|
|
INVOPCD(), // 0x0070
|
|
INVOPCD(), // 0x0071
|
|
DEFOPCD("mskqh", Reg ), // 0x0072
|
|
INVOPCD(), // 0x0073
|
|
INVOPCD(), // 0x0074
|
|
INVOPCD(), // 0x0075
|
|
INVOPCD(), // 0x0076
|
|
DEFOPCD("insqh", Reg ), // 0x0077
|
|
INVOPCD(), // 0x0078
|
|
INVOPCD(), // 0x0079
|
|
DEFOPCD("extqh", Reg ), // 0x007A
|
|
INVOPCD(), // 0x007B
|
|
INVOPCD(), // 0x007C
|
|
INVOPCD(), // 0x007D
|
|
INVOPCD(), // 0x007E
|
|
INVOPCD(), // 0x007F
|
|
};
|
|
|
|
|
|
// MUL group identified by bits 11-5 of the instruction
|
|
|
|
const DISAXP::OPCD DISAXP::rgopcdMul[] =
|
|
{
|
|
DEFOPCD("mull", Reg ), // 0x0000
|
|
INVOPCD(), // 0x0001
|
|
INVOPCD(), // 0x0002
|
|
INVOPCD(), // 0x0003
|
|
INVOPCD(), // 0x0004
|
|
INVOPCD(), // 0x0005
|
|
INVOPCD(), // 0x0006
|
|
INVOPCD(), // 0x0007
|
|
INVOPCD(), // 0x0008
|
|
INVOPCD(), // 0x0009
|
|
INVOPCD(), // 0x000A
|
|
INVOPCD(), // 0x000B
|
|
INVOPCD(), // 0x000C
|
|
INVOPCD(), // 0x000D
|
|
INVOPCD(), // 0x000E
|
|
INVOPCD(), // 0x000F
|
|
INVOPCD(), // 0x0010
|
|
INVOPCD(), // 0x0011
|
|
INVOPCD(), // 0x0012
|
|
INVOPCD(), // 0x0013
|
|
INVOPCD(), // 0x0014
|
|
INVOPCD(), // 0x0015
|
|
INVOPCD(), // 0x0016
|
|
INVOPCD(), // 0x0017
|
|
INVOPCD(), // 0x0018
|
|
INVOPCD(), // 0x0019
|
|
INVOPCD(), // 0x001A
|
|
INVOPCD(), // 0x001B
|
|
INVOPCD(), // 0x001C
|
|
INVOPCD(), // 0x001D
|
|
INVOPCD(), // 0x001E
|
|
INVOPCD(), // 0x001F
|
|
DEFOPCD("mulq", Reg ), // 0x0020
|
|
INVOPCD(), // 0x0021
|
|
INVOPCD(), // 0x0022
|
|
INVOPCD(), // 0x0023
|
|
INVOPCD(), // 0x0024
|
|
INVOPCD(), // 0x0025
|
|
INVOPCD(), // 0x0026
|
|
INVOPCD(), // 0x0027
|
|
INVOPCD(), // 0x0028
|
|
INVOPCD(), // 0x0029
|
|
INVOPCD(), // 0x002A
|
|
INVOPCD(), // 0x002B
|
|
INVOPCD(), // 0x002C
|
|
INVOPCD(), // 0x002D
|
|
INVOPCD(), // 0x002E
|
|
INVOPCD(), // 0x002F
|
|
DEFOPCD("umulh", Reg ), // 0x0030
|
|
INVOPCD(), // 0x0031
|
|
INVOPCD(), // 0x0032
|
|
INVOPCD(), // 0x0033
|
|
INVOPCD(), // 0x0034
|
|
INVOPCD(), // 0x0035
|
|
INVOPCD(), // 0x0036
|
|
INVOPCD(), // 0x0037
|
|
INVOPCD(), // 0x0038
|
|
INVOPCD(), // 0x0039
|
|
INVOPCD(), // 0x003A
|
|
INVOPCD(), // 0x003B
|
|
INVOPCD(), // 0x003C
|
|
INVOPCD(), // 0x003D
|
|
INVOPCD(), // 0x003E
|
|
INVOPCD(), // 0x003F
|
|
DEFOPCD("mull/v", RegTrap ), // 0x0040
|
|
INVOPCD(), // 0x0041
|
|
INVOPCD(), // 0x0042
|
|
INVOPCD(), // 0x0043
|
|
INVOPCD(), // 0x0044
|
|
INVOPCD(), // 0x0045
|
|
INVOPCD(), // 0x0046
|
|
INVOPCD(), // 0x0047
|
|
INVOPCD(), // 0x0048
|
|
INVOPCD(), // 0x0049
|
|
INVOPCD(), // 0x004A
|
|
INVOPCD(), // 0x004B
|
|
INVOPCD(), // 0x004C
|
|
INVOPCD(), // 0x004D
|
|
INVOPCD(), // 0x004E
|
|
INVOPCD(), // 0x004F
|
|
INVOPCD(), // 0x0050
|
|
INVOPCD(), // 0x0051
|
|
INVOPCD(), // 0x0052
|
|
INVOPCD(), // 0x0053
|
|
INVOPCD(), // 0x0054
|
|
INVOPCD(), // 0x0055
|
|
INVOPCD(), // 0x0056
|
|
INVOPCD(), // 0x0057
|
|
INVOPCD(), // 0x0058
|
|
INVOPCD(), // 0x0059
|
|
INVOPCD(), // 0x005A
|
|
INVOPCD(), // 0x005B
|
|
INVOPCD(), // 0x005C
|
|
INVOPCD(), // 0x005D
|
|
INVOPCD(), // 0x005E
|
|
INVOPCD(), // 0x005F
|
|
DEFOPCD("mulq/v", RegTrap ), // 0x0060
|
|
INVOPCD(), // 0x0061
|
|
INVOPCD(), // 0x0062
|
|
INVOPCD(), // 0x0063
|
|
INVOPCD(), // 0x0064
|
|
INVOPCD(), // 0x0065
|
|
INVOPCD(), // 0x0066
|
|
INVOPCD(), // 0x0067
|
|
INVOPCD(), // 0x0068
|
|
INVOPCD(), // 0x0069
|
|
INVOPCD(), // 0x006A
|
|
INVOPCD(), // 0x006B
|
|
INVOPCD(), // 0x006C
|
|
INVOPCD(), // 0x006D
|
|
INVOPCD(), // 0x006E
|
|
INVOPCD(), // 0x006F
|
|
INVOPCD(), // 0x0070
|
|
INVOPCD(), // 0x0071
|
|
INVOPCD(), // 0x0072
|
|
INVOPCD(), // 0x0073
|
|
INVOPCD(), // 0x0074
|
|
INVOPCD(), // 0x0075
|
|
INVOPCD(), // 0x0076
|
|
INVOPCD(), // 0x0077
|
|
INVOPCD(), // 0x0078
|
|
INVOPCD(), // 0x0079
|
|
INVOPCD(), // 0x007A
|
|
INVOPCD(), // 0x007B
|
|
INVOPCD(), // 0x007C
|
|
INVOPCD(), // 0x007D
|
|
INVOPCD(), // 0x007E
|
|
INVOPCD(), // 0x007F
|
|
};
|
|
|
|
|
|
// VAXFP group identified by bits 10-5 of the instruction
|
|
|
|
const DISAXP::OPCD DISAXP::rgopcdVax[] =
|
|
{
|
|
DEFOPCD("addf", RegFp5 ), // 0x0000
|
|
DEFOPCD("~subf", RegFp5 ), // 0x0001
|
|
DEFOPCD("mulf", RegFp5 ), // 0x0002
|
|
DEFOPCD("divf", RegFp5 ), // 0x0003
|
|
INVOPCD(), // 0x0004
|
|
INVOPCD(), // 0x0005
|
|
INVOPCD(), // 0x0006
|
|
INVOPCD(), // 0x0007
|
|
INVOPCD(), // 0x0008
|
|
INVOPCD(), // 0x0009
|
|
INVOPCD(), // 0x000A
|
|
INVOPCD(), // 0x000B
|
|
INVOPCD(), // 0x000C
|
|
INVOPCD(), // 0x000D
|
|
DEFOPCD("cvtfg", Reg2Fp6 ), // 0x000E *
|
|
INVOPCD(), // 0x000F
|
|
DEFOPCD("addd", RegFp5 ), // 0x0010 *
|
|
DEFOPCD("subd", RegFp5 ), // 0x0011 *
|
|
DEFOPCD("muld", RegFp5 ), // 0x0012 *
|
|
DEFOPCD("divd", RegFp5 ), // 0x0013 *
|
|
INVOPCD(), // 0x0014
|
|
DEFOPCD("cmpdeq", RegFp2 ), // 0x0015 *
|
|
DEFOPCD("cmpdlt", RegFp2 ), // 0x0016 *
|
|
DEFOPCD("cmpdle", RegFp2 ), // 0x0017 *
|
|
INVOPCD(), // 0x0018
|
|
INVOPCD(), // 0x0019
|
|
INVOPCD(), // 0x001A
|
|
INVOPCD(), // 0x001B
|
|
DEFOPCD("cvtdf", Reg2Fp6 ), // 0x001C *
|
|
INVOPCD(), // 0x001D
|
|
DEFOPCD("cvtdg", Reg2Fp6 ), // 0x001E
|
|
DEFOPCD("cvtdq", Reg2Fp7 ), // 0x001F *
|
|
DEFOPCD("addg", RegFp5 ), // 0x0020
|
|
DEFOPCD("~subg", RegFp5 ), // 0x0021
|
|
DEFOPCD("mulg", RegFp5 ), // 0x0022
|
|
DEFOPCD("divg", RegFp5 ), // 0x0023
|
|
INVOPCD(), // 0x0024
|
|
DEFOPCD("cmpgeq", RegFp2 ), // 0x0025
|
|
DEFOPCD("cmpglt", RegFp2 ), // 0x0026
|
|
DEFOPCD("cmpgle", RegFp2 ), // 0x0027
|
|
INVOPCD(), // 0x0028
|
|
INVOPCD(), // 0x0029
|
|
INVOPCD(), // 0x002A
|
|
INVOPCD(), // 0x002B
|
|
DEFOPCD("cvtgf", Reg2Fp6 ), // 0x002C
|
|
DEFOPCD("cvtgd", Reg2Fp6 ), // 0x002D
|
|
INVOPCD(), // 0x002E
|
|
DEFOPCD("cvtgq", Reg2Fp7 ), // 0x002F
|
|
INVOPCD(), // 0x0030
|
|
INVOPCD(), // 0x0031
|
|
INVOPCD(), // 0x0032
|
|
INVOPCD(), // 0x0033
|
|
INVOPCD(), // 0x0034
|
|
INVOPCD(), // 0x0035
|
|
INVOPCD(), // 0x0036
|
|
INVOPCD(), // 0x0037
|
|
INVOPCD(), // 0x0038
|
|
INVOPCD(), // 0x0039
|
|
INVOPCD(), // 0x003A
|
|
INVOPCD(), // 0x003B
|
|
DEFOPCD("cvtqf", Reg2Fp6 ), // 0x003C
|
|
DEFOPCD("cvtqd", Reg2Fp6 ), // 0x003D *
|
|
DEFOPCD("cvtqg", Reg2Fp6 ), // 0x003E
|
|
INVOPCD(), // 0x003F
|
|
};
|
|
|
|
|
|
// IEEEFP group identified by bits 10-5 of the instruction
|
|
|
|
const DISAXP::OPCD DISAXP::rgopcdIEEE[] =
|
|
{
|
|
DEFOPCD("adds", RegFp1 ), // 0x0000
|
|
DEFOPCD("~subs", RegFp1 ), // 0x0001
|
|
DEFOPCD("muls", RegFp1 ), // 0x0002
|
|
DEFOPCD("divs", RegFp1 ), // 0x0003
|
|
DEFOPCD("cmpsun", RegFp2 ), // 0x0004 *
|
|
DEFOPCD("cmpseq", RegFp2 ), // 0x0005 *
|
|
DEFOPCD("cmpslt", RegFp2 ), // 0x0006 *
|
|
DEFOPCD("cmpsle", RegFp2 ), // 0x0007 *
|
|
INVOPCD(), // 0x0008
|
|
INVOPCD(), // 0x0009
|
|
INVOPCD(), // 0x000A
|
|
INVOPCD(), // 0x000B
|
|
INVOPCD(), // 0x000C
|
|
INVOPCD(), // 0x000D
|
|
DEFOPCD("cvtst", Reg2Fp1 ), // 0x000E *
|
|
DEFOPCD("cvtsq", Reg2Fp4 ), // 0x000F *
|
|
INVOPCD(), // 0x0010
|
|
INVOPCD(), // 0x0011
|
|
INVOPCD(), // 0x0012
|
|
INVOPCD(), // 0x0013
|
|
INVOPCD(), // 0x0014
|
|
INVOPCD(), // 0x0015
|
|
INVOPCD(), // 0x0016
|
|
INVOPCD(), // 0x0017
|
|
INVOPCD(), // 0x0018
|
|
INVOPCD(), // 0x0019
|
|
INVOPCD(), // 0x001A
|
|
INVOPCD(), // 0x001B
|
|
INVOPCD(), // 0x001C
|
|
INVOPCD(), // 0x001D
|
|
INVOPCD(), // 0x001E
|
|
INVOPCD(), // 0x001F
|
|
DEFOPCD("addt", RegFp1 ), // 0x0020
|
|
DEFOPCD("~subt", RegFp1 ), // 0x0021
|
|
DEFOPCD("mult", RegFp1 ), // 0x0022
|
|
DEFOPCD("divt", RegFp1 ), // 0x0023
|
|
DEFOPCD("cmptun", RegFp2 ), // 0x0024
|
|
DEFOPCD("cmpteq", RegFp2 ), // 0x0025
|
|
DEFOPCD("cmptlt", RegFp2 ), // 0x0026
|
|
DEFOPCD("cmptle", RegFp2 ), // 0x0027
|
|
INVOPCD(), // 0x0028
|
|
INVOPCD(), // 0x0029
|
|
INVOPCD(), // 0x002A
|
|
INVOPCD(), // 0x002B
|
|
DEFOPCD("cvtts", Reg2Fp1 ), // 0x002C
|
|
INVOPCD(), // 0x002D
|
|
INVOPCD(), // 0x002E
|
|
DEFOPCD("cvttq", Reg2Fp4 ), // 0x002F
|
|
INVOPCD(), // 0x0030
|
|
INVOPCD(), // 0x0031
|
|
INVOPCD(), // 0x0032
|
|
INVOPCD(), // 0x0033
|
|
INVOPCD(), // 0x0034
|
|
INVOPCD(), // 0x0035
|
|
INVOPCD(), // 0x0036
|
|
INVOPCD(), // 0x0037
|
|
INVOPCD(), // 0x0038
|
|
INVOPCD(), // 0x0039
|
|
INVOPCD(), // 0x003A
|
|
INVOPCD(), // 0x003B
|
|
DEFOPCD("cvtqs", Reg2Fp3 ), // 0x003C
|
|
INVOPCD(), // 0x003D
|
|
DEFOPCD("cvtqt", Reg2Fp3 ), // 0x003E
|
|
INVOPCD(), // 0x003F
|
|
};
|
|
|
|
|
|
// FPOP group identified by bits 10-5 of the instruction
|
|
|
|
const DISAXP::OPCD DISAXP::rgopcdFP[] =
|
|
{
|
|
INVOPCD(), // 0x0000
|
|
INVOPCD(), // 0x0001
|
|
INVOPCD(), // 0x0002
|
|
DEFOPCD("cpysee", RegFp ), // 0x0003 *
|
|
INVOPCD(), // 0x0004
|
|
INVOPCD(), // 0x0005
|
|
INVOPCD(), // 0x0006
|
|
INVOPCD(), // 0x0007
|
|
INVOPCD(), // 0x0008
|
|
INVOPCD(), // 0x0009
|
|
INVOPCD(), // 0x000A
|
|
INVOPCD(), // 0x000B
|
|
INVOPCD(), // 0x000C
|
|
INVOPCD(), // 0x000D
|
|
INVOPCD(), // 0x000E
|
|
INVOPCD(), // 0x000F
|
|
DEFOPCD("cvtlq", Reg2Fp ), // 0x0010
|
|
INVOPCD(), // 0x0011
|
|
INVOPCD(), // 0x0012
|
|
INVOPCD(), // 0x0013
|
|
INVOPCD(), // 0x0014
|
|
INVOPCD(), // 0x0015
|
|
INVOPCD(), // 0x0016
|
|
INVOPCD(), // 0x0017
|
|
INVOPCD(), // 0x0018
|
|
INVOPCD(), // 0x0019
|
|
INVOPCD(), // 0x001A
|
|
INVOPCD(), // 0x001B
|
|
INVOPCD(), // 0x001C
|
|
INVOPCD(), // 0x001D
|
|
INVOPCD(), // 0x001E
|
|
INVOPCD(), // 0x001F
|
|
DEFOPCD("~cpys", RegFp ), // 0x0020
|
|
DEFOPCD("~cpysn", RegFp ), // 0x0021
|
|
DEFOPCD("cpyse", RegFp ), // 0x0022
|
|
INVOPCD(), // 0x0023
|
|
DEFOPCD("~mt_fpcr", Fpcr ), // 0x0024
|
|
DEFOPCD("~mf_fpcr", Fpcr ), // 0x0025
|
|
INVOPCD(), // 0x0026
|
|
INVOPCD(), // 0x0027
|
|
INVOPCD(), // 0x0028
|
|
INVOPCD(), // 0x0029
|
|
DEFOPCD("fcmoveq", RegFp ), // 0x002A
|
|
DEFOPCD("fcmovne", RegFp ), // 0x002B
|
|
DEFOPCD("fcmovlt", RegFp ), // 0x002C
|
|
DEFOPCD("fcmovge", RegFp ), // 0x002D
|
|
DEFOPCD("fcmovle", RegFp ), // 0x002E
|
|
DEFOPCD("fcmovgt", RegFp ), // 0x002F
|
|
DEFOPCD("cvtql", Cvtql ), // 0x0030
|
|
INVOPCD(), // 0x0031
|
|
INVOPCD(), // 0x0032
|
|
INVOPCD(), // 0x0033
|
|
INVOPCD(), // 0x0034
|
|
INVOPCD(), // 0x0035
|
|
INVOPCD(), // 0x0036
|
|
INVOPCD(), // 0x0037
|
|
INVOPCD(), // 0x0038
|
|
INVOPCD(), // 0x0039
|
|
INVOPCD(), // 0x003A
|
|
INVOPCD(), // 0x003B
|
|
INVOPCD(), // 0x003C
|
|
INVOPCD(), // 0x003D
|
|
INVOPCD(), // 0x003E
|
|
INVOPCD(), // 0x003F
|
|
};
|
|
|
|
|
|
// MEMSPC group identified by bits 15-0 of the instruction
|
|
|
|
const DISAXP::OPCD DISAXP::rgopcdMemSpc[] =
|
|
{
|
|
DEFOPCD("trapb", None ), // 0x0000
|
|
DEFOPCD("?????", None ), // 0x0400 UNDONE: Unidentified instruction
|
|
INVOPCD(), // 0x0800
|
|
INVOPCD(), // 0x0C00
|
|
INVOPCD(), // 0x1000
|
|
INVOPCD(), // 0x1400
|
|
INVOPCD(), // 0x1800
|
|
INVOPCD(), // 0x1C00
|
|
INVOPCD(), // 0x2000
|
|
INVOPCD(), // 0x2400
|
|
INVOPCD(), // 0x2800
|
|
INVOPCD(), // 0x2C00
|
|
INVOPCD(), // 0x3000
|
|
INVOPCD(), // 0x3400
|
|
INVOPCD(), // 0x3800
|
|
INVOPCD(), // 0x3C00
|
|
DEFOPCD("mb", None ), // 0x4000
|
|
DEFOPCD("mb1", None ), // 0x4400
|
|
DEFOPCD("mb2", None ), // 0x4800
|
|
DEFOPCD("mb3", None ), // 0x4C00
|
|
INVOPCD(), // 0x5000
|
|
INVOPCD(), // 0x5400
|
|
INVOPCD(), // 0x5800
|
|
INVOPCD(), // 0x5C00
|
|
INVOPCD(), // 0x6000
|
|
INVOPCD(), // 0x6400
|
|
INVOPCD(), // 0x6800
|
|
INVOPCD(), // 0x6C00
|
|
INVOPCD(), // 0x7000
|
|
INVOPCD(), // 0x7400
|
|
INVOPCD(), // 0x7800
|
|
INVOPCD(), // 0x7C00
|
|
DEFOPCD("fetch", Fetch ), // 0x8000
|
|
INVOPCD(), // 0x8400
|
|
INVOPCD(), // 0x8800
|
|
INVOPCD(), // 0x8C00
|
|
INVOPCD(), // 0x9000
|
|
INVOPCD(), // 0x9400
|
|
INVOPCD(), // 0x9800
|
|
INVOPCD(), // 0x9C00
|
|
DEFOPCD("fetch_m", Fetch ), // 0xA000
|
|
INVOPCD(), // 0xA400
|
|
INVOPCD(), // 0xA800
|
|
INVOPCD(), // 0xAC00
|
|
INVOPCD(), // 0xB000
|
|
INVOPCD(), // 0xB400
|
|
INVOPCD(), // 0xB800
|
|
INVOPCD(), // 0xBC00
|
|
DEFOPCD("rpcc", Ra_w ), // 0xC000
|
|
INVOPCD(), // 0xC400
|
|
INVOPCD(), // 0xC800
|
|
INVOPCD(), // 0xCC00
|
|
INVOPCD(), // 0xD000
|
|
INVOPCD(), // 0xD400
|
|
INVOPCD(), // 0xD800
|
|
INVOPCD(), // 0xDC00
|
|
DEFOPCD("rc", Ra_w ), // 0xE000
|
|
INVOPCD(), // 0xE400
|
|
INVOPCD(), // 0xE800
|
|
INVOPCD(), // 0xEC00
|
|
DEFOPCD("rs", Ra_w ), // 0xF000
|
|
INVOPCD(), // 0xF400
|
|
INVOPCD(), // 0xF800
|
|
INVOPCD(), // 0xFC00
|
|
};
|
|
|
|
|
|
// JMP group identified by bits 15-14 of the instruction
|
|
|
|
const DISAXP::OPCD DISAXP::rgopcdJump[] =
|
|
{
|
|
DEFOPCD("jmp", Jmp ), // 0x0000
|
|
DEFOPCD("jsr", Jmp ), // 0x0001
|
|
DEFOPCD("~ret", Jmp ), // 0x0002
|
|
DEFOPCD("~jsr_coroutine", Jmp ), // 0x0003
|
|
};
|
|
|
|
|
|
// SEXT group identified by bits 11-5 of the instruction
|
|
|
|
const DISAXP::OPCD DISAXP::rgopcdSext[] =
|
|
{
|
|
DEFOPCD("sextb", Reg2 ), // 0x0000
|
|
DEFOPCD("sextw", Reg2 ), // 0x0001
|
|
};
|
|
|
|
|
|
// The following are pseudo-ops
|
|
|
|
const DISAXP::OPCD DISAXP::opcdBr_ =
|
|
DEFOPCD("br", Bra );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdClr =
|
|
DEFOPCD("clr", Reg1 );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdFabs =
|
|
DEFOPCD("fabs", Reg2Fp );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdFclr =
|
|
DEFOPCD("fclr", Reg1Fp );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdFmov =
|
|
DEFOPCD("fmov", Reg2Fp );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdFneg =
|
|
DEFOPCD("fneg", Reg2Fp );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdFnop =
|
|
DEFOPCD("fnop", None );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdMf_Fpcr =
|
|
DEFOPCD("mf_fpcr", Reg1Fp );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdMov1 =
|
|
DEFOPCD("mov", Reg2 );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdMov2 =
|
|
DEFOPCD("mov", Mov );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdMt_Fpcr =
|
|
DEFOPCD("mt_fpcr", Reg1Fp );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdNegf =
|
|
DEFOPCD("negf", Reg2Fp1 );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdNegg =
|
|
DEFOPCD("negg", Reg2Fp1 );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdNegl =
|
|
DEFOPCD("negl", Reg2 );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdNegl_V =
|
|
DEFOPCD("negl/v", Reg2Trap );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdNegq =
|
|
DEFOPCD("negq", Reg2Trap );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdNegq_V =
|
|
DEFOPCD("negq/v", Reg2 );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdNegs =
|
|
DEFOPCD("negs", Reg2Fp1 );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdNegt =
|
|
DEFOPCD("negt", Reg2Fp1 );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdNop =
|
|
DEFOPCD("nop", None );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdNot =
|
|
DEFOPCD("not", Reg2 );
|
|
|
|
const DISAXP::OPCD DISAXP::opcdSextl =
|
|
DEFOPCD("sextl", Reg2 );
|
|
|
|
|
|
|
|
// The following applies to ADDS, ADDT, CVTTS, DIVS, DIVT, MULS, MULT, SUBS, SUBT
|
|
|
|
const DWORD DISAXP::dwValidQualifier1 = 0xF0F000FF;
|
|
|
|
// The following applies to CMPSEQ, CMPSLT, CMPSLE, CMPSUN
|
|
// The following applies to CMPTEQ, CMPTLT, CMPTLE, CMPTUN
|
|
// The following applies to CMPGEQ, CMPGLT, CMPGLE
|
|
|
|
const DWORD DISAXP::dwValidQualifier2 = 0x00400004;
|
|
|
|
// The following applies to CVTQS, CVTQT
|
|
|
|
const DWORD DISAXP::dwValidQualifier3 = 0xF000000F;
|
|
|
|
// The following applies to CVTTQ
|
|
|
|
const DWORD DISAXP::dwValidQualifier4 = 0xF0F000FF;
|
|
|
|
// The following applies to ADDF, CVTDG, ADDG, CVTGF, CVTGD, DIVF, DIVG, MULF, MULG, SUBF, SUBG
|
|
|
|
const DWORD DISAXP::dwValidQualifier5 = 0x00550055;
|
|
|
|
// The following applies to CVTQF, CVTQG
|
|
|
|
const DWORD DISAXP::dwValidQualifier6 = 0x00000005;
|
|
|
|
// The following applies to CVTGQ
|
|
|
|
const DWORD DISAXP::dwValidQualifier7 = 0x00550055;
|
|
|
|
// The following applies to CVTQL
|
|
|
|
const DWORD DISAXP::dwValidQualifier8 = 0x00100011;
|
|
|
|
|
|
const char DISAXP::rgszQualifier1[32][8] =
|
|
{
|
|
"/c", // 000
|
|
"/m", // 040
|
|
"", // 080
|
|
"/d", // 0C0
|
|
"/uc", // 100
|
|
"/um", // 140
|
|
"/u", // 180
|
|
"/ud", // 1C0
|
|
"*******", // 200
|
|
"*******", // 240
|
|
"*******", // 280
|
|
"*******", // 2C0
|
|
"*******", // 300
|
|
"*******", // 340
|
|
"*******", // 380
|
|
"*******", // 3C0
|
|
"/sc", // 400
|
|
"*******", // 440
|
|
"/s", // 480
|
|
"*******", // 4C0
|
|
"/suc", // 500
|
|
"/sum", // 540
|
|
"/su", // 580
|
|
"/sud", // 5C0
|
|
"*******", // 600
|
|
"*******", // 640
|
|
"*******", // 680
|
|
"*******", // 6C0
|
|
"/suic", // 700
|
|
"/suim", // 740
|
|
"/sui", // 780
|
|
"/suid", // 7C0
|
|
};
|
|
|
|
|
|
const char DISAXP::rgszQualifier2[32][8] =
|
|
{
|
|
"/c", // 000
|
|
"/m", // 040
|
|
"", // 080
|
|
"/d", // 0C0
|
|
"/vc", // 100
|
|
"/vm", // 140
|
|
"/v", // 180
|
|
"/vd", // 1C0
|
|
"*******", // 200
|
|
"*******", // 240
|
|
"*******", // 280
|
|
"*******", // 2C0
|
|
"*******", // 300
|
|
"*******", // 340
|
|
"*******", // 380
|
|
"*******", // 3C0
|
|
"/sc", // 400
|
|
"*******", // 440
|
|
"/s", // 480
|
|
"*******", // 4C0
|
|
"/svc", // 500
|
|
"/svm", // 540
|
|
"/sv", // 580
|
|
"/svd", // 5C0
|
|
"*******", // 600
|
|
"*******", // 640
|
|
"*******", // 680
|
|
"*******", // 6C0
|
|
"/svic", // 700
|
|
"/svim", // 740
|
|
"/svi", // 780
|
|
"/svid", // 7C0
|
|
};
|
|
|
|
|
|
const DISAXP::PALMAP DISAXP::rgpalmap[] =
|
|
{
|
|
// The following PAL operations are privileged
|
|
|
|
{ palopHalt, "halt" },
|
|
{ palopRestart, "restart" },
|
|
{ palopDraina, "draina" },
|
|
{ palopReboot, "reboot" },
|
|
{ palopInitpal, "initpal" },
|
|
{ palopWrentry, "wrentry" },
|
|
{ palopSwpirql, "swpirql" },
|
|
{ palopRdirql, "rdirql" },
|
|
{ palopDi, "di" },
|
|
{ palopEi, "ei" },
|
|
{ palopSwppal, "swppal" },
|
|
{ palopSsir, "ssir" },
|
|
{ palopCsir, "csir" },
|
|
{ palopRfe, "rfe" },
|
|
{ palopRetsys, "retsys" },
|
|
{ palopSwpctx, "swpctx" },
|
|
{ palopSwpprocess, "swpprocess" },
|
|
{ palopRdmces, "rdmces" },
|
|
{ palopWrmces, "wrmces" },
|
|
{ palopTbia, "tbia" },
|
|
{ palopTbis, "tbis" },
|
|
{ palopDtbis, "dtbis" },
|
|
{ palopTbisasn, "tbisasn" },
|
|
{ palopRdksp, "rdksp" },
|
|
{ palopSwpksp, "swpksp" },
|
|
{ palopRdpsr, "rdpsr" },
|
|
{ palopRdpcr, "rdpcr" },
|
|
{ palopRdthread, "rdthread" },
|
|
{ palopTbim, "tbim" },
|
|
{ palopTbimasn, "tbimasn" },
|
|
{ palopRdcounters, "rdcounters" },
|
|
{ palopRdstate, "rdstate" },
|
|
{ palopWrperfmon, "wrperfmon" },
|
|
{ palopInitpcr, "initpcr" },
|
|
|
|
// The following PAL operations are unprivileged
|
|
|
|
{ palopBpt, "bpt" },
|
|
{ palopCallsys, "callsys" },
|
|
{ palopImb, "imb" },
|
|
{ palopGentrap, "gentrap" },
|
|
{ palopRdteb, "rdteb" },
|
|
{ palopKbpt, "kbpt" },
|
|
{ palopCallkd, "callkd" },
|
|
};
|
|
|
|
const size_t DISAXP::cpalmap = sizeof(rgpalmap) / sizeof(PALMAP);
|
|
|
|
|
|
const char DISAXP::rgszGpr[32][8] =
|
|
{
|
|
"v0", // $0
|
|
"t0", // $1
|
|
"t1", // $2
|
|
"t2", // $3
|
|
"t3", // $4
|
|
"t4", // $5
|
|
"t5", // $6
|
|
"t6", // $7
|
|
"t7", // $8
|
|
"s0", // $9
|
|
"s1", // $10
|
|
"s2", // $11
|
|
"s3", // $12
|
|
"s4", // $13
|
|
"s5", // $14
|
|
"fp", // $15
|
|
"a0", // $16
|
|
"a1", // $17
|
|
"a2", // $18
|
|
"a3", // $19
|
|
"a4", // $20
|
|
"a5", // $21
|
|
"t8", // $22
|
|
"t9", // $23
|
|
"t10", // $24
|
|
"t11", // $25
|
|
"ra", // $26
|
|
"t12", // $27
|
|
"at", // $28
|
|
"gp", // $29
|
|
"sp", // $30
|
|
"zero", // $31
|
|
};
|
|
|
|
|
|
DISAXP::DISAXP(ARCHT archt) : DIS(archt)
|
|
{
|
|
}
|
|
|
|
|
|
// -----------------------------------------------------------------
|
|
// Public Methods
|
|
// -----------------------------------------------------------------
|
|
|
|
ADDR DISAXP::AddrAddress() const
|
|
{
|
|
// UNDONE
|
|
|
|
return(addrNil);
|
|
}
|
|
|
|
|
|
ADDR DISAXP::AddrJumpTable() const
|
|
{
|
|
return(addrNil);
|
|
}
|
|
|
|
|
|
ADDR DISAXP::AddrOperand(size_t ioperand) const
|
|
{
|
|
if (m_pfndwgetreg == 0)
|
|
{
|
|
return(addrNil);
|
|
}
|
|
|
|
if (ioperand == 0)
|
|
{
|
|
// Implicit operand if any
|
|
|
|
return(addrNil);
|
|
}
|
|
|
|
if (!FValidOperand(ioperand))
|
|
{
|
|
return(addrNil);
|
|
}
|
|
|
|
ICLS icls = (ICLS) m_popcd->icls;
|
|
Assert(icls != iclsInvalid);
|
|
|
|
ADDR addr = addrNil;
|
|
|
|
OPCLS opcls = (OPCLS) rgcls[icls].rgopcls[ioperand-1];
|
|
|
|
switch (opcls)
|
|
{
|
|
DWORD dwDisp;
|
|
|
|
case opclsMem : // Memory reference: disp.ab(Rb.ab)
|
|
case opclsMem_r : // Memory read: disp.ab(Rb.ab)
|
|
case opclsMem_w : // Memory write: disp.ab(Rb.ab)
|
|
if (m_axpiw.Memory.Rb != 31)
|
|
{
|
|
addr = (ADDR) (*m_pfndwgetreg)(this, (int) m_axpiw.Memory.Rb);
|
|
}
|
|
|
|
dwDisp = m_axpiw.Memory.MemDisp;
|
|
|
|
if ((dwDisp & 0x8000) != 0)
|
|
{
|
|
dwDisp |= 0xFFFF0000;
|
|
}
|
|
|
|
addr += dwDisp;
|
|
break;
|
|
|
|
case opclsMemHigh : // Memory reference: disp.ab(Rb.ab)
|
|
if (m_axpiw.Memory.Rb != 31)
|
|
{
|
|
addr = (ADDR) (*m_pfndwgetreg)(this, (int) m_axpiw.Memory.Rb);
|
|
}
|
|
|
|
addr += (m_axpiw.Memory.MemDisp << 16);
|
|
break;
|
|
|
|
case opclsEv4Mem_r : // Memory read: disp.ab(Rb.ab)
|
|
case opclsEv4Mem_w : // Memory write: disp.ab(Rb.ab)
|
|
if (m_axpiw.Memory.Rb != 31)
|
|
{
|
|
addr = (ADDR) (*m_pfndwgetreg)(this, (int) m_axpiw.EV4_MEM.Rb);
|
|
}
|
|
|
|
dwDisp = m_axpiw.EV4_MEM.Disp;
|
|
|
|
if ((dwDisp & 0x800) != 0)
|
|
{
|
|
dwDisp |= 0xFFFFF000;
|
|
}
|
|
|
|
addr += dwDisp;
|
|
break;
|
|
|
|
case opclsFetch : // FETCH instruction operand
|
|
if (m_axpiw.Memory.Rb != 31)
|
|
{
|
|
addr = (ADDR) (*m_pfndwgetreg)(this, (int) m_axpiw.Memory.Rb);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return(addr);
|
|
}
|
|
|
|
|
|
ADDR DISAXP::AddrTarget() const
|
|
{
|
|
ICLS icls = (ICLS) m_popcd->icls;
|
|
Assert(icls != iclsInvalid);
|
|
|
|
ADDR addrTarget;
|
|
|
|
switch (icls)
|
|
{
|
|
DWORD dwDisp;
|
|
|
|
case iclsBra :
|
|
case iclsCall :
|
|
case iclsBraCc :
|
|
case iclsBraCcFp :
|
|
dwDisp = m_axpiw.Branch.BranchDisp;
|
|
if ((dwDisp & 0x100000) != 0)
|
|
{
|
|
dwDisp |= 0xFFE00000; // Sign extend
|
|
}
|
|
|
|
addrTarget = m_addr + sizeof(AXPIW) + (dwDisp << 2);
|
|
break;
|
|
|
|
default :
|
|
addrTarget = addrNil;
|
|
}
|
|
|
|
return(addrTarget);
|
|
}
|
|
|
|
|
|
size_t DISAXP::Cb() const
|
|
{
|
|
return(sizeof(AXPIW));
|
|
}
|
|
|
|
|
|
size_t DISAXP::CbDisassemble(ADDR addr, const BYTE *pb, size_t cbMax)
|
|
{
|
|
m_addr = addr;
|
|
|
|
if ((addr & 3) != 0)
|
|
{
|
|
// Instruction address not aligned
|
|
|
|
m_popcd = NULL;
|
|
return(0);
|
|
}
|
|
|
|
if (cbMax < sizeof(AXPIW))
|
|
{
|
|
// Buffer not large enough for single instruction
|
|
|
|
m_popcd = NULL;
|
|
return(0);
|
|
}
|
|
|
|
m_axpiw = *(AXPIW UNALIGNED *) pb;
|
|
|
|
m_popcd = PopcdDecode(m_axpiw);
|
|
|
|
if (m_popcd == NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
return(sizeof(AXPIW));
|
|
}
|
|
|
|
|
|
size_t DISAXP::CbGenerateLoadAddress(BYTE *, size_t, size_t *) const
|
|
{
|
|
// UNDONE
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
size_t DISAXP::CbJumpEntry() const
|
|
{
|
|
return(sizeof(DWORD));
|
|
}
|
|
|
|
|
|
size_t DISAXP::CbMemoryReference() const
|
|
{
|
|
// UNDONE: Should we just use an array index by Opcode?
|
|
|
|
size_t cb;
|
|
|
|
switch (m_axpiw.OpReg.Opcode)
|
|
{
|
|
case 0x0020 : // ldf
|
|
case 0x0024 : // stf
|
|
case 0x0028 : // ldl
|
|
case 0x002A : // ldl_l
|
|
case 0x002C : // stl
|
|
case 0x002E : // stl_c
|
|
cb = 4;
|
|
break;
|
|
|
|
case 0x000B : // ldq_u
|
|
case 0x000F : // stq_u
|
|
case 0x0021 : // ldg
|
|
case 0x0022 : // lds
|
|
case 0x0025 : // stg
|
|
case 0x0026 : // sts
|
|
case 0x0029 : // ldq
|
|
case 0x002B : // ldq_l
|
|
case 0x002D : // stq
|
|
case 0x002F : // stq_c
|
|
cb = 8;
|
|
break;
|
|
|
|
case 0x0023 : // ldt
|
|
case 0x0027 : // stt
|
|
cb = 16;
|
|
break;
|
|
|
|
case 0x001B : // hw_ld
|
|
case 0x001F : // hw_st
|
|
cb = m_axpiw.EV4_MEM.QuadWord ? 8 : 4;
|
|
break;
|
|
|
|
default :
|
|
cb = 0;
|
|
};
|
|
|
|
return(cb);
|
|
}
|
|
|
|
|
|
size_t DISAXP::CchFormatAddr(ADDR addr, char *sz, size_t cchMax) const
|
|
{
|
|
if (cchMax > INT_MAX)
|
|
{
|
|
cchMax = INT_MAX;
|
|
}
|
|
|
|
ostrstream ostr(sz, (int) cchMax);
|
|
|
|
FormatAddr(ostr, addr);
|
|
|
|
ostr << ends;
|
|
|
|
if (ostr.fail())
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
return((size_t) ostr.pcount());
|
|
}
|
|
|
|
|
|
size_t DISAXP::CchFormatBytes(char *sz, size_t cchMax) const
|
|
{
|
|
if (cchMax <= 8)
|
|
{
|
|
// Caller's buffer is too small
|
|
|
|
return(0);
|
|
}
|
|
|
|
size_t cch = (size_t) sprintf(sz, "%08X", m_axpiw.dw);
|
|
|
|
Assert(cch == 8);
|
|
|
|
return(8);
|
|
}
|
|
|
|
|
|
size_t DISAXP::CchFormatBytesMax() const
|
|
{
|
|
return(8);
|
|
}
|
|
|
|
|
|
size_t DISAXP::CchFormatInstr(char *sz, size_t cchMax) const
|
|
{
|
|
if (cchMax > INT_MAX)
|
|
{
|
|
cchMax = INT_MAX;
|
|
}
|
|
|
|
ostrstream ostr(sz, (int) cchMax);
|
|
|
|
FormatInstr(ostr);
|
|
|
|
ostr << ends;
|
|
|
|
if (ostr.fail())
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
return((size_t) ostr.pcount());
|
|
}
|
|
|
|
|
|
size_t DISAXP::Coperand() const
|
|
{
|
|
ICLS icls = (ICLS) m_popcd->icls;
|
|
Assert(icls != iclsInvalid);
|
|
|
|
for (size_t coperand = 3; coperand > 0; coperand--)
|
|
{
|
|
if (rgcls[icls].rgopcls[coperand-1] != opclsNone)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
return(coperand);
|
|
}
|
|
|
|
|
|
void DISAXP::FormatAddr(ostream& ostr, ADDR addr) const
|
|
{
|
|
long lFlags = ostr.setf(ios::uppercase);
|
|
char chFill = ostr.fill('0');
|
|
|
|
ostr << hex << setw(8) << addr;
|
|
|
|
ostr.fill(chFill);
|
|
ostr.flags(lFlags);
|
|
}
|
|
|
|
|
|
void DISAXP::FormatInstr(ostream& ostr) const
|
|
{
|
|
long lFlags = ostr.setf(ios::uppercase);
|
|
char chFill = ostr.fill('0');
|
|
|
|
ICLS icls = (ICLS) m_popcd->icls;
|
|
Assert(icls != iclsInvalid);
|
|
|
|
const char *szMnemonic = m_popcd->szMnemonic;
|
|
|
|
// If the mnemonic begins with '~' than there
|
|
// may be a pseudo-op that should be used.
|
|
|
|
char szPseudo[32];
|
|
|
|
if (szMnemonic[0] == '~')
|
|
{
|
|
OPCD opcd;
|
|
|
|
opcd.szMnemonic = szPseudo;
|
|
|
|
const OPCD *popcd = PopcdPseudoOp(&opcd, szPseudo);
|
|
|
|
if (popcd != NULL)
|
|
{
|
|
icls = (ICLS) popcd->icls;
|
|
Assert(icls != iclsInvalid);
|
|
|
|
szMnemonic = popcd->szMnemonic;
|
|
}
|
|
|
|
else
|
|
{
|
|
szMnemonic++;
|
|
}
|
|
}
|
|
|
|
const char *szQualifier = "";
|
|
|
|
switch (icls)
|
|
{
|
|
case iclsRegFp1 :
|
|
case iclsRegFp2 :
|
|
case iclsRegFp5 :
|
|
case iclsReg2Fp1 :
|
|
case iclsReg2Fp3 :
|
|
case iclsReg2Fp6 :
|
|
szQualifier = rgszQualifier1[m_axpiw.FpOp.Function >> 6];
|
|
break;
|
|
|
|
case iclsReg2Fp4 :
|
|
case iclsReg2Fp7 :
|
|
szQualifier = rgszQualifier2[m_axpiw.FpOp.Function >> 6];
|
|
break;
|
|
|
|
case iclsCvtql :
|
|
switch (m_axpiw.FpOp.Function)
|
|
{
|
|
case 0x030 :
|
|
break;
|
|
|
|
case 0x130 :
|
|
szQualifier = "/v";
|
|
break;
|
|
|
|
case 0x530 :
|
|
szQualifier = "/sv";
|
|
break;
|
|
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
ostr << szMnemonic << szQualifier;
|
|
|
|
for (size_t ioperand = 0; ioperand < 3; ioperand++)
|
|
{
|
|
OPCLS opcls = (OPCLS) rgcls[icls].rgopcls[ioperand];
|
|
|
|
if (opcls == opclsNone)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ioperand == 0)
|
|
{
|
|
// Pad opcode field to 14 characters
|
|
|
|
size_t cch = strlen(szMnemonic) + strlen(szQualifier);
|
|
|
|
do
|
|
{
|
|
ostr << ' ';
|
|
}
|
|
while (++cch < 14);
|
|
}
|
|
|
|
else
|
|
{
|
|
ostr << ',';
|
|
}
|
|
|
|
FormatOperand(ostr, opcls);
|
|
}
|
|
|
|
ostr.fill(chFill);
|
|
ostr.flags(lFlags);
|
|
}
|
|
|
|
|
|
DIS::MEMREFT DISAXP::Memreft() const
|
|
{
|
|
ICLS icls = (ICLS) m_popcd->icls;
|
|
Assert(icls != iclsInvalid);
|
|
|
|
// There is no translation for pseudo-ops so we only check operand 2
|
|
|
|
MEMREFT memreft;
|
|
|
|
switch ((OPCLS) rgcls[icls].rgopcls[1])
|
|
{
|
|
case opclsMem_r :
|
|
case opclsEv4Mem_r :
|
|
memreft = memreftRead;
|
|
break;
|
|
|
|
case opclsMem_w :
|
|
case opclsEv4Mem_w :
|
|
// UNDONE: Should STL_C and STQ_C return memreftOther?
|
|
|
|
memreft = memreftWrite;
|
|
break;
|
|
|
|
default :
|
|
memreft = memreftNone;
|
|
break;
|
|
}
|
|
|
|
return(memreft);
|
|
}
|
|
|
|
|
|
TRMT DISAXP::Trmt() const
|
|
{
|
|
TRMTAXP trmtaxp = Trmtaxp();
|
|
|
|
return(mptrmtaxptrmt[trmtaxp]);
|
|
}
|
|
|
|
|
|
TRMTA DISAXP::Trmta() const
|
|
{
|
|
TRMTAXP trmtaxp = Trmtaxp();
|
|
|
|
return((TRMTA) trmtaxp);
|
|
}
|
|
|
|
|
|
// -----------------------------------------------------------------
|
|
// Private Methods
|
|
// -----------------------------------------------------------------
|
|
|
|
void DISAXP::FormatHex(ostream& ostr, DWORD dw) const
|
|
{
|
|
if (dw <= 9)
|
|
{
|
|
ostr << dw;
|
|
return;
|
|
}
|
|
|
|
ostr << "0x" << hex << dw;
|
|
}
|
|
|
|
|
|
void DISAXP::FormatOperand(ostream& ostr, OPCLS opcls) const
|
|
{
|
|
size_t cch;
|
|
char szSymbol[1024];
|
|
DWORD dwDisp;
|
|
size_t ipalmap;
|
|
|
|
switch (opcls)
|
|
{
|
|
case opclsNone : // No operand
|
|
AssertSz(false, "Unexpected AXP operand class");
|
|
break;
|
|
|
|
case opclsRa_w : // General purpose register Ra (write)
|
|
case opclsRa_m : // General purpose register Ra (read/write)
|
|
case opclsRa_r : // General purpose register Ra (read)
|
|
ostr << rgszGpr[m_axpiw.OpReg.Ra];
|
|
break;
|
|
|
|
case opclsRb_r : // General purpose register Ra (read)
|
|
ostr << rgszGpr[m_axpiw.OpReg.Rb];
|
|
break;
|
|
|
|
case opclsRbLb : // General purpose register Rb (read) or literal in Rb field
|
|
if (m_axpiw.OpReg.RbvType == 0)
|
|
{
|
|
ostr << rgszGpr[m_axpiw.OpReg.Rb];
|
|
}
|
|
|
|
else
|
|
{
|
|
FormatHex(ostr, m_axpiw.OpLit.Literal);
|
|
}
|
|
break;
|
|
|
|
case opclsRc_w : // General purpose register Rc (write)
|
|
ostr << rgszGpr[m_axpiw.OpReg.Rc];
|
|
break;
|
|
|
|
case opclsFa_w : // Floating point register Fa (write)
|
|
case opclsFa_r : // Floating point register Fa (read)
|
|
ostr << 'f' << (unsigned) m_axpiw.FpOp.Fa;
|
|
break;
|
|
|
|
case opclsFb_r : // Floating point register Fb (read)
|
|
ostr << 'f' << (unsigned) m_axpiw.FpOp.Fb;
|
|
break;
|
|
|
|
case opclsFc_w : // Floating point register Fc (write)
|
|
ostr << 'f' << (unsigned) m_axpiw.FpOp.Fc;
|
|
break;
|
|
|
|
case opclsMem : // Memory reference: disp.ab(Rb.ab)
|
|
case opclsMemHigh : // Memory reference: disp.ab(Rb.ab)
|
|
case opclsMem_r : // Memory read: disp.ab(Rb.ab)
|
|
case opclsMem_w : // Memory write: disp.ab(Rb.ab)
|
|
if (m_pfncchfixup != 0)
|
|
{
|
|
cch = (*m_pfncchfixup)(this, m_addr, sizeof(WORD), szSymbol, sizeof(szSymbol), &dwDisp);
|
|
|
|
if (cch != 0)
|
|
{
|
|
ostr << szSymbol;
|
|
|
|
if (dwDisp != 0)
|
|
{
|
|
ostr << '+';
|
|
|
|
FormatHex(ostr, dwDisp);
|
|
}
|
|
|
|
if (m_axpiw.Memory.Rb != 31)
|
|
{
|
|
ostr << '(' << rgszGpr[m_axpiw.Memory.Rb] << ')';
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
dwDisp = m_axpiw.Memory.MemDisp;
|
|
|
|
if ((dwDisp & 0x8000) != 0)
|
|
{
|
|
dwDisp |= 0xFFFF0000;
|
|
}
|
|
|
|
FormatRegRel(ostr, (REG) m_axpiw.Memory.Rb, dwDisp);
|
|
break;
|
|
|
|
case opclsEv4Mem_r : // Memory read: disp.ab(Rb.ab)
|
|
case opclsEv4Mem_w : // Memory write: disp.ab(Rb.ab)
|
|
if (m_pfncchfixup != 0)
|
|
{
|
|
cch = (*m_pfncchfixup)(this, m_addr, sizeof(WORD), szSymbol, sizeof(szSymbol), &dwDisp);
|
|
|
|
if (cch != 0)
|
|
{
|
|
ostr << szSymbol;
|
|
|
|
if (dwDisp != 0)
|
|
{
|
|
ostr << '+';
|
|
|
|
FormatHex(ostr, dwDisp);
|
|
}
|
|
|
|
if (m_axpiw.Memory.Rb != 31)
|
|
{
|
|
ostr << '(' << rgszGpr[m_axpiw.EV4_MEM.Rb] << ')';
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
dwDisp = m_axpiw.EV4_MEM.Disp;
|
|
|
|
if ((dwDisp & 0x800) != 0)
|
|
{
|
|
dwDisp |= 0xFFFFF000;
|
|
}
|
|
|
|
FormatRegRel(ostr, (REG) m_axpiw.EV4_MEM.Rb, dwDisp);
|
|
break;
|
|
|
|
case opclsBra : // Branch instruction target
|
|
if (m_pfncchaddr != 0)
|
|
{
|
|
cch = (*m_pfncchaddr)(this, AddrTarget(), szSymbol, sizeof(szSymbol), &dwDisp);
|
|
|
|
if (cch != 0)
|
|
{
|
|
ostr << szSymbol;
|
|
|
|
if (dwDisp != 0)
|
|
{
|
|
ostr << '+';
|
|
|
|
FormatHex(ostr, dwDisp);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
ostr << hex << setw(8) << AddrTarget();
|
|
break;
|
|
|
|
case opclsJmp : // Jump instruction target: (Rb.ab)
|
|
ostr << '(' << rgszGpr[m_axpiw.Jump.Rb] << ')';
|
|
break;
|
|
|
|
case opclsHint1 : // Jump target hint
|
|
FormatHex(ostr, m_axpiw.Jump.Hint << 2);
|
|
break;
|
|
|
|
case opclsHint2 : // RET/JSR_COROUTINE hint
|
|
FormatHex(ostr, m_axpiw.Jump.Hint);
|
|
break;
|
|
|
|
case opclsPal : // CALL_PAL instruction operand
|
|
for (ipalmap = 0; ipalmap < cpalmap; ipalmap++)
|
|
{
|
|
if (rgpalmap[ipalmap].palop == (PALOP) m_axpiw.Pal.Function)
|
|
{
|
|
ostr << rgpalmap[ipalmap].szFunction;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ipalmap == cpalmap)
|
|
{
|
|
FormatHex(ostr, m_axpiw.Pal.Function);
|
|
}
|
|
break;
|
|
|
|
case opclsFetch : // FETCH instruction operand
|
|
ostr << "0(" << rgszGpr[m_axpiw.Memory.Rb] << ')';
|
|
break;
|
|
|
|
default :
|
|
AssertSz(false, "Unexpected AXP operand class");
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void DISAXP::FormatRegRel(ostream& ostr, REG reg, DWORD dwDisp) const
|
|
{
|
|
if ((m_pfncchregrel != 0) && (reg != regZero))
|
|
{
|
|
char sz[1024];
|
|
|
|
size_t cch = (*m_pfncchregrel)(this, (int) reg, dwDisp, sz, sizeof(sz), &dwDisp);
|
|
|
|
if (cch != 0)
|
|
{
|
|
ostr << sz;
|
|
|
|
if (dwDisp != 0)
|
|
{
|
|
ostr << '+';
|
|
|
|
FormatHex(ostr, dwDisp);
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
FormatHex(ostr, (WORD) dwDisp);
|
|
|
|
if (reg != regZero)
|
|
{
|
|
ostr << '(' << rgszGpr[reg] << ')';
|
|
}
|
|
}
|
|
|
|
|
|
bool DISAXP::FValidOperand(size_t ioperand) const
|
|
{
|
|
if (ioperand == 0)
|
|
{
|
|
// Implicit operand if any
|
|
|
|
return(true);
|
|
}
|
|
|
|
if (ioperand > 3)
|
|
{
|
|
return(false);
|
|
}
|
|
|
|
ICLS icls = (ICLS) m_popcd->icls;
|
|
Assert(icls != iclsInvalid);
|
|
|
|
OPCLS opcls = (OPCLS) rgcls[icls].rgopcls[ioperand-1];
|
|
|
|
return(opcls != opclsNone);
|
|
}
|
|
|
|
|
|
const DISAXP::OPCD *DISAXP::PopcdDecode(AXPIW axpiw)
|
|
{
|
|
const OPCD *popcd = rgopcd + axpiw.OpReg.Opcode;
|
|
|
|
if ((ICLS) popcd->icls == iclsInvalid)
|
|
{
|
|
switch (axpiw.OpReg.Opcode)
|
|
{
|
|
case 0x10 : // ARITH group
|
|
popcd = rgopcdArith + axpiw.OpReg.Function;
|
|
break;
|
|
|
|
case 0x11 : // BIT group
|
|
popcd = rgopcdBit + axpiw.OpReg.Function;
|
|
break;
|
|
|
|
case 0x12 : // BYTE group
|
|
popcd = rgopcdByte + axpiw.OpReg.Function;
|
|
break;
|
|
|
|
case 0x13 : // MUL group
|
|
popcd = rgopcdMul + axpiw.OpReg.Function;
|
|
break;
|
|
|
|
case 0x15 : // VAXFP group
|
|
popcd = rgopcdVax + (axpiw.FpOp.Function & 0x3F);
|
|
break;
|
|
|
|
case 0x16 : // IEEEFP group
|
|
popcd = rgopcdIEEE + (axpiw.FpOp.Function & 0x3F);
|
|
break;
|
|
|
|
case 0x17 : // FPOP group
|
|
popcd = rgopcdFP + (axpiw.FpOp.Function & 0x3F);
|
|
break;
|
|
|
|
case 0x18 : // MEMSPC group
|
|
if ((axpiw.Memory.MemDisp & 0x03FF) != 0)
|
|
{
|
|
return(NULL);
|
|
}
|
|
|
|
popcd = rgopcdMemSpc + (axpiw.Memory.MemDisp >> 10);
|
|
break;
|
|
|
|
case 0x1A : // Jump group
|
|
popcd = rgopcdJump + axpiw.Jump.Function;
|
|
break;
|
|
|
|
case 0x1C : // Sext group
|
|
if (axpiw.OpReg.Function > 1)
|
|
{
|
|
return(NULL);
|
|
}
|
|
|
|
popcd = rgopcdSext + axpiw.OpReg.Function;
|
|
break;
|
|
|
|
default :
|
|
return(NULL);
|
|
}
|
|
}
|
|
|
|
ICLS icls = (ICLS) popcd->icls;
|
|
|
|
switch (icls)
|
|
{
|
|
case iclsInvalid :
|
|
return(NULL);
|
|
|
|
case iclsLoadAddr :
|
|
case iclsLoadAddrH :
|
|
case iclsLoad :
|
|
case iclsStore :
|
|
case iclsStoreCc :
|
|
case iclsCall :
|
|
case iclsBraCc :
|
|
// UNDONE: Validate restrictions
|
|
break;
|
|
|
|
case iclsJmp :
|
|
#if 0
|
|
if ((axpiw.Jump.Function & 0x2) != 0)
|
|
{
|
|
// For RET and JSR_COROUTINE, Hint contains magic values
|
|
|
|
if (axpiw.Jump.Hint > 0x0001)
|
|
{
|
|
// Hint values above 0x0001 are reserved to Digital
|
|
|
|
return(NULL);
|
|
}
|
|
}
|
|
#endif
|
|
break;
|
|
|
|
case iclsReg :
|
|
case iclsRegTrap :
|
|
if ((axpiw.OpReg.RbvType == 0) && (axpiw.OpReg.SBZ != 0))
|
|
{
|
|
return(NULL);
|
|
}
|
|
break;
|
|
|
|
case iclsLoadFp :
|
|
case iclsStoreFp :
|
|
case iclsBraCcFp :
|
|
// UNDONE: Validate restrictions
|
|
break;
|
|
|
|
case iclsRegFp :
|
|
break;
|
|
|
|
case iclsRegFp1 :
|
|
if (((dwValidQualifier1 >> (axpiw.FpOp.Function >> 6)) & 1) == 0)
|
|
{
|
|
return(NULL);
|
|
}
|
|
break;
|
|
|
|
case iclsRegFp2 :
|
|
if (((dwValidQualifier2 >> (axpiw.FpOp.Function >> 6)) & 1) == 0)
|
|
{
|
|
return(NULL);
|
|
}
|
|
break;
|
|
|
|
case iclsRegFp5 :
|
|
if (((dwValidQualifier5 >> (axpiw.FpOp.Function >> 6)) & 1) == 0)
|
|
{
|
|
return(NULL);
|
|
}
|
|
break;
|
|
|
|
case iclsReg2Fp :
|
|
Reg2Fp:
|
|
if (axpiw.FpOp.Fa != 31)
|
|
{
|
|
return(NULL);
|
|
}
|
|
break;
|
|
|
|
case iclsReg2Fp1 :
|
|
if (((dwValidQualifier1 >> (axpiw.FpOp.Function >> 6)) & 1) == 0)
|
|
{
|
|
return(NULL);
|
|
}
|
|
goto Reg2Fp;
|
|
|
|
case iclsReg2Fp3 :
|
|
if (((dwValidQualifier3 >> (axpiw.FpOp.Function >> 6)) & 1) == 0)
|
|
{
|
|
return(NULL);
|
|
}
|
|
goto Reg2Fp;
|
|
|
|
case iclsReg2Fp4 :
|
|
if (((dwValidQualifier4 >> (axpiw.FpOp.Function >> 6)) & 1) == 0)
|
|
{
|
|
return(NULL);
|
|
}
|
|
goto Reg2Fp;
|
|
|
|
case iclsReg2Fp6 :
|
|
if (((dwValidQualifier6 >> (axpiw.FpOp.Function >> 6)) & 1) == 0)
|
|
{
|
|
return(NULL);
|
|
}
|
|
goto Reg2Fp;
|
|
|
|
case iclsReg2Fp7 :
|
|
if (((dwValidQualifier7 >> (axpiw.FpOp.Function >> 6)) & 1) == 0)
|
|
{
|
|
return(NULL);
|
|
}
|
|
goto Reg2Fp;
|
|
|
|
case iclsCvtql :
|
|
if (((dwValidQualifier8 >> (axpiw.FpOp.Function >> 6)) & 1) == 0)
|
|
{
|
|
return(NULL);
|
|
}
|
|
goto Reg2Fp;
|
|
|
|
case iclsFpcr :
|
|
if ((axpiw.FpOp.Fa != axpiw.FpOp.Fb) ||
|
|
(axpiw.FpOp.Fa != axpiw.FpOp.Fc))
|
|
{
|
|
return(NULL);
|
|
}
|
|
break;
|
|
|
|
case iclsPal :
|
|
// UNDONE: Validate Function
|
|
break;
|
|
|
|
case iclsFetch :
|
|
case iclsNone :
|
|
case iclsRa_w :
|
|
// UNDONE: What about Ra?
|
|
break;
|
|
|
|
case iclsEv4Rei:
|
|
if ((axpiw.EV4_REI.zero != 0) || (axpiw.EV4_REI.one != 1))
|
|
{
|
|
return(NULL);
|
|
}
|
|
|
|
// UNDONE: What about Ra, Rb?
|
|
break;
|
|
|
|
case iclsEv4Pr :
|
|
// UNDONE: Validate
|
|
break;
|
|
|
|
case iclsEv4Load :
|
|
case iclsEv4Store :
|
|
// UNDONE: Validate
|
|
break;
|
|
|
|
default :
|
|
AssertSz(false, "Unknown Alpha instruction class");
|
|
break;
|
|
}
|
|
|
|
return(popcd);
|
|
}
|
|
|
|
|
|
const DISAXP::OPCD *DISAXP::PopcdPseudoOp(OPCD *popcd, char *) const
|
|
{
|
|
if (m_popcd == rgopcd+0x0008)
|
|
{
|
|
// lda Ra,d(Rb)
|
|
|
|
if (m_axpiw.Memory.Rb == 31)
|
|
{
|
|
return(&opcdMov2);
|
|
}
|
|
}
|
|
|
|
else if (m_popcd == rgopcd+0x0030)
|
|
{
|
|
// br Ra,target
|
|
|
|
if (m_axpiw.Branch.Ra == 31)
|
|
{
|
|
return(&opcdBr_);
|
|
}
|
|
}
|
|
|
|
else if (m_popcd == rgopcdBit+0x0020)
|
|
{
|
|
// bis rA,rB,rC
|
|
|
|
if (m_axpiw.OpReg.Ra == 31)
|
|
{
|
|
if ((m_axpiw.OpReg.RbvType == 0) && (m_axpiw.OpReg.Rb == 31))
|
|
{
|
|
if (m_axpiw.OpReg.Rc == 31)
|
|
{
|
|
return(&opcdNop);
|
|
}
|
|
|
|
else
|
|
{
|
|
return(&opcdClr);
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
return(&opcdMov1);
|
|
}
|
|
}
|
|
}
|
|
|
|
else if (m_popcd == rgopcdBit+0x0028)
|
|
{
|
|
// ornot Ra,Rb,Rc
|
|
|
|
if (m_axpiw.OpReg.Ra == 31)
|
|
{
|
|
return(&opcdNot);
|
|
}
|
|
}
|
|
|
|
else if (m_popcd == rgopcdFP+0x0020)
|
|
{
|
|
// cpys Fa,Fb,Fc
|
|
|
|
if (m_axpiw.FpOp.Fa == 31)
|
|
{
|
|
if (m_axpiw.FpOp.Fb == 31)
|
|
{
|
|
if (m_axpiw.FpOp.Fc == 31)
|
|
{
|
|
return(&opcdFnop);
|
|
}
|
|
|
|
else
|
|
{
|
|
return(&opcdFclr);
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
return(&opcdFabs);
|
|
}
|
|
}
|
|
|
|
else if (m_axpiw.FpOp.Fa == m_axpiw.FpOp.Fb)
|
|
{
|
|
return(&opcdFmov);
|
|
}
|
|
}
|
|
|
|
else if (m_popcd == rgopcdFP+0x0021)
|
|
{
|
|
// cpysn Fa,Fb,Fc
|
|
|
|
if (m_axpiw.FpOp.Fa == m_axpiw.FpOp.Fb)
|
|
{
|
|
return(&opcdFneg);
|
|
}
|
|
}
|
|
|
|
else if (m_popcd == rgopcdFP+0x0024)
|
|
{
|
|
// mt_fpcr Fa,Fb,Fc
|
|
|
|
if ((m_axpiw.FpOp.Fa == m_axpiw.FpOp.Fb) &&
|
|
(m_axpiw.FpOp.Fa == m_axpiw.FpOp.Fc))
|
|
{
|
|
return(&opcdMt_Fpcr);
|
|
}
|
|
}
|
|
|
|
else if (m_popcd == rgopcdFP+0x0025)
|
|
{
|
|
// mf_fpcr Fa,Fb,Fc
|
|
|
|
if ((m_axpiw.FpOp.Fa == m_axpiw.FpOp.Fb) &&
|
|
(m_axpiw.FpOp.Fa == m_axpiw.FpOp.Fc))
|
|
{
|
|
return(&opcdMf_Fpcr);
|
|
}
|
|
}
|
|
|
|
else if (m_popcd == rgopcdVax+0x0001)
|
|
{
|
|
// subf Fa,Fb,Fc
|
|
|
|
if (m_axpiw.FpOp.Fa == 31)
|
|
{
|
|
// UNDONE: Restrict qualifiers?
|
|
|
|
return(&opcdNegf);
|
|
}
|
|
}
|
|
|
|
// UNDONE: SUBD -> NEGD?
|
|
|
|
else if (m_popcd == rgopcdVax+0x0021)
|
|
{
|
|
// subg Fa,Fb,Fc
|
|
|
|
if (m_axpiw.FpOp.Fa == 31)
|
|
{
|
|
// UNDONE: Restrict qualifiers?
|
|
|
|
return(&opcdNegg);
|
|
}
|
|
}
|
|
|
|
else if (m_popcd == rgopcdIEEE+0x0001)
|
|
{
|
|
// subs Fa,Fb,Fc
|
|
|
|
if (m_axpiw.FpOp.Fa == 31)
|
|
{
|
|
// UNDONE: Restrict qualifiers?
|
|
|
|
return(&opcdNegs);
|
|
}
|
|
}
|
|
|
|
else if (m_popcd == rgopcdIEEE+0x0021)
|
|
{
|
|
// subt Fa,Fb,Fc
|
|
|
|
if (m_axpiw.FpOp.Fa == 31)
|
|
{
|
|
// UNDONE: Restrict qualifiers?
|
|
|
|
return(&opcdNegt);
|
|
}
|
|
}
|
|
|
|
else if (m_popcd == rgopcdArith+0x0000)
|
|
{
|
|
// addl Ra,Rb,Rc
|
|
|
|
if (m_axpiw.OpReg.Ra == 31)
|
|
{
|
|
return(&opcdSextl);
|
|
}
|
|
}
|
|
|
|
else if (m_popcd == rgopcdArith+0x0009)
|
|
{
|
|
// subl Ra,Rb,Rc
|
|
|
|
if (m_axpiw.OpReg.Ra == 31)
|
|
{
|
|
return(&opcdNegl);
|
|
}
|
|
}
|
|
|
|
else if (m_popcd == rgopcdArith+0x0029)
|
|
{
|
|
// subq Ra,Rb,Rc
|
|
|
|
if (m_axpiw.OpReg.Ra == 31)
|
|
{
|
|
return(&opcdNegq);
|
|
}
|
|
}
|
|
|
|
else if (m_popcd == rgopcdArith+0x0049)
|
|
{
|
|
// subl/v Ra,Rb,Rc
|
|
|
|
if (m_axpiw.OpReg.Ra == 31)
|
|
{
|
|
return(&opcdNegl_V);
|
|
}
|
|
}
|
|
|
|
else if (m_popcd == rgopcdArith+0x0069)
|
|
{
|
|
// subq/v Ra,Rb,Rc
|
|
|
|
if (m_axpiw.OpReg.Ra == 31)
|
|
{
|
|
return(&opcdNegq_V);
|
|
}
|
|
}
|
|
|
|
else if (m_popcd == rgopcdJump+0x00)
|
|
{
|
|
// jmp ra,(rb),hint
|
|
|
|
// UNDONE
|
|
}
|
|
|
|
else if (m_popcd == rgopcdJump+0x01)
|
|
{
|
|
// jsr ra,(rb),hint
|
|
|
|
// UNDONE
|
|
}
|
|
|
|
else if ((m_popcd == rgopcdJump+0x02) || (m_popcd == rgopcdJump+0x03))
|
|
{
|
|
// ret ra,(rb),hint
|
|
// jsr_coroutine ra,(rb),hint
|
|
|
|
bool fDefaultRa = (m_axpiw.Jump.Ra == 31);
|
|
bool fDefaultRb = (m_axpiw.Jump.Rb == 26);
|
|
bool fDefaultHint = (m_axpiw.Jump.Hint == 1);
|
|
|
|
popcd->szMnemonic = m_popcd->szMnemonic + 1;
|
|
|
|
popcd->icls = (ICLS) (iclsRet1 +
|
|
(fDefaultRa << 2) +
|
|
(fDefaultRb << 1) +
|
|
fDefaultHint);
|
|
|
|
return(popcd);
|
|
}
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
|
|
TRMTAXP DISAXP::Trmtaxp() const
|
|
{
|
|
ICLS icls = (ICLS) m_popcd->icls;
|
|
Assert(icls != iclsInvalid);
|
|
|
|
if (icls == iclsCall)
|
|
{
|
|
if (m_axpiw.Branch.Ra != 31)
|
|
{
|
|
return(trmtaxpCall);
|
|
}
|
|
|
|
else
|
|
{
|
|
return(trmtaxpBra);
|
|
}
|
|
}
|
|
|
|
if (icls == iclsJmp)
|
|
{
|
|
if (m_axpiw.Jump.Ra != 31)
|
|
{
|
|
return(trmtaxpCallInd);
|
|
}
|
|
|
|
return(trmtaxpBraInd);
|
|
}
|
|
|
|
return((TRMTAXP) rgcls[icls].trmtaxp);
|
|
}
|