opcode.h 7.66 KB

/**************************************************************************
 *                                                                        *
 *               Copyright (C) 1994, Silicon Graphics, Inc.               *
 *                                                                        *
 *  These coded instructions, statements, and computer programs  contain  *
 *  unpublished  proprietary  information of Silicon Graphics, Inc., and  *
 *  are protected by Federal copyright  law.  They  may not be disclosed  *
 *  to  third  parties  or copied or duplicated in any form, in whole or  *
 *  in part, without the prior written consent of Silicon Graphics, Inc.  *
 *                                                                        *
 *************************************************************************/

/*
 * File:	opcode.h
 * Creator:	hsa@sgi.com
 * Create Date:	Thu Feb 10 15:04:56 PST 1994
 *
 * This file contains all the definitions for the RSP opcodes, 
 * plus some macros to operate on them (fetch bits, etc.).
 *
 */

#ifndef _rsp_opcode_h_
#define _rsp_opcode_h_ 1
#include <assert.h>

#define ExtractBits(inst, high, low) ((inst >> low) & (0xffffffff>>(31-(high-low))))
#define ExtractOpcode(inst)	ExtractBits((inst), 31, 26)
#define LoadField(inst, high, low, bits) 				\
    {									\
        unsigned int mask;		     				\
        assert(high>=low);						\
	mask = (0xffffffff>>(31-high)) ^ (0x7fffffff>>(31-low));	\
	(inst) = ((inst) & ~mask) | (mask & (bits<<low));		\
    }


/*
 * The RSP SU instruction set is a 32-bit version of a subset of
 * the MIPS R4000 instruction set.
 *
 * Instructions not implemented include:
 *
 *	Load/Store:	LWL, LWR, SWL, SWR, LL, SC
 *	Special:	SYSCALL, BREAK, TRAP (all)
 *
 * additional RSP SU instructions include:
 *
 *	XXX breakpoint, complete executing instruction(s), clear busy.
 *	XXX idle, an internally synthesized instruction, executed
 *		after busy is cleared.
 *
 * The SU does not implement CP0 (system control), CP1 (floating
 * point), or CP3 (64-bit instructions). [note: CP2 is used for
 * the VU]
 *
 */

/*
 * opcodes:
 *
 * The MIPS R4000 instructions look like this:
 *
 *	32      26 25                 0
 *      -------------------------------
 *      |  op     | <<other stuff>>    |
 *      -------------------------------
 *
 * If op == CP2 (0x12) this is a VU instruction.
 * If op == special (0x00) the real opcode is in the lower 6 bits.
 * If op == regimm (0x01) the real opcode is somewhere in the middle.
 *
 */
typedef enum
{
    /* identify subtypes of opcodes: */
    rsp_SPECIAL	= 0x00,
    rsp_REGIMM	= 0x01,

    /* jump and branch instructions: */
    rsp_J	= 0x02,
    rsp_JAL	= 0x03,
    rsp_BEQ	= 0x04,
    rsp_BNE	= 0x05,
    rsp_BLEZ	= 0x06,
    rsp_BGTZ	= 0x07,

    /* arithmetic instructions (ALU immediate): */
    rsp_ADDI	= 0x08,
    rsp_ADDIU	= 0x09,
    rsp_SLTI	= 0x0a,
    rsp_SLTIU	= 0x0b,
    rsp_ANDI	= 0x0c,
    rsp_ORI	= 0x0d,
    rsp_XORI	= 0x0e,
    rsp_LUI	= 0x0f,

    /* CP0 instruction: */
    rsp_COP0	= 0x10,

    /* CP2 (VU) instruction: */
    rsp_COP2	= 0x12,

    /* load and store instructions: */
    rsp_LB	= 0x20,
    rsp_LBU	= 0x24,
    rsp_LH	= 0x21,
    rsp_LHU	= 0x25,
    rsp_LW	= 0x23,
    rsp_SB	= 0x28,
    rsp_SH	= 0x29,
    rsp_SW	= 0x2b,

    /* CP2 coprocessor instructions: (uses sub-opcodes below) */
    rsp_LWC2	= 0x32,
    rsp_SWC2	= 0x3a
} rsp_suOpcode_t;

/*
 * SPECIAL functions:
 */
typedef enum
{
    /* arithmetic instructions (3-operand, R-type): */
    rsp_ADD	= 0x20,
    rsp_ADDU	= 0x21,
    rsp_SUB	= 0x22,
    rsp_SUBU	= 0x23,
    rsp_SLT	= 0x2a,
    rsp_SLTU	= 0x2b,
    rsp_AND	= 0x24,
    rsp_OR	= 0x25,
    rsp_XOR	= 0x26,
    rsp_NOR	= 0x27,

    /* arithmetic instructions (multiply and divide): */
    rsp_MULT	= 0x18,
    rsp_MULTU	= 0x19,
    rsp_DIV	= 0x1a,
    rsp_DIVU	= 0x1b,
    rsp_MFHI	= 0x10,
    rsp_MTHI	= 0x11,
    rsp_MFLO	= 0x12,
    rsp_MTLO	= 0x13,

    /* jump and branch instructions: */
    rsp_JR	= 0x08,
    rsp_JALR	= 0x09,

    /* breakpoint (not in RSP spec, useful for debuggin) */
    rsp_BREAK	= 0x0d,

    /* shift instructions: */
    rsp_SLL	= 0x00,
    rsp_SRL	= 0x02,
    rsp_SRA	= 0x03,
    rsp_SLLV	= 0x04,
    rsp_SRLV	= 0x06,
    rsp_SRAV	= 0x07
} rsp_suOpSpecial_t;

/*
 * REGIMM instructions:
 */
typedef enum
{
    /* jump and branch instructions: */
    rsp_BLTZ	= 0x00,
    rsp_BGEZ	= 0x01,
    rsp_BLTZAL	= 0x10,
    rsp_BGEZAL	= 0x11
} rsp_suOpRegimm_t;

/*
 * CP0 coprocessor instructions: (these are still SU instructions)
 */
typedef enum
{
    rsp_MFC0	= 0x00,
    rsp_MTC0	= 0x04,
    rsp_BC0	= 0x08 	/* BC0T, BC0F */
} rsp_suOpCop0_t;

/*
 * CP2 coprocessor instructions: (these are still SU instructions)
 */
typedef enum
{
    rsp_MFC2	= 0x00,
    rsp_CFC2	= 0x02,
    rsp_MTC2	= 0x04,
    rsp_CTC2	= 0x06,
    rsp_BC	= 0x08 	/* BC2T, BC2F, ... RSP does not support these */
} rsp_suOpCop2_t;

/*
 * VU Load and Store sub-opcodes.
 * LWC2/SWC2 ...
 */
typedef enum
{
    /* normal loads/stores: */
    rsp_LSB	= 0x00,
    rsp_LSS	= 0x01,
    rsp_LSL	= 0x02,
    rsp_LSD	= 0x03,
    rsp_LSQ	= 0x04,
    rsp_LSR	= 0x05,
    rsp_LSP	= 0x06,
    rsp_LSU	= 0x07,
    rsp_LSH	= 0x08,
    rsp_LSF	= 0x09,
    rsp_LSW	= 0x0a,
    rsp_LST	= 0x0b,
    /* extended loads/stores: (obsolete?) */
    rsp_LSBE	= 0x10,
    rsp_LSSE	= 0x11,
    rsp_LSLE	= 0x12,
    rsp_LSDE	= 0x13,
    rsp_LSQE	= 0x14,
    rsp_LSPE	= 0x15,
    rsp_LSUE	= 0x16,
    rsp_LSHE	= 0x17,
    rsp_LSFE	= 0x18,
    rsp_LSAE	= 0x19,
    rsp_LSTE	= 0x1a
} rsp_vuLSOp_t;

/*
 * These are the RSP VU operate instructions, which follow the general 
 * organization of a MIPS coprocessor, with instructions mapped into CP2.
 *
 * If the opcode of the instructon is COP2 and bit 25 of the instruction
 * is set, then it is a VU operate and we pass this instruction to the VU for 
 * further decoding and execution.
 *
 * The lower 6 bits of the instruction will hold the VU opcode, which
 * are listed below:
 *
 */
typedef enum
{
    /* multiply instructions: */
    rsp_VMULF	= 0x00,	/* opcode bits: 00 a fff 				*/
    rsp_VMACF	= 0x08, /* where 00 is the mult op, a is accumulator or not, 	*/
    rsp_VMULU	= 0x01, /* and fff is the format. 				*/
    rsp_VMACU	= 0x09,
    rsp_VRNDP	= 0x02,
    rsp_VRNDN	= 0x0a,
    rsp_VMULQ	= 0x03,
    rsp_VMACQ	= 0x0b,
    rsp_VMUDL	= 0x04,
    rsp_VMADL	= 0x0c,
    rsp_VMUDM	= 0x05,
    rsp_VMADM	= 0x0d,
    rsp_VMUDN	= 0x06,
    rsp_VMADN	= 0x0e,
    rsp_VMUDH	= 0x07,
    rsp_VMADH	= 0x0f,

    /* add instructions: */
    rsp_VADD	= 0x10,
    rsp_VSUB	= 0x11,
    rsp_VSUT	= 0x12,
    rsp_VABS	= 0x13,
    rsp_VADDC	= 0x14,
    rsp_VSUBC	= 0x15,
    rsp_VADDB	= 0x16,
    rsp_VSUBB	= 0x17,
    rsp_VACCB	= 0x18,
    rsp_VSUCB	= 0x19,
    rsp_VSAD	= 0x1a,
    rsp_VSAC	= 0x1b,
    rsp_VSUM	= 0x1c,
    rsp_VSAW	= 0x1d,

    /* select instructions: */
    rsp_VLT	= 0x20,
    rsp_VEQ	= 0x21,
    rsp_VNE	= 0x22,
    rsp_VGE	= 0x23,
    rsp_VCL	= 0x24,
    rsp_VCH	= 0x25,
    rsp_VCR	= 0x26,
    rsp_VMRG	= 0x27,

    /* logical instructions: */
    rsp_VAND	= 0x28,
    rsp_VNAND	= 0x29,
    rsp_VOR	= 0x2a,
    rsp_VNOR	= 0x2b,
    rsp_VXOR	= 0x2c,
    rsp_VNXOR	= 0x2d,

    /* divide instructions: */
    rsp_VRCP	= 0x30,	/* opcode bits: 110 f tt 			*/
    rsp_VRCPL	= 0x31, /* where 110 is the div op, f is the function 	*/
    rsp_VRCPH	= 0x32, /* (reciprocal or reciprocal squared), and tt is*/
    rsp_VRSQ	= 0x34, /* the type, move/high/low			*/
    rsp_VRSQL	= 0x35,
    rsp_VRSQH	= 0x36,
    rsp_VNOP	= 0x37,
    rsp_VMOV	= 0x33,

    /* pack instructions: */
    /* bit 2 is pack/unpack */
    rsp_VINST	= 0x3c,
    rsp_VEXTT	= 0x38,
    rsp_VINSQ	= 0x3d,
    rsp_VEXTQ	= 0x39,
    rsp_VINSN	= 0x3e,
    rsp_VEXTN	= 0x3a,

    rsp_VNULLOP	= 0x3f
} rsp_vuOpcode_t;

#endif