/***********************************************************************
* Microsoft Puma
*
* Microsoft Confidential.  Copyright 1994-1996 Microsoft Corporation.
*
* Component:
*
* File: mips.h
*
* File Comments:
*
*
***********************************************************************/

class ostream;
struct _IMAGE_RUNTIME_FUNCTION_ENTRY;


enum TRMTMIPS
{
   trmtmipsUnknown,
   trmtmipsFallThrough,
   trmtmipsBraInd,
   trmtmipsCallInd,
   trmtmipsTrap,
   trmtmipsTrapCc,
   trmtmipsBraDef,
   trmtmipsBraIndDef,
   trmtmipsBraCcDef,
   trmtmipsBraCcLikely,
   trmtmipsCallDef,
   trmtmipsCallIndDef,
   trmtmipsCallCcDef,
   trmtmipsCallCcLikely,
};


union MIPSIW			       // MIPS Instruction Word
{
   DWORD    dw;

   struct
   {
      DWORD Target : 26;
      DWORD Opcode : 6;
   } j_format;

   struct
   {
      DWORD Uimmediate : 16;
      DWORD Rt : 5;
      DWORD Rs : 5;
      DWORD Opcode : 6;
   } u_format;

   struct
   {
      DWORD Function : 6;
      DWORD Re : 5;
      DWORD Rd : 5;
      DWORD Rt : 5;
      DWORD Rs : 5;
      DWORD Opcode : 6;
   } r_format;

   struct
   {
      DWORD Function : 6;
      DWORD Re : 5;
      DWORD Rd : 5;
      DWORD Rt : 5;
      DWORD Format : 4;
      DWORD Fill1 : 1;
      DWORD Opcode : 6;
   } f_format;

   struct
   {
      DWORD Function : 6;
      DWORD Fd : 5;
      DWORD Fs : 5;
      DWORD Ft : 5;
      DWORD Format : 4;
      DWORD Fill1 : 1;
      DWORD Opcode : 6;
   } c_format;
};


class DISMIPS : public DIS
{
public:
	    DISMIPS(ARCHT);

	    enum REG
	    {
	       regR0	= 0,
	       regR1	= 1,
	       regR2	= 2,
	       regR3	= 3,
	       regR4	= 4,
	       regR5	= 5,
	       regR6	= 6,
	       regR7	= 7,
	       regR8	= 8,
	       regR9	= 9,
	       regR10	= 10,
	       regR11	= 11,
	       regR12	= 12,
	       regR13	= 13,
	       regR14	= 14,
	       regR15	= 15,
	       regR16	= 16,
	       regR17	= 17,
	       regR18	= 18,
	       regR19	= 19,
	       regR20	= 20,
	       regR21	= 21,
	       regR22	= 22,
	       regR23	= 23,
	       regR24	= 24,
	       regR25	= 25,
	       regR26	= 26,
	       regR27	= 27,
	       regR28	= 28,
	       regR29	= 29,
	       regR30	= 30,
	       regR31	= 31,

	       regZero	= 0,
	       regAt	= 1,
	       regV0	= 2,
	       regV1	= 3,
	       regA0	= 4,
	       regA1	= 5,
	       regA2	= 6,
	       regA3	= 7,
	       regT0	= 8,
	       regT1	= 9,
	       regT2	= 10,
	       regT3	= 11,
	       regT4	= 12,
	       regT5	= 13,
	       regT6	= 14,
	       regT7	= 15,
	       regS0	= 16,
	       regS1	= 17,
	       regS2	= 18,
	       regS3	= 19,
	       regS4	= 20,
	       regS5	= 21,
	       regS6	= 22,
	       regS7	= 23,
	       regT8	= 24,
	       regT9	= 25,
	       regK0	= 26,
	       regK1	= 27,
	       regGp	= 28,
	       regSp	= 29,
	       regS8	= 30,
	       regRa	= 31,

	       regF0	= 32,
	       regF1	= 33,
	       regF2	= 34,
	       regF3	= 35,
	       regF4	= 36,
	       regF5	= 37,
	       regF6	= 38,
	       regF7	= 39,
	       regF8	= 40,
	       regF9	= 41,
	       regF10	= 42,
	       regF11	= 43,
	       regF12	= 44,
	       regF13	= 45,
	       regF14	= 46,
	       regF15	= 47,
	       regF16	= 48,
	       regF17	= 49,
	       regF18	= 50,
	       regF19	= 51,
	       regF20	= 52,
	       regF21	= 53,
	       regF22	= 54,
	       regF23	= 55,
	       regF24	= 56,
	       regF25	= 57,
	       regF26	= 58,
	       regF27	= 59,
	       regF28	= 60,
	       regF29	= 61,
	       regF30	= 62,
	       regF31	= 63,
	    };

	    // Methods inherited from DIS

	    ADDR AddrAddress() const;
	    ADDR AddrJumpTable() const;
	    ADDR AddrOperand(size_t) const;
	    ADDR AddrTarget() const;
	    size_t Cb() const;
	    size_t CbDisassemble(ADDR, const BYTE *, size_t);
	    size_t CbGenerateLoadAddress(BYTE *, size_t, size_t * = NULL) const;
	    size_t CbJumpEntry() const;
	    size_t CbMemoryReference() const;
	    size_t CchFormatAddr(ADDR, char *, size_t) const;
	    size_t CchFormatBytes(char *, size_t) const;
	    size_t CchFormatBytesMax() const;
	    size_t CchFormatInstr(char *, size_t) const;
	    size_t Coperand() const;
	    void FormatAddr(ostream&, ADDR) const;
	    void FormatInstr(ostream&) const;
	    MEMREFT Memreft() const;
	    TRMT Trmt() const;
	    TRMTA Trmta() const;

private:
	    enum OPCLS		       // Operand Class
	    {
	       opclsNone,	       // No operand
	       opclsRegRs,	       // General purpose register Rs
	       opclsRegRt,	       // General purpose register Rt
	       opclsRegRd,	       // General purpose register Rd
	       opclsImmRt,	       // Immediate value of Rt
	       opclsImmRe,	       // Immediate value of Re
	       opclsImm,	       // Immediate value
	       opclsMem,	       // Memory reference
	       opclsMem_w,	       // Memory reference
	       opclsMem_r,	       // Memory reference
	       opclsCc1,	       // Floating point condition code
	       opclsCc2,	       // Floating point condition code
	       opclsAddrBra,	       // Branch instruction target
	       opclsAddrJmp,	       // Jump instruction target
	       opclsCprRt,	       // Coprocessor general register Rt
	       opclsCprRd,	       // Coprocessor general register Rd
	       opclsRegFr,	       // Floating point general register Fr
	       opclsRegFs,	       // Floating point general register Fs
	       opclsRegFt,	       // Floating point general register Ft
	       opclsRegFd,	       // Floating point general register Fd
	       opclsIndex,	       // Index based reference
	    };

	    enum ICLS		       // Instruction Class
	    {
		    // Invalid Class

	       iclsInvalid,

		    // Immediate Class
		    //
		    // Text Format:	    ADDIU   rt,rs,immediate
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Rs
		    // Registers Set:	    Rt

	       iclsImmediate,

		    // Immediate Class
		    //
		    // Text Format:	    ADDI    rt,rs,immediate
		    //
		    // Termination Type:    trmtmipsTrapCc
		    //
		    // Registers Used:	    Rs
		    // Registers Set:	    Rt

	       iclsImmTrapCc,

		    // Immediate (BraCc-1) Class
		    //
		    // Text Format:	    BEQ     rt,rs,Target
		    //
		    // Termination Type:    trmtmipsBraCcDef
		    //
		    // Registers Used:	    Rs, Rt
		    // Registers Set:

	       iclsImmBraCc1,

		    // Immediate (BraCc-2) Class
		    //
		    // Text Format:	    BEQL    rt,rs,Target
		    //
		    // Termination Type:    trmtmipsBraCcLikely
		    //
		    // Registers Used:	    Rs, Rt
		    // Registers Set:

	       iclsImmBraCc2,

		    // Immediate (BraCc-3) Class
		    //
		    // Text Format:	    BGTZ    rs,Target
		    //
		    // Termination Type:    trmtmipsBraCcDef
		    //
		    // Registers Used:	    Rs
		    // Registers Set:
		    //
		    // Constraints:	    Rt must be zero

	       iclsImmBraCc3,

		    // Immediate (BraCc-4) Class
		    //
		    // Text Format:	    BGTZL   rs,Target
		    //
		    // Termination Type:    trmtmipsBraCcLikely
		    //
		    // Registers Used:	    Rs
		    // Registers Set:
		    //
		    // Constraints:	    Rt must be zero

	       iclsImmBraCc4,

		    // Immediate (BraCc-5) Class
		    //
		    // Text Format:	    BGEZ    rs,Target
		    //
		    // Termination Type:    trmtmipsBraCcDef
		    //
		    // Registers Used:	    Rs
		    // Registers Set:
		    //
		    // Note:		    The Rt field is a function code

	       iclsImmBraCc5,

		    // Immediate (BraCc-6) Class
		    //
		    // Text Format:	    BGEZL   rs,Target
		    //
		    // Termination Type:    trmtmipsBraCcLikely
		    //
		    // Registers Used:	    Rs
		    // Registers Set:
		    //
		    // Note:		    The Rt field is a function code

	       iclsImmBraCc6,

		    // Immediate (CallCc-1) Class
		    //
		    // Text Format:	    BGEZAL  rs,Target
		    //
		    // Termination Type:    trmtmipsCallCcDef
		    //
		    // Registers Used:	    Rs
		    // Registers Set:	    R31
		    //
		    // Note:		    The Rt field is a function code

	       iclsImmCallCc1,

		    // Immediate (CallCc-2) Class
		    //
		    // Text Format:	    BGEZALL rs,Target
		    //
		    // Termination Type:    trmtmipsCallCcLikely
		    //
		    // Registers Used:	    Rs
		    // Registers Set:	    R31
		    //
		    // Note:		    The Rt field is a function code

	       iclsImmCallCc2,

		    // Immediate (Performance) Class
		    //
		    // Text Format:	    CACHE   op,offset(rs)
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Rs
		    // Registers Set:
		    //
		    // Note:		    The Rt field stores the op parm

	       iclsImmPerf,

		    // Immediate (Load) Class
		    //
		    // Text Format:	    LB	    rt,offset(rs)
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Rs
		    // Registers Set:	    Rt

	       iclsImmLoad,

		    // Immediate (Load Coprocessor) Class
		    //
		    // Text Format:	    LDC0    rt,offset(rs)
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Rs
		    // Registers Set:	    Coprocessor general register Rt

	       iclsImmLoadCp,

		    // Immediate (LUI) Class
		    //
		    // Text Format:	    LUI     rt,immediate
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:
		    // Registers Set:	    Rt
		    //
		    // Note:		    The Rs field is unused (UNDONE: Must be zero?)

	       iclsImmLui,

		    // Immediate (Store) Class
		    //
		    // Text Format:	    SB	    rt,offset(rs)
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Rs, Rt
		    // Registers Set:

	       iclsImmStore,

		    // Immediate (SC) Class
		    //
		    // Text Format:	    SC	    rt,offset(rs)
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Rs, Rt
		    // Registers Set:	    Rt

	       iclsImmSc,

		    // Immediate (Store Coprocessor) Class
		    //
		    // Text Format:	    SDC0    rt,offset(rs)
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Rs, Coprocessor general register Rt
		    // Registers Set:

	       iclsImmStoreCp,

		    // Immediate (Trap) Class
		    //
		    // Text Format:	    TEQI    rs,immediate
		    //
		    // Termination Type:    trmtmipsTrapCc
		    //
		    // Registers Used:	    Rs
		    // Registers Set:
		    //
		    // Note:		    The Rt field is a function code

	       iclsImmTrap,

		    // Jump Class
		    //
		    // Text Format:	    J	    Target
		    //
		    // Termination Type:    trmtmipsBraDef
		    //
		    // Registers Used:
		    // Registers Set:

	       iclsJump,

		    // Jump (JAL) Class
		    //
		    // Text Format:	    JAL     Target
		    //
		    // Termination Type:    trmtmipsCallDef
		    //
		    // Registers Used:
		    // Registers Set:	    R31

	       iclsJumpJal,

		    // Register Class
		    //
		    // Text Format:	    ADDU    rd,rs,rt
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Rs, Rt
		    // Registers Set:	    Rd
		    //
		    // Constraints:	    Shift ammount must be zero

	       iclsRegister,

		    // Register Class with Condition Code
		    //
		    // Text Format:	    MOVF    rd,rs,cc
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Rs
		    // Registers Set:	    Rd
		    //
		    // Constraints:	    cc represents

	       iclsRegisterCc,

		    // Register Class
		    //
		    // Text Format:	    ADD     rd,rs,rt
		    //
		    // Termination Type:    trmtmipsTrapCc
		    //
		    // Registers Used:	    Rs, Rt
		    // Registers Set:	    Rd
		    //
		    // Constraints:	    Shift ammount must be zero

	       iclsRegTrapCc,

		    // Register (BREAK) Class
		    //
		    // Text Format:	    BREAK   immediate
		    //
		    // Termination Type:    trmtmipsTrap
		    //
		    // Registers Used:
		    // Registers Set:
		    //
		    // Note:		    MIPS does not use an operand for the immediate

	       iclsRegBreak,

		    // Register (JALR) Class
		    //
		    // Text Format:	    JALR    rd,rs
		    //
		    // Termination Type:    trmtmipsCallInd
		    //
		    // Registers Used:	    Rs
		    // Registers Set:	    Rd
		    //
		    // Constraints:	    Rt and shift ammount must be zero

	       iclsRegJalr,

		    // Register (JR) Class
		    //
		    // Text Format:	    JR	    rs
		    //
		    // Termination Type:    trmtmipsBraIndDef
		    //
		    // Registers Used:	    Rs
		    // Registers Set:
		    //
		    // Constraints:	    Rd, Rt, and shift ammount must be zero

	       iclsRegJr,

		    // Register (MFHI) Class
		    //
		    // Text Format:	    MFHI    rd
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    HI
		    // Registers Set:	    Rd
		    //
		    // Constraints:	    Rs, Rt, and shift ammount must be zero

	       iclsRegMfhi,

		    // Register (MFLO) Class
		    //
		    // Text Format:	    MFLO    rd
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    LO
		    // Registers Set:	    Rd
		    //
		    // Constraints:	    Rs, Rt, and shift ammount must be zero

	       iclsRegMflo,

		    // Register (MTHI) Class
		    //
		    // Text Format:	    MTHI    rs
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Rs
		    // Registers Set:	    HI
		    //
		    // Constraints:	    Rt, Rd, and shift ammount must be zero

	       iclsRegMthi,

		    // Register (MTLO) Class
		    //
		    // Text Format:	    MTLO    rs
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Rs
		    // Registers Set:	    LO
		    //
		    // Constraints:	    Rt, Rd, and shift ammount must be zero

	       iclsRegMtlo,

		    // Register (Multiply-Divide) Class
		    //
		    // Text Format:	    DDIV    rs,rt
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Rs, Rt
		    // Registers Set:	    HI, LO
		    //
		    // Constraints:	    Rd and shift ammount must be zero

	       iclsRegMulDiv,

		    // Register (Shift) Class
		    //
		    // Text Format:	    DSLL    rd,rt,sa
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Rt
		    // Registers Set:	    Rd
		    //
		    // Constraints:	    The Rs field must be zero

	       iclsRegShift,

		    // Register (Shift Variable) Class
		    //
		    // Text Format:	    DSLLV   rd,rt,rs
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Rs, Rt
		    // Registers Set:	    Rd
		    //
		    // Constraints:	    Shift ammount must be zero

	       iclsRegShiftVar,

		    // Register (SYNC) Class
		    //
		    // Text Format:	    SYNC
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:
		    // Registers Set:
		    //
		    // Constraints:	    Rs, Rt, Rd, and shift ammount must be zero

	       iclsRegSync,

		    // Register (SYSCALL) Class
		    //
		    // Text Format:	    SYSCALL
		    //
		    // Termination Type:    trmtmipsTrap
		    //
		    // Registers Used:
		    // Registers Set:
		    //
		    // Constraints:	    Rs, Rt, Rd, and shift ammount must be zero

	       iclsRegSyscall,

		    // Register (Trap) Class
		    //
		    // Text Format:	    TEQ     rs,rt,immediate
		    //
		    // Termination Type:    trmtmipsTrapCc
		    //
		    // Registers Used:	    Rs, Rt
		    // Registers Set:
		    //
		    // Note:		    Rd and shift ammount contain the immediate
		    // Note:		    MIPS does not use an operand for the immediate

	       iclsRegTrap,

		    // Immediate (BraCc-7) Class
		    //
		    // Coprocessor
		    //
		    // Text Format:	    BCzF    cc,Target
		    //
		    // Termination Type:    trmtmipsBraCcDef
		    //
		    // Registers Used:
		    // Registers Set:
		    //
		    // Note:		    The coprocessor z condition is referenced
		    // Note:		    The Rs and Rt fields are function codes
		    // Note:		    The coprocessor must be set in the mnemonic

	       iclsImmBraCc7,

		    // Immediate (BraCc-8) Class
		    //
		    // Coprocessor
		    //
		    // Text Format:	    BCzF    Target
		    //
		    // Termination Type:    trmtmipsBraCcDef
		    //
		    // Registers Used:
		    // Registers Set:
		    //
		    // Note:		    The coprocessor z condition is referenced
		    // Note:		    The Rs and Rt fields are function codes
		    // Note:		    The coprocessor must be set in the mnemonic

	       iclsImmBraCc8,

		    // Register (CFCz) Class
		    //
		    // Coprocessor
		    //
		    // Text Format:	    CFCz    rt,rd
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Coprocessor control register Rd
		    // Registers Set:	    Rt
		    //
		    // Constraints:	    Shift ammount and function must be zero
		    //
		    // Note:		    The coprocessor must be set in the mnemonic

	       iclsRegCfc,

		    // Register (CTCz) Class
		    //
		    // Coprocessor
		    //
		    // Text Format:	    CTCz    rt,rd
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Rt
		    // Registers Set:	    Coprocessor control register Rd
		    //
		    // Constraints:	    Shift ammount and function must be zero
		    //
		    // Note:		    The coprocessor must be set in the mnemonic

	       iclsRegCtc,

		    // Register (MFCz) Class
		    //
		    // Coprocessor
		    //
		    // Text Format:	    DMFCz   rt,rd
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Coprocessor general register Rd
		    // Registers Set:	    Rt
		    //
		    // Constraints:	    Shift ammount and function must be zero
		    //
		    // Note:		    The coprocessor must be set in the mnemonic

	       iclsRegMfc,

		    // Register (MTCz) Class
		    //
		    // Coprocessor
		    //
		    // Text Format:	    DMTCz   rt,rd
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Rt
		    // Registers Set:	    Coprocessor general register Rd
		    //
		    // Constraints:	    Shift ammount and function must be zero
		    //
		    // Note:		    The coprocessor must be set in the mnemonic

	       iclsRegMtc,

		    // Register (Cp0) Class
		    //
		    // Coprocessor
		    //
		    // Text Format:	    TLBP
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:
		    // Registers Set:
		    //
		    // Constraints:	    This is valid for coprocessor 0 only
		    // Constraints:	    Rs must be 10000b
		    // Constraints:	    Rt, Rd, and shift ammount must be zero
		    //
		    // Note:		    The coprocessor must be set in the mnemonic

	       iclsRegCp0,

		    // Register (ERET) Class
		    //
		    // Coprocessor
		    //
		    // Text Format:	    ERET
		    //
		    // Termination Type:    trmtmipsBraInd
		    //
		    // Registers Used:
		    // Registers Set:
		    //
		    // Constraints:	    This is valid for coprocessor 0 only
		    // Constraints:	    Rs must be 10000b
		    // Constraints:	    Rt, Rd, and shift ammount must be zero
		    //
		    // Note:		    The coprocessor must be set in the mnemonic

	       iclsRegEret,

		    // Register (Float-1) Class
		    //
		    // Coprocessor
		    //
		    // Text Format:	    ADD.S  fd,fs,ft
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Coprocessor general registers Fs and Ft
		    // Registers Set:	    Coprocessor general register Fd
		    //
		    // Constraints:	    Format must be Single or Double

	       iclsRegFloat1,

		    // Register (Float-2) Class
		    //
		    // Coprocessor
		    //
		    // Text Format:	    SQRT.S fd,fs
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Coprocessor general register Fs
		    // Registers Set:	    Coprocessor general register Fd
		    //
		    // Constraints:	    Format must be Single or Double
		    // Constraints:	    Ft must be zero

	       iclsRegFloat2,

		    // Register (Float-3) Class
		    //
		    // Coprocessor
		    //
		    // Text Format:	    MOV.S  fd,fs
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Coprocessor general registers Fs
		    // Registers Set:	    Coprocessor general register Fd
		    //
		    // Constraints:	    Format must be Single or Double or Word
		    // Constraints:	    Ft must be zero

	       iclsRegFloat3,

		    // Register (Float-4) Class
		    //
		    // Coprocessor
		    //
		    // Text Format:	    CVT.S  fd,fs
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Coprocessor general registers Fs
		    // Registers Set:	    Coprocessor general register Fd
		    //
		    // Constraints:	    Format must be Double or Word
		    // Constraints:	    Ft must be zero

	       iclsRegFloat4,

		    // Register (Float-5) Class
		    //
		    // Coprocessor
		    //
		    // Text Format:	    CVT.D  fd,fs
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Coprocessor general registers Fs
		    // Registers Set:	    Coprocessor general register Fd
		    //
		    // Constraints:	    Format must be Single or Word
		    // Constraints:	    Ft must be zero

	       iclsRegFloat5,

		    // Register (Float-6) Class
		    //
		    // Coprocessor
		    //
		    // Text Format:	    C.F.S  cc,fs,ft
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Coprocessor general register Fs
		    // Registers Set:	    Coprocessor general register Fd
		    //
		    // Constraints:	    Format must be Single or Double
		    // Constraints:	    Fd must be zero

	       iclsRegFloat6,

		    // Register (Float-7) Class
		    //
		    // Coprocessor
		    //
		    // Text Format:	    MOVN.S fd,fs,rt
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Rt, Coprocessor general register Fs
		    // Registers Set:	    Coprocessor general register Fd
		    //
		    // Constraints:	    UNDONE

	       iclsRegFloat7,

		    // Register (Float-8) Class
		    //
		    // Coprocessor
		    //
		    // Text Format:	    MOVF.S fd,fs,cc
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Coprocessor general registers Fs
		    // Registers Set:	    Coprocessor general register Fd
		    //
		    // Constraints:	    UNDONE

	       iclsRegFloat8,

		    // Register (Float-9) Class
		    //
		    // Coprocessor
		    //
		    // Text Format:	    C.F.S  fs,ft
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Coprocessor general register Fs
		    // Registers Set:	    Coprocessor general register Fd
		    //
		    // Constraints:	    Format must be Single or Double
		    // Constraints:	    Fd must be zero

	       iclsRegFloat9,

		    // Register (Float) Class with Cc Trap termination
		    //
		    // Text Format:	    MADD   fd,fr,fs,ft
		    //
		    // Termination Type:    trmtmipsTrapCc
		    //
		    // Registers Used:	    Fs, Ft, Fr
		    // Registers Set:	    Fd
		    //
		    // Constraints:

	       iclsRegFloat10,

		    // Index Prefetched Class
		    //
		    // Text Format:	    PREFX  hint,index(rs)
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    Rs
		    // Registers Set:
		    //
		    // Note:		    The Rd field stores the hint parm
		    //			    The Rt field stores the index parm

	       iclsIndexPref,

		    // Index Load Class
		    //
		    // Text Format:	    LDXC1  fd,index(rs)
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    rs, fd
		    // Registers Set:
		    //
		    // Note:		    The Rt field stores the index parm

	       iclsIndexLoad,

		    // Index Store Class
		    //
		    // Text Format:	    SDXC1  fs,index(rs)
		    //
		    // Termination Type:    trmtmipsFallThrough
		    //
		    // Registers Used:	    rs, fs
		    // Registers Set:
		    //
		    // Note:		    The Rt field stores the index parm

	       iclsIndexStore,
	    };

	    struct CLS
	    {
	       BYTE	   trmtmips;
	       BYTE	   rgopcls[4];	  // Operand class for each operand
	    };

	    struct OPCD
	    {
	       const char  *szMnemonic;
	       BYTE	   icls;
	    };

   static   const TRMT mptrmtmipstrmt[];

   static   const CLS rgcls[];

   static   const OPCD rgopcd[];
   static   const OPCD rgopcdSpecial[];
   static   const OPCD rgopcdRegimm[];
   static   const OPCD rgopcdCop[];
   static   const OPCD rgopcdBc[];
   static   const OPCD rgopcdCop1x[];
   static   const OPCD rgopcdCp0[];
   static   const OPCD rgopcdCp1[];

   static   const char rgszFormat[5][4];
   static   const char * const rgszGpr[32];

   static   const OPCD opcdB;
   static   const OPCD opcdNop;

	    void FormatHex(ostream&, DWORD) const;
	    void FormatOperand(ostream&, OPCLS opcls) const;
	    void FormatRegRel(ostream&, REG, DWORD) const;
	    bool FValidOperand(size_t) const;
   static   const OPCD *PopcdDecode(MIPSIW);
	    const OPCD *PopcdPseudoOp(OPCD *, char *) const;
	    TRMTMIPS Trmtmips() const;

	    MIPSIW m_mipsiw;
	    const OPCD *m_popcd;
};