/*
- * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
- * ============================================
*
- * MXU (full name: MIPS eXtension/enhanced Unit) is an SIMD extension of MIPS32
+ * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
+ * ============================================
+ *
+ *
+ * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
* instructions set. It is designed to fit the needs of signal, graphical and
* video processing applications. MXU instruction set is used in Xburst family
* of microprocessors by Ingenic.
* MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
* the control register.
*
- * The notation used in MXU assembler mnemonics
- * --------------------------------------------
*
- * Registers:
+ * The notation used in MXU assembler mnemonics
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * Register operands:
*
* XRa, XRb, XRc, XRd - MXU registers
* Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
*
- * Subfields:
+ * Non-register operands:
*
- * aptn1 - 1-bit accumulate add/subtract pattern
- * aptn2 - 2-bit accumulate add/subtract pattern
- * eptn2 - 2-bit execute add/subtract pattern
- * optn2 - 2-bit operand pattern
- * optn3 - 3-bit operand pattern
- * sft4 - 4-bit shift amount
- * strd2 - 2-bit stride amount
+ * aptn1 - 1-bit accumulate add/subtract pattern
+ * aptn2 - 2-bit accumulate add/subtract pattern
+ * eptn2 - 2-bit execute add/subtract pattern
+ * optn2 - 2-bit operand pattern
+ * optn3 - 3-bit operand pattern
+ * sft4 - 4-bit shift amount
+ * strd2 - 2-bit stride amount
*
* Prefixes:
*
- * <Operation parallel level><Operand size>
- * S 32
- * D 16
- * Q 8
- *
- * Suffixes:
- *
- * E - Expand results
- * F - Fixed point multiplication
- * L - Low part result
- * R - Doing rounding
- * V - Variable instead of immediate
- * W - Combine above L and V
+ * Level of parallelism: Operand size:
+ * S - single operation at a time 32 - word
+ * D - two operations in parallel 16 - half word
+ * Q - four operations in parallel 8 - byte
*
* Operations:
*
* SCOP - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
* XOR - Logical bitwise 'exclusive or' operation
*
+ * Suffixes:
+ *
+ * E - Expand results
+ * F - Fixed point multiplication
+ * L - Low part result
+ * R - Doing rounding
+ * V - Variable instead of immediate
+ * W - Combine above L and V
+ *
+ *
+ * The list of MXU instructions grouped by functionality
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
* Load/Store instructions Multiplication instructions
* ----------------------- ---------------------------
*
* Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
*
*
+ * The opcode organization of MXU instructions
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
+ * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
+ * other bits up to the instruction level is as follows:
+ *
* bits
* 05..00
*
* │ 20..18
* ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
* │ ├─ 001 ─ OPC_MXU_S32ALN
- * ├─ 101000 ─ OPC_MXU_LXB ├─ 010 ─ OPC_MXU_S32ALNI
- * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_S32NOR
- * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_S32AND
- * ├─ 101011 ─ OPC_MXU_S16STD ├─ 101 ─ OPC_MXU_S32OR
- * ├─ 101100 ─ OPC_MXU_S16LDI ├─ 110 ─ OPC_MXU_S32XOR
- * ├─ 101101 ─ OPC_MXU_S16SDI └─ 111 ─ OPC_MXU_S32LUI
+ * │ ├─ 010 ─ OPC_MXU_S32ALNI
+ * │ ├─ 011 ─ OPC_MXU_S32LUI
+ * │ ├─ 100 ─ OPC_MXU_S32NOR
+ * │ ├─ 101 ─ OPC_MXU_S32AND
+ * │ ├─ 110 ─ OPC_MXU_S32OR
+ * │ └─ 111 ─ OPC_MXU_S32XOR
+ * │
+ * │ 7..5
+ * ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
+ * │ ├─ 001 ─ OPC_MXU_LXH
+ * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_LXW
+ * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_LXBU
+ * ├─ 101011 ─ OPC_MXU_S16STD └─ 101 ─ OPC_MXU_LXHU
+ * ├─ 101100 ─ OPC_MXU_S16LDI
+ * ├─ 101101 ─ OPC_MXU_S16SDI
* ├─ 101110 ─ OPC_MXU_S32M2I
* ├─ 101111 ─ OPC_MXU_S32I2M
* ├─ 110000 ─ OPC_MXU_D32SLL
* ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
* ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
* │ ├─ 100 ─ OPC_MXU_Q16SLRV
- * ├─ 110110 ─ OPC_MXU__POOL17 ─┴─ 101 ─ OPC_MXU_Q16SARV
+ * ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
* │
* ├─ 110111 ─ OPC_MXU_Q16SAR
* │ 23..22
- * ├─ 111000 ─ OPC_MXU__POOL18 ─┬─ 00 ─ OPC_MXU_Q8MUL
+ * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
* │ └─ 01 ─ OPC_MXU_Q8MULSU
* │
* │ 20..18
- * ├─ 111001 ─ OPC_MXU__POOL19 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
+ * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
* │ ├─ 001 ─ OPC_MXU_Q8MOVN
* │ ├─ 010 ─ OPC_MXU_D16MOVZ
* │ ├─ 011 ─ OPC_MXU_D16MOVN
* │ ├─ 100 ─ OPC_MXU_S32MOVZ
- * │ └─ 101 ─ OPC_MXU_S32MOV
+ * │ └─ 101 ─ OPC_MXU_S32MOVN
* │
* │ 23..22
- * ├─ 111010 ─ OPC_MXU__POOL20 ─┬─ 00 ─ OPC_MXU_Q8MAC
+ * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
* │ └─ 10 ─ OPC_MXU_Q8MACSU
* ├─ 111011 ─ OPC_MXU_Q16SCOP
* ├─ 111100 ─ OPC_MXU_Q8MADL
* └─ 111111 ─ <not assigned> (overlaps with SDBBP)
*
*
- * Compiled after:
+ * Compiled after:
*
* "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
- * Programming Manual", Ingenic Semiconductor Co, Ltd., 2017
+ * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
*/
enum {
OPC_MXU_S8SDI = 0x25,
OPC_MXU__POOL15 = 0x26,
OPC_MXU__POOL16 = 0x27,
- OPC_MXU_LXB = 0x28,
+ OPC_MXU__POOL17 = 0x28,
/* not assigned 0x29 */
OPC_MXU_S16LDD = 0x2A,
OPC_MXU_S16STD = 0x2B,
OPC_MXU_D32SAR = 0x33,
OPC_MXU_Q16SLL = 0x34,
OPC_MXU_Q16SLR = 0x35,
- OPC_MXU__POOL17 = 0x36,
+ OPC_MXU__POOL18 = 0x36,
OPC_MXU_Q16SAR = 0x37,
- OPC_MXU__POOL18 = 0x38,
- OPC_MXU__POOL19 = 0x39,
- OPC_MXU__POOL20 = 0x3A,
+ OPC_MXU__POOL19 = 0x38,
+ OPC_MXU__POOL20 = 0x39,
+ OPC_MXU__POOL21 = 0x3A,
OPC_MXU_Q16SCOP = 0x3B,
OPC_MXU_Q8MADL = 0x3C,
OPC_MXU_S32SFL = 0x3D,
OPC_MXU_D32SARW = 0x00,
OPC_MXU_S32ALN = 0x01,
OPC_MXU_S32ALNI = 0x02,
- OPC_MXU_S32NOR = 0x03,
- OPC_MXU_S32AND = 0x04,
- OPC_MXU_S32OR = 0x05,
- OPC_MXU_S32XOR = 0x06,
- OPC_MXU_S32LUI = 0x07,
+ OPC_MXU_S32LUI = 0x03,
+ OPC_MXU_S32NOR = 0x04,
+ OPC_MXU_S32AND = 0x05,
+ OPC_MXU_S32OR = 0x06,
+ OPC_MXU_S32XOR = 0x07,
};
/*
* MXU pool 17
*/
+enum {
+ OPC_MXU_LXB = 0x00,
+ OPC_MXU_LXH = 0x01,
+ OPC_MXU_LXW = 0x03,
+ OPC_MXU_LXBU = 0x04,
+ OPC_MXU_LXHU = 0x05,
+};
+
+/*
+ * MXU pool 18
+ */
enum {
OPC_MXU_D32SLLV = 0x00,
OPC_MXU_D32SLRV = 0x01,
};
/*
- * MXU pool 18
+ * MXU pool 19
*/
enum {
OPC_MXU_Q8MUL = 0x00,
};
/*
- * MXU pool 19
+ * MXU pool 20
*/
enum {
OPC_MXU_Q8MOVZ = 0x00,
};
/*
- * MXU pool 20
+ * MXU pool 21
*/
enum {
OPC_MXU_Q8MAC = 0x00,
* MTSAH rs, immediate Move Halfword Count to Shift Amount Register
* PROT3W rd, rt Parallel Rotate 3 Words
*
- * The TX79-specific Multimedia Instruction encodings
- * ==================================================
+ * MMI (MultiMedia Instruction) encodings
+ * ======================================
*
- * TX79 Multimedia Instruction encoding table keys:
+ * MMI instructions encoding table keys:
*
* * This code is reserved for future use. An attempt to execute it
* causes a Reserved Instruction exception.
* DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
* to execute it causes a Reserved Instruction exception.
*
- * TX79 Multimedia Instructions encoded by opcode field (MMI, LQ, SQ):
+ * MMI instructions encoded by opcode field (MMI, LQ, SQ):
*
* 31 26 0
* +--------+----------------------------------------+
*/
enum {
- TX79_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
- TX79_LQ = 0x1E << 26, /* Same as OPC_MSA */
- TX79_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
+ MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
+ MMI_OPC_LQ = 0x1E << 26, /* Same as OPC_MSA */
+ MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
};
/*
- * TX79 Multimedia Instructions with opcode field = MMI:
+ * MMI instructions with opcode field = MMI:
*
* 31 26 5 0
* +--------+-------------------------------+--------+
* 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
*/
-#define MASK_TX79_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
+#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
enum {
- TX79_MMI_MADD = 0x00 | TX79_CLASS_MMI, /* Same as OPC_MADD */
- TX79_MMI_MADDU = 0x01 | TX79_CLASS_MMI, /* Same as OPC_MADDU */
- TX79_MMI_PLZCW = 0x04 | TX79_CLASS_MMI,
- TX79_MMI_CLASS_MMI0 = 0x08 | TX79_CLASS_MMI,
- TX79_MMI_CLASS_MMI2 = 0x09 | TX79_CLASS_MMI,
- TX79_MMI_MFHI1 = 0x10 | TX79_CLASS_MMI, /* Same minor as OPC_MFHI */
- TX79_MMI_MTHI1 = 0x11 | TX79_CLASS_MMI, /* Same minor as OPC_MTHI */
- TX79_MMI_MFLO1 = 0x12 | TX79_CLASS_MMI, /* Same minor as OPC_MFLO */
- TX79_MMI_MTLO1 = 0x13 | TX79_CLASS_MMI, /* Same minor as OPC_MTLO */
- TX79_MMI_MULT1 = 0x18 | TX79_CLASS_MMI, /* Same minor as OPC_MULT */
- TX79_MMI_MULTU1 = 0x19 | TX79_CLASS_MMI, /* Same minor as OPC_MULTU */
- TX79_MMI_DIV1 = 0x1A | TX79_CLASS_MMI, /* Same minor as OPC_DIV */
- TX79_MMI_DIVU1 = 0x1B | TX79_CLASS_MMI, /* Same minor as OPC_DIVU */
- TX79_MMI_MADD1 = 0x20 | TX79_CLASS_MMI,
- TX79_MMI_MADDU1 = 0x21 | TX79_CLASS_MMI,
- TX79_MMI_CLASS_MMI1 = 0x28 | TX79_CLASS_MMI,
- TX79_MMI_CLASS_MMI3 = 0x29 | TX79_CLASS_MMI,
- TX79_MMI_PMFHL = 0x30 | TX79_CLASS_MMI,
- TX79_MMI_PMTHL = 0x31 | TX79_CLASS_MMI,
- TX79_MMI_PSLLH = 0x34 | TX79_CLASS_MMI,
- TX79_MMI_PSRLH = 0x36 | TX79_CLASS_MMI,
- TX79_MMI_PSRAH = 0x37 | TX79_CLASS_MMI,
- TX79_MMI_PSLLW = 0x3C | TX79_CLASS_MMI,
- TX79_MMI_PSRLW = 0x3E | TX79_CLASS_MMI,
- TX79_MMI_PSRAW = 0x3F | TX79_CLASS_MMI,
+ MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
+ MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
+ MMI_OPC_PLZCW = 0x04 | MMI_OPC_CLASS_MMI,
+ MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
+ MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
+ MMI_OPC_MFHI1 = 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFHI */
+ MMI_OPC_MTHI1 = 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTHI */
+ MMI_OPC_MFLO1 = 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFLO */
+ MMI_OPC_MTLO1 = 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTLO */
+ MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
+ MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
+ MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */
+ MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
+ MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI,
+ MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
+ MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
+ MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
+ MMI_OPC_PMFHL = 0x30 | MMI_OPC_CLASS_MMI,
+ MMI_OPC_PMTHL = 0x31 | MMI_OPC_CLASS_MMI,
+ MMI_OPC_PSLLH = 0x34 | MMI_OPC_CLASS_MMI,
+ MMI_OPC_PSRLH = 0x36 | MMI_OPC_CLASS_MMI,
+ MMI_OPC_PSRAH = 0x37 | MMI_OPC_CLASS_MMI,
+ MMI_OPC_PSLLW = 0x3C | MMI_OPC_CLASS_MMI,
+ MMI_OPC_PSRLW = 0x3E | MMI_OPC_CLASS_MMI,
+ MMI_OPC_PSRAW = 0x3F | MMI_OPC_CLASS_MMI,
};
/*
- * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI0:
+ * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
*
* 31 26 10 6 5 0
* +--------+----------------------+--------+--------+
* 7 111 | * | * | PEXT5 | PPAC5
*/
-#define MASK_TX79_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
+#define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
enum {
- TX79_MMI0_PADDW = (0x00 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PSUBW = (0x01 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PCGTW = (0x02 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PMAXW = (0x03 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PADDH = (0x04 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PSUBH = (0x05 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PCGTH = (0x06 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PMAXH = (0x07 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PADDB = (0x08 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PSUBB = (0x09 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PCGTB = (0x0A << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PADDSW = (0x10 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PSUBSW = (0x11 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PEXTLW = (0x12 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PPACW = (0x13 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PADDSH = (0x14 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PSUBSH = (0x15 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PEXTLH = (0x16 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PPACH = (0x17 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PADDSB = (0x18 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PSUBSB = (0x19 << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PEXTLB = (0x1A << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PPACB = (0x1B << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PEXT5 = (0x1E << 6) | TX79_MMI_CLASS_MMI0,
- TX79_MMI0_PPAC5 = (0x1F << 6) | TX79_MMI_CLASS_MMI0,
+ MMI_OPC_0_PADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PSUBW = (0x01 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PCGTW = (0x02 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PMAXW = (0x03 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PADDH = (0x04 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PSUBH = (0x05 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PCGTH = (0x06 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PMAXH = (0x07 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PADDB = (0x08 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PSUBB = (0x09 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PCGTB = (0x0A << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PADDSW = (0x10 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PSUBSW = (0x11 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PEXTLW = (0x12 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PPACW = (0x13 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PADDSH = (0x14 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PSUBSH = (0x15 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PEXTLH = (0x16 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PPACH = (0x17 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PADDSB = (0x18 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PSUBSB = (0x19 << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PEXTLB = (0x1A << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PPACB = (0x1B << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PEXT5 = (0x1E << 6) | MMI_OPC_CLASS_MMI0,
+ MMI_OPC_0_PPAC5 = (0x1F << 6) | MMI_OPC_CLASS_MMI0,
};
/*
- * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI1:
+ * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
*
* 31 26 10 6 5 0
* +--------+----------------------+--------+--------+
* 7 111 | * | * | * | *
*/
-#define MASK_TX79_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
+#define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
enum {
- TX79_MMI1_PABSW = (0x01 << 6) | TX79_MMI_CLASS_MMI1,
- TX79_MMI1_PCEQW = (0x02 << 6) | TX79_MMI_CLASS_MMI1,
- TX79_MMI1_PMINW = (0x03 << 6) | TX79_MMI_CLASS_MMI1,
- TX79_MMI1_PADSBH = (0x04 << 6) | TX79_MMI_CLASS_MMI1,
- TX79_MMI1_PABSH = (0x05 << 6) | TX79_MMI_CLASS_MMI1,
- TX79_MMI1_PCEQH = (0x06 << 6) | TX79_MMI_CLASS_MMI1,
- TX79_MMI1_PMINH = (0x07 << 6) | TX79_MMI_CLASS_MMI1,
- TX79_MMI1_PCEQB = (0x0A << 6) | TX79_MMI_CLASS_MMI1,
- TX79_MMI1_PADDUW = (0x10 << 6) | TX79_MMI_CLASS_MMI1,
- TX79_MMI1_PSUBUW = (0x11 << 6) | TX79_MMI_CLASS_MMI1,
- TX79_MMI1_PEXTUW = (0x12 << 6) | TX79_MMI_CLASS_MMI1,
- TX79_MMI1_PADDUH = (0x14 << 6) | TX79_MMI_CLASS_MMI1,
- TX79_MMI1_PSUBUH = (0x15 << 6) | TX79_MMI_CLASS_MMI1,
- TX79_MMI1_PEXTUH = (0x16 << 6) | TX79_MMI_CLASS_MMI1,
- TX79_MMI1_PADDUB = (0x18 << 6) | TX79_MMI_CLASS_MMI1,
- TX79_MMI1_PSUBUB = (0x19 << 6) | TX79_MMI_CLASS_MMI1,
- TX79_MMI1_PEXTUB = (0x1A << 6) | TX79_MMI_CLASS_MMI1,
- TX79_MMI1_QFSRV = (0x1B << 6) | TX79_MMI_CLASS_MMI1,
+ MMI_OPC_1_PABSW = (0x01 << 6) | MMI_OPC_CLASS_MMI1,
+ MMI_OPC_1_PCEQW = (0x02 << 6) | MMI_OPC_CLASS_MMI1,
+ MMI_OPC_1_PMINW = (0x03 << 6) | MMI_OPC_CLASS_MMI1,
+ MMI_OPC_1_PADSBH = (0x04 << 6) | MMI_OPC_CLASS_MMI1,
+ MMI_OPC_1_PABSH = (0x05 << 6) | MMI_OPC_CLASS_MMI1,
+ MMI_OPC_1_PCEQH = (0x06 << 6) | MMI_OPC_CLASS_MMI1,
+ MMI_OPC_1_PMINH = (0x07 << 6) | MMI_OPC_CLASS_MMI1,
+ MMI_OPC_1_PCEQB = (0x0A << 6) | MMI_OPC_CLASS_MMI1,
+ MMI_OPC_1_PADDUW = (0x10 << 6) | MMI_OPC_CLASS_MMI1,
+ MMI_OPC_1_PSUBUW = (0x11 << 6) | MMI_OPC_CLASS_MMI1,
+ MMI_OPC_1_PEXTUW = (0x12 << 6) | MMI_OPC_CLASS_MMI1,
+ MMI_OPC_1_PADDUH = (0x14 << 6) | MMI_OPC_CLASS_MMI1,
+ MMI_OPC_1_PSUBUH = (0x15 << 6) | MMI_OPC_CLASS_MMI1,
+ MMI_OPC_1_PEXTUH = (0x16 << 6) | MMI_OPC_CLASS_MMI1,
+ MMI_OPC_1_PADDUB = (0x18 << 6) | MMI_OPC_CLASS_MMI1,
+ MMI_OPC_1_PSUBUB = (0x19 << 6) | MMI_OPC_CLASS_MMI1,
+ MMI_OPC_1_PEXTUB = (0x1A << 6) | MMI_OPC_CLASS_MMI1,
+ MMI_OPC_1_QFSRV = (0x1B << 6) | MMI_OPC_CLASS_MMI1,
};
/*
- * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI2:
+ * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
*
* 31 26 10 6 5 0
* +--------+----------------------+--------+--------+
* 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
*/
-#define MASK_TX79_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
+#define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
enum {
- TX79_MMI2_PMADDW = (0x00 << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PSLLVW = (0x02 << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PSRLVW = (0x03 << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PMSUBW = (0x04 << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PMFHI = (0x08 << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PMFLO = (0x09 << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PINTH = (0x0A << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PMULTW = (0x0C << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PDIVW = (0x0D << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PCPYLD = (0x0E << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PMADDH = (0x10 << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PHMADH = (0x11 << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PAND = (0x12 << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PXOR = (0x13 << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PMSUBH = (0x14 << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PHMSBH = (0x15 << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PEXEH = (0x1A << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PREVH = (0x1B << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PMULTH = (0x1C << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PDIVBW = (0x1D << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PEXEW = (0x1E << 6) | TX79_MMI_CLASS_MMI2,
- TX79_MMI2_PROT3W = (0x1F << 6) | TX79_MMI_CLASS_MMI2,
+ MMI_OPC_2_PMADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PSLLVW = (0x02 << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PSRLVW = (0x03 << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PMSUBW = (0x04 << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PMFHI = (0x08 << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PMFLO = (0x09 << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PINTH = (0x0A << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PMULTW = (0x0C << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PDIVW = (0x0D << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PCPYLD = (0x0E << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PMADDH = (0x10 << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PHMADH = (0x11 << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PAND = (0x12 << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PXOR = (0x13 << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PMSUBH = (0x14 << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PHMSBH = (0x15 << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PEXEH = (0x1A << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PREVH = (0x1B << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PMULTH = (0x1C << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PDIVBW = (0x1D << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PEXEW = (0x1E << 6) | MMI_OPC_CLASS_MMI2,
+ MMI_OPC_2_PROT3W = (0x1F << 6) | MMI_OPC_CLASS_MMI2,
};
/*
- * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI3:
+ * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
*
* 31 26 10 6 5 0
* +--------+----------------------+--------+--------+
* 7 111 | * | * | PEXCW | *
*/
-#define MASK_TX79_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
+#define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
enum {
- TX79_MMI3_PMADDUW = (0x00 << 6) | TX79_MMI_CLASS_MMI3,
- TX79_MMI3_PSRAVW = (0x03 << 6) | TX79_MMI_CLASS_MMI3,
- TX79_MMI3_PMTHI = (0x08 << 6) | TX79_MMI_CLASS_MMI3,
- TX79_MMI3_PMTLO = (0x09 << 6) | TX79_MMI_CLASS_MMI3,
- TX79_MMI3_PINTEH = (0x0A << 6) | TX79_MMI_CLASS_MMI3,
- TX79_MMI3_PMULTUW = (0x0C << 6) | TX79_MMI_CLASS_MMI3,
- TX79_MMI3_PDIVUW = (0x0D << 6) | TX79_MMI_CLASS_MMI3,
- TX79_MMI3_PCPYUD = (0x0E << 6) | TX79_MMI_CLASS_MMI3,
- TX79_MMI3_POR = (0x12 << 6) | TX79_MMI_CLASS_MMI3,
- TX79_MMI3_PNOR = (0x13 << 6) | TX79_MMI_CLASS_MMI3,
- TX79_MMI3_PEXCH = (0x1A << 6) | TX79_MMI_CLASS_MMI3,
- TX79_MMI3_PCPYH = (0x1B << 6) | TX79_MMI_CLASS_MMI3,
- TX79_MMI3_PEXCW = (0x1E << 6) | TX79_MMI_CLASS_MMI3,
+ MMI_OPC_3_PMADDUW = (0x00 << 6) | MMI_OPC_CLASS_MMI3,
+ MMI_OPC_3_PSRAVW = (0x03 << 6) | MMI_OPC_CLASS_MMI3,
+ MMI_OPC_3_PMTHI = (0x08 << 6) | MMI_OPC_CLASS_MMI3,
+ MMI_OPC_3_PMTLO = (0x09 << 6) | MMI_OPC_CLASS_MMI3,
+ MMI_OPC_3_PINTEH = (0x0A << 6) | MMI_OPC_CLASS_MMI3,
+ MMI_OPC_3_PMULTUW = (0x0C << 6) | MMI_OPC_CLASS_MMI3,
+ MMI_OPC_3_PDIVUW = (0x0D << 6) | MMI_OPC_CLASS_MMI3,
+ MMI_OPC_3_PCPYUD = (0x0E << 6) | MMI_OPC_CLASS_MMI3,
+ MMI_OPC_3_POR = (0x12 << 6) | MMI_OPC_CLASS_MMI3,
+ MMI_OPC_3_PNOR = (0x13 << 6) | MMI_OPC_CLASS_MMI3,
+ MMI_OPC_3_PEXCH = (0x1A << 6) | MMI_OPC_CLASS_MMI3,
+ MMI_OPC_3_PCPYH = (0x1B << 6) | MMI_OPC_CLASS_MMI3,
+ MMI_OPC_3_PEXCW = (0x1E << 6) | MMI_OPC_CLASS_MMI3,
};
/* global register indices */
static TCGv_i64 fpu_f64[32];
static TCGv_i64 msa_wr_d[64];
+#if defined(TARGET_MIPS64)
+/* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
+static TCGv_i64 cpu_mmr[32];
+#endif
+
+#if !defined(TARGET_MIPS64)
/* MXU registers */
static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
static TCGv mxu_CR;
+#endif
#include "exec/gen-icount.h"
bool mrp;
bool nan2008;
bool abs2008;
+ bool saar;
} DisasContext;
#define DISAS_STOP DISAS_TARGET_0
"w30.d0", "w30.d1", "w31.d0", "w31.d1",
};
+#if !defined(TARGET_MIPS64)
static const char * const mxuregnames[] = {
"XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
"XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
};
+#endif
#define LOG_DISAS(...) \
do { \
}
}
+#if !defined(TARGET_MIPS64)
/* MXU General purpose registers moves. */
static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
{
/* TODO: Add handling of RW rules for MXU_CR. */
tcg_gen_mov_tl(mxu_CR, t);
}
+#endif
/* Tests */
tcg_temp_free(t1);
}
+/* Copy GPR to and from TX79 HI1/LO1 register. */
+static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
+{
+ if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
+ /* Treat as NOP. */
+ return;
+ }
+
+ switch (opc) {
+ case MMI_OPC_MFHI1:
+ tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
+ break;
+ case MMI_OPC_MFLO1:
+ tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
+ break;
+ case MMI_OPC_MTHI1:
+ if (reg != 0) {
+ tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
+ } else {
+ tcg_gen_movi_tl(cpu_HI[1], 0);
+ }
+ break;
+ case MMI_OPC_MTLO1:
+ if (reg != 0) {
+ tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
+ } else {
+ tcg_gen_movi_tl(cpu_LO[1], 0);
+ }
+ break;
+ default:
+ MIPS_INVAL("mfthilo1 TX79");
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+}
+
/* Arithmetic on HI/LO registers */
static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
{
- if (reg == 0 && (opc == OPC_MFHI || opc == TX79_MMI_MFHI1 ||
- opc == OPC_MFLO || opc == TX79_MMI_MFLO1)) {
+ if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
/* Treat as NOP. */
return;
}
if (acc != 0) {
- if (!(ctx->insn_flags & INSN_R5900)) {
- check_dsp(ctx);
- }
+ check_dsp(ctx);
}
switch (opc) {
case OPC_MFHI:
- case TX79_MMI_MFHI1:
#if defined(TARGET_MIPS64)
if (acc != 0) {
tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
}
break;
case OPC_MFLO:
- case TX79_MMI_MFLO1:
#if defined(TARGET_MIPS64)
if (acc != 0) {
tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
}
break;
case OPC_MTHI:
- case TX79_MMI_MTHI1:
if (reg != 0) {
#if defined(TARGET_MIPS64)
if (acc != 0) {
}
break;
case OPC_MTLO:
- case TX79_MMI_MTLO1:
if (reg != 0) {
#if defined(TARGET_MIPS64)
if (acc != 0) {
tcg_temp_free(t1);
}
+static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
+{
+ TCGv t0, t1;
+
+ t0 = tcg_temp_new();
+ t1 = tcg_temp_new();
+
+ gen_load_gpr(t0, rs);
+ gen_load_gpr(t1, rt);
+
+ switch (opc) {
+ case MMI_OPC_DIV1:
+ {
+ TCGv t2 = tcg_temp_new();
+ TCGv t3 = tcg_temp_new();
+ tcg_gen_ext32s_tl(t0, t0);
+ tcg_gen_ext32s_tl(t1, t1);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
+ tcg_gen_and_tl(t2, t2, t3);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
+ tcg_gen_or_tl(t2, t2, t3);
+ tcg_gen_movi_tl(t3, 0);
+ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
+ tcg_gen_div_tl(cpu_LO[1], t0, t1);
+ tcg_gen_rem_tl(cpu_HI[1], t0, t1);
+ tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
+ tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
+ tcg_temp_free(t3);
+ tcg_temp_free(t2);
+ }
+ break;
+ case MMI_OPC_DIVU1:
+ {
+ TCGv t2 = tcg_const_tl(0);
+ TCGv t3 = tcg_const_tl(1);
+ tcg_gen_ext32u_tl(t0, t0);
+ tcg_gen_ext32u_tl(t1, t1);
+ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
+ tcg_gen_divu_tl(cpu_LO[1], t0, t1);
+ tcg_gen_remu_tl(cpu_HI[1], t0, t1);
+ tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
+ tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
+ tcg_temp_free(t3);
+ tcg_temp_free(t2);
+ }
+ break;
+ default:
+ MIPS_INVAL("div1 TX79");
+ generate_exception_end(ctx, EXCP_RI);
+ goto out;
+ }
+ out:
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+}
+
static void gen_muldiv(DisasContext *ctx, uint32_t opc,
int acc, int rs, int rt)
{
gen_load_gpr(t1, rt);
if (acc != 0) {
- if (!(ctx->insn_flags & INSN_R5900)) {
- check_dsp(ctx);
- }
+ check_dsp(ctx);
}
switch (opc) {
case OPC_DIV:
- case TX79_MMI_DIV1:
{
TCGv t2 = tcg_temp_new();
TCGv t3 = tcg_temp_new();
}
break;
case OPC_DIVU:
- case TX79_MMI_DIVU1:
{
TCGv t2 = tcg_const_tl(0);
TCGv t3 = tcg_const_tl(1);
}
/*
- * These MULT and MULTU instructions implemented in for example the
- * Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
+ * These MULT[U] and MADD[U] instructions implemented in for example
+ * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
* architectures are special three-operand variants with the syntax
*
* MULT[U][1] rd, rs, rt
*
* (rd, LO, HI) <- rs * rt
*
+ * and
+ *
+ * MADD[U][1] rd, rs, rt
+ *
+ * such that
+ *
+ * (rd, LO, HI) <- (LO, HI) + rs * rt
+ *
* where the low-order 32-bits of the result is placed into both the
* GPR rd and the special register LO. The high-order 32-bits of the
* result is placed into the special register HI.
gen_load_gpr(t1, rt);
switch (opc) {
- case TX79_MMI_MULT1:
+ case MMI_OPC_MULT1:
acc = 1;
/* Fall through */
case OPC_MULT:
tcg_temp_free_i32(t3);
}
break;
- case TX79_MMI_MULTU1:
+ case MMI_OPC_MULTU1:
acc = 1;
/* Fall through */
case OPC_MULTU:
tcg_temp_free_i32(t3);
}
break;
+ case MMI_OPC_MADD1:
+ acc = 1;
+ /* Fall through */
+ case MMI_OPC_MADD:
+ {
+ TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t3 = tcg_temp_new_i64();
+
+ tcg_gen_ext_tl_i64(t2, t0);
+ tcg_gen_ext_tl_i64(t3, t1);
+ tcg_gen_mul_i64(t2, t2, t3);
+ tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
+ tcg_gen_add_i64(t2, t2, t3);
+ tcg_temp_free_i64(t3);
+ gen_move_low32(cpu_LO[acc], t2);
+ gen_move_high32(cpu_HI[acc], t2);
+ if (rd) {
+ gen_move_low32(cpu_gpr[rd], t2);
+ }
+ tcg_temp_free_i64(t2);
+ }
+ break;
+ case MMI_OPC_MADDU1:
+ acc = 1;
+ /* Fall through */
+ case MMI_OPC_MADDU:
+ {
+ TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t3 = tcg_temp_new_i64();
+
+ tcg_gen_ext32u_tl(t0, t0);
+ tcg_gen_ext32u_tl(t1, t1);
+ tcg_gen_extu_tl_i64(t2, t0);
+ tcg_gen_extu_tl_i64(t3, t1);
+ tcg_gen_mul_i64(t2, t2, t3);
+ tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
+ tcg_gen_add_i64(t2, t2, t3);
+ tcg_temp_free_i64(t3);
+ gen_move_low32(cpu_LO[acc], t2);
+ gen_move_high32(cpu_HI[acc], t2);
+ if (rd) {
+ gen_move_low32(cpu_gpr[rd], t2);
+ }
+ tcg_temp_free_i64(t2);
+ }
+ break;
default:
- MIPS_INVAL("mul TXx9");
+ MIPS_INVAL("mul/madd TXx9");
generate_exception_end(ctx, EXCP_RI);
goto out;
}
static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
{
- const char *rn = "invalid";
+ const char *register_name = "invalid";
switch (reg) {
- case 2:
+ case CP0_REGISTER_02:
switch (sel) {
case 0:
CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
- rn = "EntryLo0";
+ register_name = "EntryLo0";
break;
default:
goto cp0_unimplemented;
}
break;
- case 3:
+ case CP0_REGISTER_03:
switch (sel) {
case 0:
CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
- rn = "EntryLo1";
+ register_name = "EntryLo1";
break;
default:
goto cp0_unimplemented;
}
break;
- case 17:
+ case CP0_REGISTER_09:
+ switch (sel) {
+ case 7:
+ CP0_CHECK(ctx->saar);
+ gen_helper_mfhc0_saar(arg, cpu_env);
+ register_name = "SAAR";
+ break;
+ default:
+ goto cp0_unimplemented;
+ }
+ break;
+ case CP0_REGISTER_17:
switch (sel) {
case 0:
gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
ctx->CP0_LLAddr_shift);
- rn = "LLAddr";
+ register_name = "LLAddr";
break;
case 1:
CP0_CHECK(ctx->mrp);
gen_helper_mfhc0_maar(arg, cpu_env);
- rn = "MAAR";
+ register_name = "MAAR";
break;
default:
goto cp0_unimplemented;
}
break;
- case 28:
+ case CP0_REGISTER_28:
switch (sel) {
case 0:
case 2:
case 4:
case 6:
gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
- rn = "TagLo";
+ register_name = "TagLo";
break;
default:
goto cp0_unimplemented;
default:
goto cp0_unimplemented;
}
- trace_mips_translate_c0("mfhc0", rn, reg, sel);
+ trace_mips_translate_c0("mfhc0", register_name, reg, sel);
return;
cp0_unimplemented:
- qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
+ qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
+ register_name, reg, sel);
tcg_gen_movi_tl(arg, 0);
}
static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
{
- const char *rn = "invalid";
+ const char *register_name = "invalid";
uint64_t mask = ctx->PAMask >> 36;
switch (reg) {
- case 2:
+ case CP0_REGISTER_02:
switch (sel) {
case 0:
CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
tcg_gen_andi_tl(arg, arg, mask);
gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
- rn = "EntryLo0";
+ register_name = "EntryLo0";
break;
default:
goto cp0_unimplemented;
}
break;
- case 3:
+ case CP0_REGISTER_03:
switch (sel) {
case 0:
CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
tcg_gen_andi_tl(arg, arg, mask);
gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
- rn = "EntryLo1";
+ register_name = "EntryLo1";
break;
default:
goto cp0_unimplemented;
}
break;
- case 17:
+ case CP0_REGISTER_09:
+ switch (sel) {
+ case 7:
+ CP0_CHECK(ctx->saar);
+ gen_helper_mthc0_saar(cpu_env, arg);
+ register_name = "SAAR";
+ break;
+ default:
+ goto cp0_unimplemented;
+ }
+ case CP0_REGISTER_17:
switch (sel) {
case 0:
/* LLAddr is read-only (the only exception is bit 0 if LLB is
supported); the CP0_LLAddr_rw_bitmask does not seem to be
relevant for modern MIPS cores supporting MTHC0, therefore
treating MTHC0 to LLAddr as NOP. */
- rn = "LLAddr";
+ register_name = "LLAddr";
break;
case 1:
CP0_CHECK(ctx->mrp);
gen_helper_mthc0_maar(cpu_env, arg);
- rn = "MAAR";
+ register_name = "MAAR";
break;
default:
goto cp0_unimplemented;
}
break;
- case 28:
+ case CP0_REGISTER_28:
switch (sel) {
case 0:
case 2:
case 6:
tcg_gen_andi_tl(arg, arg, mask);
gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
- rn = "TagLo";
+ register_name = "TagLo";
break;
default:
goto cp0_unimplemented;
default:
goto cp0_unimplemented;
}
- trace_mips_translate_c0("mthc0", rn, reg, sel);
+ trace_mips_translate_c0("mthc0", register_name, reg, sel);
cp0_unimplemented:
- qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
+ qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
+ register_name, reg, sel);
}
static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
{
- const char *rn = "invalid";
+ const char *register_name = "invalid";
if (sel != 0)
check_insn(ctx, ISA_MIPS32);
switch (reg) {
- case 0:
+ case CP0_REGISTER_00:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
- rn = "Index";
+ register_name = "Index";
break;
case 1:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_mvpcontrol(arg, cpu_env);
- rn = "MVPControl";
+ register_name = "MVPControl";
break;
case 2:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_mvpconf0(arg, cpu_env);
- rn = "MVPConf0";
+ register_name = "MVPConf0";
break;
case 3:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_mvpconf1(arg, cpu_env);
- rn = "MVPConf1";
+ register_name = "MVPConf1";
break;
case 4:
CP0_CHECK(ctx->vp);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
- rn = "VPControl";
+ register_name = "VPControl";
break;
default:
goto cp0_unimplemented;
}
break;
- case 1:
+ case CP0_REGISTER_01:
switch (sel) {
case 0:
CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
gen_helper_mfc0_random(arg, cpu_env);
- rn = "Random";
+ register_name = "Random";
break;
case 1:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
- rn = "VPEControl";
+ register_name = "VPEControl";
break;
case 2:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
- rn = "VPEConf0";
+ register_name = "VPEConf0";
break;
case 3:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
- rn = "VPEConf1";
+ register_name = "VPEConf1";
break;
case 4:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
- rn = "YQMask";
+ register_name = "YQMask";
break;
case 5:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
- rn = "VPESchedule";
+ register_name = "VPESchedule";
break;
case 6:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
- rn = "VPEScheFBack";
+ register_name = "VPEScheFBack";
break;
case 7:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
- rn = "VPEOpt";
+ register_name = "VPEOpt";
break;
default:
goto cp0_unimplemented;
}
break;
- case 2:
+ case CP0_REGISTER_02:
switch (sel) {
case 0:
{
gen_move_low32(arg, tmp);
tcg_temp_free_i64(tmp);
}
- rn = "EntryLo0";
+ register_name = "EntryLo0";
break;
case 1:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_tcstatus(arg, cpu_env);
- rn = "TCStatus";
+ register_name = "TCStatus";
break;
case 2:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_tcbind(arg, cpu_env);
- rn = "TCBind";
+ register_name = "TCBind";
break;
case 3:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_tcrestart(arg, cpu_env);
- rn = "TCRestart";
+ register_name = "TCRestart";
break;
case 4:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_tchalt(arg, cpu_env);
- rn = "TCHalt";
+ register_name = "TCHalt";
break;
case 5:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_tccontext(arg, cpu_env);
- rn = "TCContext";
+ register_name = "TCContext";
break;
case 6:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_tcschedule(arg, cpu_env);
- rn = "TCSchedule";
+ register_name = "TCSchedule";
break;
case 7:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_tcschefback(arg, cpu_env);
- rn = "TCScheFBack";
+ register_name = "TCScheFBack";
break;
default:
goto cp0_unimplemented;
}
break;
- case 3:
+ case CP0_REGISTER_03:
switch (sel) {
case 0:
{
gen_move_low32(arg, tmp);
tcg_temp_free_i64(tmp);
}
- rn = "EntryLo1";
+ register_name = "EntryLo1";
break;
case 1:
CP0_CHECK(ctx->vp);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
- rn = "GlobalNumber";
+ register_name = "GlobalNumber";
break;
default:
goto cp0_unimplemented;
}
break;
- case 4:
+ case CP0_REGISTER_04:
switch (sel) {
case 0:
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
tcg_gen_ext32s_tl(arg, arg);
- rn = "Context";
+ register_name = "Context";
break;
case 1:
// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
- rn = "ContextConfig";
+ register_name = "ContextConfig";
goto cp0_unimplemented;
case 2:
CP0_CHECK(ctx->ulri);
tcg_gen_ld_tl(arg, cpu_env,
offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
tcg_gen_ext32s_tl(arg, arg);
- rn = "UserLocal";
+ register_name = "UserLocal";
break;
default:
goto cp0_unimplemented;
}
break;
- case 5:
+ case CP0_REGISTER_05:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
- rn = "PageMask";
+ register_name = "PageMask";
break;
case 1:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
- rn = "PageGrain";
+ register_name = "PageGrain";
break;
case 2:
CP0_CHECK(ctx->sc);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
tcg_gen_ext32s_tl(arg, arg);
- rn = "SegCtl0";
+ register_name = "SegCtl0";
break;
case 3:
CP0_CHECK(ctx->sc);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
tcg_gen_ext32s_tl(arg, arg);
- rn = "SegCtl1";
+ register_name = "SegCtl1";
break;
case 4:
CP0_CHECK(ctx->sc);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
tcg_gen_ext32s_tl(arg, arg);
- rn = "SegCtl2";
+ register_name = "SegCtl2";
break;
case 5:
check_pw(ctx);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
- rn = "PWBase";
+ register_name = "PWBase";
break;
case 6:
check_pw(ctx);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
- rn = "PWField";
+ register_name = "PWField";
break;
case 7:
check_pw(ctx);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
- rn = "PWSize";
+ register_name = "PWSize";
break;
default:
goto cp0_unimplemented;
}
break;
- case 6:
+ case CP0_REGISTER_06:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
- rn = "Wired";
+ register_name = "Wired";
break;
case 1:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
- rn = "SRSConf0";
+ register_name = "SRSConf0";
break;
case 2:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
- rn = "SRSConf1";
+ register_name = "SRSConf1";
break;
case 3:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
- rn = "SRSConf2";
+ register_name = "SRSConf2";
break;
case 4:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
- rn = "SRSConf3";
+ register_name = "SRSConf3";
break;
case 5:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
- rn = "SRSConf4";
+ register_name = "SRSConf4";
break;
case 6:
check_pw(ctx);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
- rn = "PWCtl";
+ register_name = "PWCtl";
break;
default:
goto cp0_unimplemented;
}
break;
- case 7:
+ case CP0_REGISTER_07:
switch (sel) {
case 0:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
- rn = "HWREna";
+ register_name = "HWREna";
break;
default:
goto cp0_unimplemented;
}
break;
- case 8:
+ case CP0_REGISTER_08:
switch (sel) {
case 0:
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
tcg_gen_ext32s_tl(arg, arg);
- rn = "BadVAddr";
+ register_name = "BadVAddr";
break;
case 1:
CP0_CHECK(ctx->bi);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
- rn = "BadInstr";
+ register_name = "BadInstr";
break;
case 2:
CP0_CHECK(ctx->bp);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
- rn = "BadInstrP";
+ register_name = "BadInstrP";
break;
case 3:
CP0_CHECK(ctx->bi);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
tcg_gen_andi_tl(arg, arg, ~0xffff);
- rn = "BadInstrX";
+ register_name = "BadInstrX";
break;
default:
goto cp0_unimplemented;
}
break;
- case 9:
+ case CP0_REGISTER_09:
switch (sel) {
case 0:
/* Mark as an IO operation because we read the time. */
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
- }
+ }
gen_helper_mfc0_count(arg, cpu_env);
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
gen_io_end();
ensure we break completely out of translated code. */
gen_save_pc(ctx->base.pc_next + 4);
ctx->base.is_jmp = DISAS_EXIT;
- rn = "Count";
+ register_name = "Count";
+ break;
+ case 6:
+ CP0_CHECK(ctx->saar);
+ gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
+ register_name = "SAARI";
+ break;
+ case 7:
+ CP0_CHECK(ctx->saar);
+ gen_helper_mfc0_saar(arg, cpu_env);
+ register_name = "SAAR";
break;
- /* 6,7 are implementation dependent */
default:
goto cp0_unimplemented;
}
break;
- case 10:
+ case CP0_REGISTER_10:
switch (sel) {
case 0:
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
tcg_gen_ext32s_tl(arg, arg);
- rn = "EntryHi";
+ register_name = "EntryHi";
break;
default:
goto cp0_unimplemented;
}
break;
- case 11:
+ case CP0_REGISTER_11:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
- rn = "Compare";
+ register_name = "Compare";
break;
/* 6,7 are implementation dependent */
default:
goto cp0_unimplemented;
}
break;
- case 12:
+ case CP0_REGISTER_12:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
- rn = "Status";
+ register_name = "Status";
break;
case 1:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
- rn = "IntCtl";
+ register_name = "IntCtl";
break;
case 2:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
- rn = "SRSCtl";
+ register_name = "SRSCtl";
break;
case 3:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
- rn = "SRSMap";
+ register_name = "SRSMap";
break;
default:
goto cp0_unimplemented;
}
break;
- case 13:
+ case CP0_REGISTER_13:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
- rn = "Cause";
+ register_name = "Cause";
break;
default:
goto cp0_unimplemented;
}
break;
- case 14:
+ case CP0_REGISTER_14:
switch (sel) {
case 0:
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
tcg_gen_ext32s_tl(arg, arg);
- rn = "EPC";
+ register_name = "EPC";
break;
default:
goto cp0_unimplemented;
}
break;
- case 15:
+ case CP0_REGISTER_15:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
- rn = "PRid";
+ register_name = "PRid";
break;
case 1:
check_insn(ctx, ISA_MIPS32R2);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
tcg_gen_ext32s_tl(arg, arg);
- rn = "EBase";
+ register_name = "EBase";
break;
case 3:
check_insn(ctx, ISA_MIPS32R2);
CP0_CHECK(ctx->cmgcr);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
tcg_gen_ext32s_tl(arg, arg);
- rn = "CMGCRBase";
+ register_name = "CMGCRBase";
break;
default:
goto cp0_unimplemented;
}
break;
- case 16:
+ case CP0_REGISTER_16:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
- rn = "Config";
+ register_name = "Config";
break;
case 1:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
- rn = "Config1";
+ register_name = "Config1";
break;
case 2:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
- rn = "Config2";
+ register_name = "Config2";
break;
case 3:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
- rn = "Config3";
+ register_name = "Config3";
break;
case 4:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
- rn = "Config4";
+ register_name = "Config4";
break;
case 5:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
- rn = "Config5";
+ register_name = "Config5";
break;
/* 6,7 are implementation dependent */
case 6:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
- rn = "Config6";
+ register_name = "Config6";
break;
case 7:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
- rn = "Config7";
+ register_name = "Config7";
break;
default:
goto cp0_unimplemented;
}
break;
- case 17:
+ case CP0_REGISTER_17:
switch (sel) {
case 0:
gen_helper_mfc0_lladdr(arg, cpu_env);
- rn = "LLAddr";
+ register_name = "LLAddr";
break;
case 1:
CP0_CHECK(ctx->mrp);
gen_helper_mfc0_maar(arg, cpu_env);
- rn = "MAAR";
+ register_name = "MAAR";
break;
case 2:
CP0_CHECK(ctx->mrp);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
- rn = "MAARI";
+ register_name = "MAARI";
break;
default:
goto cp0_unimplemented;
}
break;
- case 18:
+ case CP0_REGISTER_18:
switch (sel) {
case 0:
case 1:
case 7:
CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
gen_helper_1e0i(mfc0_watchlo, arg, sel);
- rn = "WatchLo";
+ register_name = "WatchLo";
break;
default:
goto cp0_unimplemented;
}
break;
- case 19:
+ case CP0_REGISTER_19:
switch (sel) {
case 0:
case 1:
case 7:
CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
gen_helper_1e0i(mfc0_watchhi, arg, sel);
- rn = "WatchHi";
+ register_name = "WatchHi";
break;
default:
goto cp0_unimplemented;
}
break;
- case 20:
+ case CP0_REGISTER_20:
switch (sel) {
case 0:
#if defined(TARGET_MIPS64)
check_insn(ctx, ISA_MIPS3);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
tcg_gen_ext32s_tl(arg, arg);
- rn = "XContext";
+ register_name = "XContext";
break;
#endif
default:
goto cp0_unimplemented;
}
break;
- case 21:
+ case CP0_REGISTER_21:
/* Officially reserved, but sel 0 is used for R1x000 framemask */
CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
- rn = "Framemask";
+ register_name = "Framemask";
break;
default:
goto cp0_unimplemented;
}
break;
- case 22:
+ case CP0_REGISTER_22:
tcg_gen_movi_tl(arg, 0); /* unimplemented */
- rn = "'Diagnostic"; /* implementation dependent */
+ register_name = "'Diagnostic"; /* implementation dependent */
break;
- case 23:
+ case CP0_REGISTER_23:
switch (sel) {
case 0:
gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
- rn = "Debug";
+ register_name = "Debug";
break;
case 1:
// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
- rn = "TraceControl";
+ register_name = "TraceControl";
goto cp0_unimplemented;
case 2:
// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
- rn = "TraceControl2";
+ register_name = "TraceControl2";
goto cp0_unimplemented;
case 3:
// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
- rn = "UserTraceData";
+ register_name = "UserTraceData";
goto cp0_unimplemented;
case 4:
// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
- rn = "TraceBPC";
+ register_name = "TraceBPC";
goto cp0_unimplemented;
default:
goto cp0_unimplemented;
}
break;
- case 24:
+ case CP0_REGISTER_24:
switch (sel) {
case 0:
/* EJTAG support */
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
tcg_gen_ext32s_tl(arg, arg);
- rn = "DEPC";
+ register_name = "DEPC";
break;
default:
goto cp0_unimplemented;
}
break;
- case 25:
+ case CP0_REGISTER_25:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
- rn = "Performance0";
+ register_name = "Performance0";
break;
case 1:
// gen_helper_mfc0_performance1(arg);
- rn = "Performance1";
+ register_name = "Performance1";
goto cp0_unimplemented;
case 2:
// gen_helper_mfc0_performance2(arg);
- rn = "Performance2";
+ register_name = "Performance2";
goto cp0_unimplemented;
case 3:
// gen_helper_mfc0_performance3(arg);
- rn = "Performance3";
+ register_name = "Performance3";
goto cp0_unimplemented;
case 4:
// gen_helper_mfc0_performance4(arg);
- rn = "Performance4";
+ register_name = "Performance4";
goto cp0_unimplemented;
case 5:
// gen_helper_mfc0_performance5(arg);
- rn = "Performance5";
+ register_name = "Performance5";
goto cp0_unimplemented;
case 6:
// gen_helper_mfc0_performance6(arg);
- rn = "Performance6";
+ register_name = "Performance6";
goto cp0_unimplemented;
case 7:
// gen_helper_mfc0_performance7(arg);
- rn = "Performance7";
+ register_name = "Performance7";
goto cp0_unimplemented;
default:
goto cp0_unimplemented;
}
break;
- case 26:
+ case CP0_REGISTER_26:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
- rn = "ErrCtl";
+ register_name = "ErrCtl";
break;
default:
goto cp0_unimplemented;
}
break;
- case 27:
+ case CP0_REGISTER_27:
switch (sel) {
case 0:
case 1:
case 2:
case 3:
tcg_gen_movi_tl(arg, 0); /* unimplemented */
- rn = "CacheErr";
+ register_name = "CacheErr";
break;
default:
goto cp0_unimplemented;
}
break;
- case 28:
+ case CP0_REGISTER_28:
switch (sel) {
case 0:
case 2:
gen_move_low32(arg, tmp);
tcg_temp_free_i64(tmp);
}
- rn = "TagLo";
+ register_name = "TagLo";
break;
case 1:
case 3:
case 5:
case 7:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
- rn = "DataLo";
+ register_name = "DataLo";
break;
default:
goto cp0_unimplemented;
}
break;
- case 29:
+ case CP0_REGISTER_29:
switch (sel) {
case 0:
case 2:
case 4:
case 6:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
- rn = "TagHi";
+ register_name = "TagHi";
break;
case 1:
case 3:
case 5:
case 7:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
- rn = "DataHi";
+ register_name = "DataHi";
break;
default:
goto cp0_unimplemented;
}
break;
- case 30:
+ case CP0_REGISTER_30:
switch (sel) {
case 0:
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
tcg_gen_ext32s_tl(arg, arg);
- rn = "ErrorEPC";
+ register_name = "ErrorEPC";
break;
default:
goto cp0_unimplemented;
}
break;
- case 31:
+ case CP0_REGISTER_31:
switch (sel) {
case 0:
/* EJTAG support */
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
- rn = "DESAVE";
+ register_name = "DESAVE";
break;
case 2:
case 3:
tcg_gen_ld_tl(arg, cpu_env,
offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
tcg_gen_ext32s_tl(arg, arg);
- rn = "KScratch";
+ register_name = "KScratch";
break;
default:
goto cp0_unimplemented;
default:
goto cp0_unimplemented;
}
- trace_mips_translate_c0("mfc0", rn, reg, sel);
+ trace_mips_translate_c0("mfc0", register_name, reg, sel);
return;
cp0_unimplemented:
- qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
+ qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
+ register_name, reg, sel);
gen_mfc0_unimplemented(ctx, arg);
}
static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
{
- const char *rn = "invalid";
+ const char *register_name = "invalid";
if (sel != 0)
check_insn(ctx, ISA_MIPS32);
}
switch (reg) {
- case 0:
+ case CP0_REGISTER_00:
switch (sel) {
case 0:
gen_helper_mtc0_index(cpu_env, arg);
- rn = "Index";
+ register_name = "Index";
break;
case 1:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_mvpcontrol(cpu_env, arg);
- rn = "MVPControl";
+ register_name = "MVPControl";
break;
case 2:
CP0_CHECK(ctx->insn_flags & ASE_MT);
/* ignored */
- rn = "MVPConf0";
+ register_name = "MVPConf0";
break;
case 3:
CP0_CHECK(ctx->insn_flags & ASE_MT);
/* ignored */
- rn = "MVPConf1";
+ register_name = "MVPConf1";
break;
case 4:
CP0_CHECK(ctx->vp);
/* ignored */
- rn = "VPControl";
+ register_name = "VPControl";
break;
default:
goto cp0_unimplemented;
}
break;
- case 1:
+ case CP0_REGISTER_01:
switch (sel) {
case 0:
/* ignored */
- rn = "Random";
+ register_name = "Random";
break;
case 1:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_vpecontrol(cpu_env, arg);
- rn = "VPEControl";
+ register_name = "VPEControl";
break;
case 2:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_vpeconf0(cpu_env, arg);
- rn = "VPEConf0";
+ register_name = "VPEConf0";
break;
case 3:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_vpeconf1(cpu_env, arg);
- rn = "VPEConf1";
+ register_name = "VPEConf1";
break;
case 4:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_yqmask(cpu_env, arg);
- rn = "YQMask";
+ register_name = "YQMask";
break;
case 5:
CP0_CHECK(ctx->insn_flags & ASE_MT);
tcg_gen_st_tl(arg, cpu_env,
offsetof(CPUMIPSState, CP0_VPESchedule));
- rn = "VPESchedule";
+ register_name = "VPESchedule";
break;
case 6:
CP0_CHECK(ctx->insn_flags & ASE_MT);
tcg_gen_st_tl(arg, cpu_env,
offsetof(CPUMIPSState, CP0_VPEScheFBack));
- rn = "VPEScheFBack";
+ register_name = "VPEScheFBack";
break;
case 7:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_vpeopt(cpu_env, arg);
- rn = "VPEOpt";
+ register_name = "VPEOpt";
break;
default:
goto cp0_unimplemented;
}
break;
- case 2:
+ case CP0_REGISTER_02:
switch (sel) {
case 0:
gen_helper_mtc0_entrylo0(cpu_env, arg);
- rn = "EntryLo0";
+ register_name = "EntryLo0";
break;
case 1:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcstatus(cpu_env, arg);
- rn = "TCStatus";
+ register_name = "TCStatus";
break;
case 2:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcbind(cpu_env, arg);
- rn = "TCBind";
+ register_name = "TCBind";
break;
case 3:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcrestart(cpu_env, arg);
- rn = "TCRestart";
+ register_name = "TCRestart";
break;
case 4:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tchalt(cpu_env, arg);
- rn = "TCHalt";
+ register_name = "TCHalt";
break;
case 5:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tccontext(cpu_env, arg);
- rn = "TCContext";
+ register_name = "TCContext";
break;
case 6:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcschedule(cpu_env, arg);
- rn = "TCSchedule";
+ register_name = "TCSchedule";
break;
case 7:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcschefback(cpu_env, arg);
- rn = "TCScheFBack";
+ register_name = "TCScheFBack";
break;
default:
goto cp0_unimplemented;
}
break;
- case 3:
+ case CP0_REGISTER_03:
switch (sel) {
case 0:
gen_helper_mtc0_entrylo1(cpu_env, arg);
- rn = "EntryLo1";
+ register_name = "EntryLo1";
break;
case 1:
CP0_CHECK(ctx->vp);
/* ignored */
- rn = "GlobalNumber";
+ register_name = "GlobalNumber";
break;
default:
goto cp0_unimplemented;
}
break;
- case 4:
+ case CP0_REGISTER_04:
switch (sel) {
case 0:
gen_helper_mtc0_context(cpu_env, arg);
- rn = "Context";
+ register_name = "Context";
break;
case 1:
// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
- rn = "ContextConfig";
+ register_name = "ContextConfig";
goto cp0_unimplemented;
case 2:
CP0_CHECK(ctx->ulri);
tcg_gen_st_tl(arg, cpu_env,
offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
- rn = "UserLocal";
+ register_name = "UserLocal";
break;
default:
goto cp0_unimplemented;
}
break;
- case 5:
+ case CP0_REGISTER_05:
switch (sel) {
case 0:
gen_helper_mtc0_pagemask(cpu_env, arg);
- rn = "PageMask";
+ register_name = "PageMask";
break;
case 1:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_pagegrain(cpu_env, arg);
- rn = "PageGrain";
+ register_name = "PageGrain";
ctx->base.is_jmp = DISAS_STOP;
break;
case 2:
CP0_CHECK(ctx->sc);
gen_helper_mtc0_segctl0(cpu_env, arg);
- rn = "SegCtl0";
+ register_name = "SegCtl0";
break;
case 3:
CP0_CHECK(ctx->sc);
gen_helper_mtc0_segctl1(cpu_env, arg);
- rn = "SegCtl1";
+ register_name = "SegCtl1";
break;
case 4:
CP0_CHECK(ctx->sc);
gen_helper_mtc0_segctl2(cpu_env, arg);
- rn = "SegCtl2";
+ register_name = "SegCtl2";
break;
case 5:
check_pw(ctx);
gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
- rn = "PWBase";
+ register_name = "PWBase";
break;
case 6:
check_pw(ctx);
gen_helper_mtc0_pwfield(cpu_env, arg);
- rn = "PWField";
+ register_name = "PWField";
break;
case 7:
check_pw(ctx);
gen_helper_mtc0_pwsize(cpu_env, arg);
- rn = "PWSize";
+ register_name = "PWSize";
break;
default:
goto cp0_unimplemented;
}
break;
- case 6:
+ case CP0_REGISTER_06:
switch (sel) {
case 0:
gen_helper_mtc0_wired(cpu_env, arg);
- rn = "Wired";
+ register_name = "Wired";
break;
case 1:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_srsconf0(cpu_env, arg);
- rn = "SRSConf0";
+ register_name = "SRSConf0";
break;
case 2:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_srsconf1(cpu_env, arg);
- rn = "SRSConf1";
+ register_name = "SRSConf1";
break;
case 3:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_srsconf2(cpu_env, arg);
- rn = "SRSConf2";
+ register_name = "SRSConf2";
break;
case 4:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_srsconf3(cpu_env, arg);
- rn = "SRSConf3";
+ register_name = "SRSConf3";
break;
case 5:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_srsconf4(cpu_env, arg);
- rn = "SRSConf4";
+ register_name = "SRSConf4";
break;
case 6:
check_pw(ctx);
gen_helper_mtc0_pwctl(cpu_env, arg);
- rn = "PWCtl";
+ register_name = "PWCtl";
break;
default:
goto cp0_unimplemented;
}
break;
- case 7:
+ case CP0_REGISTER_07:
switch (sel) {
case 0:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_hwrena(cpu_env, arg);
ctx->base.is_jmp = DISAS_STOP;
- rn = "HWREna";
+ register_name = "HWREna";
break;
default:
goto cp0_unimplemented;
}
break;
- case 8:
+ case CP0_REGISTER_08:
switch (sel) {
case 0:
/* ignored */
- rn = "BadVAddr";
+ register_name = "BadVAddr";
break;
case 1:
/* ignored */
- rn = "BadInstr";
+ register_name = "BadInstr";
break;
case 2:
/* ignored */
- rn = "BadInstrP";
+ register_name = "BadInstrP";
break;
case 3:
/* ignored */
- rn = "BadInstrX";
+ register_name = "BadInstrX";
break;
default:
goto cp0_unimplemented;
}
break;
- case 9:
+ case CP0_REGISTER_09:
switch (sel) {
case 0:
gen_helper_mtc0_count(cpu_env, arg);
- rn = "Count";
+ register_name = "Count";
+ break;
+ case 6:
+ CP0_CHECK(ctx->saar);
+ gen_helper_mtc0_saari(cpu_env, arg);
+ register_name = "SAARI";
+ break;
+ case 7:
+ CP0_CHECK(ctx->saar);
+ gen_helper_mtc0_saar(cpu_env, arg);
+ register_name = "SAAR";
break;
- /* 6,7 are implementation dependent */
default:
goto cp0_unimplemented;
}
break;
- case 10:
+ case CP0_REGISTER_10:
switch (sel) {
case 0:
gen_helper_mtc0_entryhi(cpu_env, arg);
- rn = "EntryHi";
+ register_name = "EntryHi";
break;
default:
goto cp0_unimplemented;
}
break;
- case 11:
+ case CP0_REGISTER_11:
switch (sel) {
case 0:
gen_helper_mtc0_compare(cpu_env, arg);
- rn = "Compare";
+ register_name = "Compare";
break;
/* 6,7 are implementation dependent */
default:
goto cp0_unimplemented;
}
break;
- case 12:
+ case CP0_REGISTER_12:
switch (sel) {
case 0:
save_cpu_state(ctx, 1);
/* DISAS_STOP isn't good enough here, hflags may have changed. */
gen_save_pc(ctx->base.pc_next + 4);
ctx->base.is_jmp = DISAS_EXIT;
- rn = "Status";
+ register_name = "Status";
break;
case 1:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_intctl(cpu_env, arg);
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
- rn = "IntCtl";
+ register_name = "IntCtl";
break;
case 2:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_srsctl(cpu_env, arg);
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
- rn = "SRSCtl";
+ register_name = "SRSCtl";
break;
case 3:
check_insn(ctx, ISA_MIPS32R2);
gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
- rn = "SRSMap";
+ register_name = "SRSMap";
break;
default:
goto cp0_unimplemented;
}
break;
- case 13:
+ case CP0_REGISTER_13:
switch (sel) {
case 0:
save_cpu_state(ctx, 1);
* translated code to check for pending interrupts. */
gen_save_pc(ctx->base.pc_next + 4);
ctx->base.is_jmp = DISAS_EXIT;
- rn = "Cause";
+ register_name = "Cause";
break;
default:
goto cp0_unimplemented;
}
break;
- case 14:
+ case CP0_REGISTER_14:
switch (sel) {
case 0:
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
- rn = "EPC";
+ register_name = "EPC";
break;
default:
goto cp0_unimplemented;
}
break;
- case 15:
+ case CP0_REGISTER_15:
switch (sel) {
case 0:
/* ignored */
- rn = "PRid";
+ register_name = "PRid";
break;
case 1:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_ebase(cpu_env, arg);
- rn = "EBase";
+ register_name = "EBase";
break;
default:
goto cp0_unimplemented;
}
break;
- case 16:
+ case CP0_REGISTER_16:
switch (sel) {
case 0:
gen_helper_mtc0_config0(cpu_env, arg);
- rn = "Config";
+ register_name = "Config";
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
break;
case 1:
/* ignored, read only */
- rn = "Config1";
+ register_name = "Config1";
break;
case 2:
gen_helper_mtc0_config2(cpu_env, arg);
- rn = "Config2";
+ register_name = "Config2";
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
break;
case 3:
gen_helper_mtc0_config3(cpu_env, arg);
- rn = "Config3";
+ register_name = "Config3";
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
break;
case 4:
gen_helper_mtc0_config4(cpu_env, arg);
- rn = "Config4";
+ register_name = "Config4";
ctx->base.is_jmp = DISAS_STOP;
break;
case 5:
gen_helper_mtc0_config5(cpu_env, arg);
- rn = "Config5";
+ register_name = "Config5";
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
break;
/* 6,7 are implementation dependent */
case 6:
/* ignored */
- rn = "Config6";
+ register_name = "Config6";
break;
case 7:
/* ignored */
- rn = "Config7";
+ register_name = "Config7";
break;
default:
- rn = "Invalid config selector";
+ register_name = "Invalid config selector";
goto cp0_unimplemented;
}
break;
- case 17:
+ case CP0_REGISTER_17:
switch (sel) {
case 0:
gen_helper_mtc0_lladdr(cpu_env, arg);
- rn = "LLAddr";
+ register_name = "LLAddr";
break;
case 1:
CP0_CHECK(ctx->mrp);
gen_helper_mtc0_maar(cpu_env, arg);
- rn = "MAAR";
+ register_name = "MAAR";
break;
case 2:
CP0_CHECK(ctx->mrp);
gen_helper_mtc0_maari(cpu_env, arg);
- rn = "MAARI";
+ register_name = "MAARI";
break;
default:
goto cp0_unimplemented;
}
break;
- case 18:
+ case CP0_REGISTER_18:
switch (sel) {
case 0:
case 1:
case 7:
CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
gen_helper_0e1i(mtc0_watchlo, arg, sel);
- rn = "WatchLo";
+ register_name = "WatchLo";
break;
default:
goto cp0_unimplemented;
}
break;
- case 19:
+ case CP0_REGISTER_19:
switch (sel) {
case 0:
case 1:
case 7:
CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
gen_helper_0e1i(mtc0_watchhi, arg, sel);
- rn = "WatchHi";
+ register_name = "WatchHi";
break;
default:
goto cp0_unimplemented;
}
break;
- case 20:
+ case CP0_REGISTER_20:
switch (sel) {
case 0:
#if defined(TARGET_MIPS64)
check_insn(ctx, ISA_MIPS3);
gen_helper_mtc0_xcontext(cpu_env, arg);
- rn = "XContext";
+ register_name = "XContext";
break;
#endif
default:
goto cp0_unimplemented;
}
break;
- case 21:
+ case CP0_REGISTER_21:
/* Officially reserved, but sel 0 is used for R1x000 framemask */
CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
switch (sel) {
case 0:
gen_helper_mtc0_framemask(cpu_env, arg);
- rn = "Framemask";
+ register_name = "Framemask";
break;
default:
goto cp0_unimplemented;
}
break;
- case 22:
+ case CP0_REGISTER_22:
/* ignored */
- rn = "Diagnostic"; /* implementation dependent */
+ register_name = "Diagnostic"; /* implementation dependent */
break;
- case 23:
+ case CP0_REGISTER_23:
switch (sel) {
case 0:
gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
/* DISAS_STOP isn't good enough here, hflags may have changed. */
gen_save_pc(ctx->base.pc_next + 4);
ctx->base.is_jmp = DISAS_EXIT;
- rn = "Debug";
+ register_name = "Debug";
break;
case 1:
// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
- rn = "TraceControl";
+ register_name = "TraceControl";
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
goto cp0_unimplemented;
case 2:
// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
- rn = "TraceControl2";
+ register_name = "TraceControl2";
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
goto cp0_unimplemented;
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
- rn = "UserTraceData";
+ register_name = "UserTraceData";
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
goto cp0_unimplemented;
// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
- rn = "TraceBPC";
+ register_name = "TraceBPC";
goto cp0_unimplemented;
default:
goto cp0_unimplemented;
}
break;
- case 24:
+ case CP0_REGISTER_24:
switch (sel) {
case 0:
/* EJTAG support */
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
- rn = "DEPC";
+ register_name = "DEPC";
break;
default:
goto cp0_unimplemented;
}
break;
- case 25:
+ case CP0_REGISTER_25:
switch (sel) {
case 0:
gen_helper_mtc0_performance0(cpu_env, arg);
- rn = "Performance0";
+ register_name = "Performance0";
break;
case 1:
// gen_helper_mtc0_performance1(arg);
- rn = "Performance1";
+ register_name = "Performance1";
goto cp0_unimplemented;
case 2:
// gen_helper_mtc0_performance2(arg);
- rn = "Performance2";
+ register_name = "Performance2";
goto cp0_unimplemented;
case 3:
// gen_helper_mtc0_performance3(arg);
- rn = "Performance3";
+ register_name = "Performance3";
goto cp0_unimplemented;
case 4:
// gen_helper_mtc0_performance4(arg);
- rn = "Performance4";
+ register_name = "Performance4";
goto cp0_unimplemented;
case 5:
// gen_helper_mtc0_performance5(arg);
- rn = "Performance5";
+ register_name = "Performance5";
goto cp0_unimplemented;
case 6:
// gen_helper_mtc0_performance6(arg);
- rn = "Performance6";
+ register_name = "Performance6";
goto cp0_unimplemented;
case 7:
// gen_helper_mtc0_performance7(arg);
- rn = "Performance7";
+ register_name = "Performance7";
goto cp0_unimplemented;
default:
goto cp0_unimplemented;
}
break;
- case 26:
+ case CP0_REGISTER_26:
switch (sel) {
case 0:
gen_helper_mtc0_errctl(cpu_env, arg);
ctx->base.is_jmp = DISAS_STOP;
- rn = "ErrCtl";
+ register_name = "ErrCtl";
break;
default:
goto cp0_unimplemented;
}
break;
- case 27:
+ case CP0_REGISTER_27:
switch (sel) {
case 0:
case 1:
case 2:
case 3:
/* ignored */
- rn = "CacheErr";
+ register_name = "CacheErr";
break;
default:
goto cp0_unimplemented;
}
break;
- case 28:
+ case CP0_REGISTER_28:
switch (sel) {
case 0:
case 2:
case 4:
case 6:
gen_helper_mtc0_taglo(cpu_env, arg);
- rn = "TagLo";
+ register_name = "TagLo";
break;
case 1:
case 3:
case 5:
case 7:
gen_helper_mtc0_datalo(cpu_env, arg);
- rn = "DataLo";
+ register_name = "DataLo";
break;
default:
goto cp0_unimplemented;
}
break;
- case 29:
+ case CP0_REGISTER_29:
switch (sel) {
case 0:
case 2:
case 4:
case 6:
gen_helper_mtc0_taghi(cpu_env, arg);
- rn = "TagHi";
+ register_name = "TagHi";
break;
case 1:
case 3:
case 5:
case 7:
gen_helper_mtc0_datahi(cpu_env, arg);
- rn = "DataHi";
+ register_name = "DataHi";
break;
default:
- rn = "invalid sel";
+ register_name = "invalid sel";
goto cp0_unimplemented;
}
break;
- case 30:
+ case CP0_REGISTER_30:
switch (sel) {
case 0:
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
- rn = "ErrorEPC";
+ register_name = "ErrorEPC";
break;
default:
goto cp0_unimplemented;
}
break;
- case 31:
+ case CP0_REGISTER_31:
switch (sel) {
case 0:
/* EJTAG support */
gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
- rn = "DESAVE";
+ register_name = "DESAVE";
break;
case 2:
case 3:
CP0_CHECK(ctx->kscrexist & (1 << sel));
tcg_gen_st_tl(arg, cpu_env,
offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
- rn = "KScratch";
+ register_name = "KScratch";
break;
default:
goto cp0_unimplemented;
default:
goto cp0_unimplemented;
}
- trace_mips_translate_c0("mtc0", rn, reg, sel);
+ trace_mips_translate_c0("mtc0", register_name, reg, sel);
/* For simplicity assume that all writes can cause interrupts. */
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
return;
cp0_unimplemented:
- qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
+ qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
+ register_name, reg, sel);
}
#if defined(TARGET_MIPS64)
static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
{
- const char *rn = "invalid";
+ const char *register_name = "invalid";
if (sel != 0)
check_insn(ctx, ISA_MIPS64);
switch (reg) {
- case 0:
+ case CP0_REGISTER_00:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
- rn = "Index";
+ register_name = "Index";
break;
case 1:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_mvpcontrol(arg, cpu_env);
- rn = "MVPControl";
+ register_name = "MVPControl";
break;
case 2:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_mvpconf0(arg, cpu_env);
- rn = "MVPConf0";
+ register_name = "MVPConf0";
break;
case 3:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_mvpconf1(arg, cpu_env);
- rn = "MVPConf1";
+ register_name = "MVPConf1";
break;
case 4:
CP0_CHECK(ctx->vp);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
- rn = "VPControl";
+ register_name = "VPControl";
break;
default:
goto cp0_unimplemented;
}
break;
- case 1:
+ case CP0_REGISTER_01:
switch (sel) {
case 0:
CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
gen_helper_mfc0_random(arg, cpu_env);
- rn = "Random";
+ register_name = "Random";
break;
case 1:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
- rn = "VPEControl";
+ register_name = "VPEControl";
break;
case 2:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
- rn = "VPEConf0";
+ register_name = "VPEConf0";
break;
case 3:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
- rn = "VPEConf1";
+ register_name = "VPEConf1";
break;
case 4:
CP0_CHECK(ctx->insn_flags & ASE_MT);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
- rn = "YQMask";
+ register_name = "YQMask";
break;
case 5:
CP0_CHECK(ctx->insn_flags & ASE_MT);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
- rn = "VPESchedule";
+ register_name = "VPESchedule";
break;
case 6:
CP0_CHECK(ctx->insn_flags & ASE_MT);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
- rn = "VPEScheFBack";
+ register_name = "VPEScheFBack";
break;
case 7:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
- rn = "VPEOpt";
+ register_name = "VPEOpt";
break;
default:
goto cp0_unimplemented;
}
break;
- case 2:
+ case CP0_REGISTER_02:
switch (sel) {
case 0:
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
- rn = "EntryLo0";
+ register_name = "EntryLo0";
break;
case 1:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_tcstatus(arg, cpu_env);
- rn = "TCStatus";
+ register_name = "TCStatus";
break;
case 2:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_tcbind(arg, cpu_env);
- rn = "TCBind";
+ register_name = "TCBind";
break;
case 3:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_dmfc0_tcrestart(arg, cpu_env);
- rn = "TCRestart";
+ register_name = "TCRestart";
break;
case 4:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_dmfc0_tchalt(arg, cpu_env);
- rn = "TCHalt";
+ register_name = "TCHalt";
break;
case 5:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_dmfc0_tccontext(arg, cpu_env);
- rn = "TCContext";
+ register_name = "TCContext";
break;
case 6:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_dmfc0_tcschedule(arg, cpu_env);
- rn = "TCSchedule";
+ register_name = "TCSchedule";
break;
case 7:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_dmfc0_tcschefback(arg, cpu_env);
- rn = "TCScheFBack";
+ register_name = "TCScheFBack";
break;
default:
goto cp0_unimplemented;
}
break;
- case 3:
+ case CP0_REGISTER_03:
switch (sel) {
case 0:
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
- rn = "EntryLo1";
+ register_name = "EntryLo1";
break;
case 1:
CP0_CHECK(ctx->vp);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
- rn = "GlobalNumber";
+ register_name = "GlobalNumber";
break;
default:
goto cp0_unimplemented;
}
break;
- case 4:
+ case CP0_REGISTER_04:
switch (sel) {
case 0:
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
- rn = "Context";
+ register_name = "Context";
break;
case 1:
// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
- rn = "ContextConfig";
+ register_name = "ContextConfig";
goto cp0_unimplemented;
case 2:
CP0_CHECK(ctx->ulri);
tcg_gen_ld_tl(arg, cpu_env,
offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
- rn = "UserLocal";
+ register_name = "UserLocal";
break;
default:
goto cp0_unimplemented;
}
break;
- case 5:
+ case CP0_REGISTER_05:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
- rn = "PageMask";
+ register_name = "PageMask";
break;
case 1:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
- rn = "PageGrain";
+ register_name = "PageGrain";
break;
case 2:
CP0_CHECK(ctx->sc);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
- rn = "SegCtl0";
+ register_name = "SegCtl0";
break;
case 3:
CP0_CHECK(ctx->sc);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
- rn = "SegCtl1";
+ register_name = "SegCtl1";
break;
case 4:
CP0_CHECK(ctx->sc);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
- rn = "SegCtl2";
+ register_name = "SegCtl2";
break;
case 5:
check_pw(ctx);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
- rn = "PWBase";
+ register_name = "PWBase";
break;
case 6:
check_pw(ctx);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
- rn = "PWField";
+ register_name = "PWField";
break;
case 7:
check_pw(ctx);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
- rn = "PWSize";
+ register_name = "PWSize";
break;
default:
goto cp0_unimplemented;
}
break;
- case 6:
+ case CP0_REGISTER_06:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
- rn = "Wired";
+ register_name = "Wired";
break;
case 1:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
- rn = "SRSConf0";
+ register_name = "SRSConf0";
break;
case 2:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
- rn = "SRSConf1";
+ register_name = "SRSConf1";
break;
case 3:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
- rn = "SRSConf2";
+ register_name = "SRSConf2";
break;
case 4:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
- rn = "SRSConf3";
+ register_name = "SRSConf3";
break;
case 5:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
- rn = "SRSConf4";
+ register_name = "SRSConf4";
break;
case 6:
check_pw(ctx);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
- rn = "PWCtl";
+ register_name = "PWCtl";
break;
default:
goto cp0_unimplemented;
}
break;
- case 7:
+ case CP0_REGISTER_07:
switch (sel) {
case 0:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
- rn = "HWREna";
+ register_name = "HWREna";
break;
default:
goto cp0_unimplemented;
}
break;
- case 8:
+ case CP0_REGISTER_08:
switch (sel) {
case 0:
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
- rn = "BadVAddr";
+ register_name = "BadVAddr";
break;
case 1:
CP0_CHECK(ctx->bi);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
- rn = "BadInstr";
+ register_name = "BadInstr";
break;
case 2:
CP0_CHECK(ctx->bp);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
- rn = "BadInstrP";
+ register_name = "BadInstrP";
break;
case 3:
CP0_CHECK(ctx->bi);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
tcg_gen_andi_tl(arg, arg, ~0xffff);
- rn = "BadInstrX";
+ register_name = "BadInstrX";
break;
default:
goto cp0_unimplemented;
}
break;
- case 9:
+ case CP0_REGISTER_09:
switch (sel) {
case 0:
/* Mark as an IO operation because we read the time. */
ensure we break completely out of translated code. */
gen_save_pc(ctx->base.pc_next + 4);
ctx->base.is_jmp = DISAS_EXIT;
- rn = "Count";
+ register_name = "Count";
+ break;
+ case 6:
+ CP0_CHECK(ctx->saar);
+ gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
+ register_name = "SAARI";
+ break;
+ case 7:
+ CP0_CHECK(ctx->saar);
+ gen_helper_dmfc0_saar(arg, cpu_env);
+ register_name = "SAAR";
break;
- /* 6,7 are implementation dependent */
default:
goto cp0_unimplemented;
}
break;
- case 10:
+ case CP0_REGISTER_10:
switch (sel) {
case 0:
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
- rn = "EntryHi";
+ register_name = "EntryHi";
break;
default:
goto cp0_unimplemented;
}
break;
- case 11:
+ case CP0_REGISTER_11:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
- rn = "Compare";
+ register_name = "Compare";
break;
/* 6,7 are implementation dependent */
default:
goto cp0_unimplemented;
}
break;
- case 12:
+ case CP0_REGISTER_12:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
- rn = "Status";
+ register_name = "Status";
break;
case 1:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
- rn = "IntCtl";
+ register_name = "IntCtl";
break;
case 2:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
- rn = "SRSCtl";
+ register_name = "SRSCtl";
break;
case 3:
check_insn(ctx, ISA_MIPS32R2);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
- rn = "SRSMap";
+ register_name = "SRSMap";
break;
default:
goto cp0_unimplemented;
}
break;
- case 13:
+ case CP0_REGISTER_13:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
- rn = "Cause";
+ register_name = "Cause";
break;
default:
goto cp0_unimplemented;
}
break;
- case 14:
+ case CP0_REGISTER_14:
switch (sel) {
case 0:
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
- rn = "EPC";
+ register_name = "EPC";
break;
default:
goto cp0_unimplemented;
}
break;
- case 15:
+ case CP0_REGISTER_15:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
- rn = "PRid";
+ register_name = "PRid";
break;
case 1:
check_insn(ctx, ISA_MIPS32R2);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
- rn = "EBase";
+ register_name = "EBase";
break;
case 3:
check_insn(ctx, ISA_MIPS32R2);
CP0_CHECK(ctx->cmgcr);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
- rn = "CMGCRBase";
+ register_name = "CMGCRBase";
break;
default:
goto cp0_unimplemented;
}
break;
- case 16:
+ case CP0_REGISTER_16:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
- rn = "Config";
+ register_name = "Config";
break;
case 1:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
- rn = "Config1";
+ register_name = "Config1";
break;
case 2:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
- rn = "Config2";
+ register_name = "Config2";
break;
case 3:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
- rn = "Config3";
+ register_name = "Config3";
break;
case 4:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
- rn = "Config4";
+ register_name = "Config4";
break;
case 5:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
- rn = "Config5";
+ register_name = "Config5";
break;
/* 6,7 are implementation dependent */
case 6:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
- rn = "Config6";
+ register_name = "Config6";
break;
case 7:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
- rn = "Config7";
+ register_name = "Config7";
break;
default:
goto cp0_unimplemented;
}
break;
- case 17:
+ case CP0_REGISTER_17:
switch (sel) {
case 0:
gen_helper_dmfc0_lladdr(arg, cpu_env);
- rn = "LLAddr";
+ register_name = "LLAddr";
break;
case 1:
CP0_CHECK(ctx->mrp);
gen_helper_dmfc0_maar(arg, cpu_env);
- rn = "MAAR";
+ register_name = "MAAR";
break;
case 2:
CP0_CHECK(ctx->mrp);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
- rn = "MAARI";
+ register_name = "MAARI";
break;
default:
goto cp0_unimplemented;
}
break;
- case 18:
+ case CP0_REGISTER_18:
switch (sel) {
case 0:
case 1:
case 7:
CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
gen_helper_1e0i(dmfc0_watchlo, arg, sel);
- rn = "WatchLo";
+ register_name = "WatchLo";
break;
default:
goto cp0_unimplemented;
}
break;
- case 19:
+ case CP0_REGISTER_19:
switch (sel) {
case 0:
case 1:
case 7:
CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
gen_helper_1e0i(mfc0_watchhi, arg, sel);
- rn = "WatchHi";
+ register_name = "WatchHi";
break;
default:
goto cp0_unimplemented;
}
break;
- case 20:
+ case CP0_REGISTER_20:
switch (sel) {
case 0:
check_insn(ctx, ISA_MIPS3);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
- rn = "XContext";
+ register_name = "XContext";
break;
default:
goto cp0_unimplemented;
}
break;
- case 21:
+ case CP0_REGISTER_21:
/* Officially reserved, but sel 0 is used for R1x000 framemask */
CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
- rn = "Framemask";
+ register_name = "Framemask";
break;
default:
goto cp0_unimplemented;
}
break;
- case 22:
+ case CP0_REGISTER_22:
tcg_gen_movi_tl(arg, 0); /* unimplemented */
- rn = "'Diagnostic"; /* implementation dependent */
+ register_name = "'Diagnostic"; /* implementation dependent */
break;
- case 23:
+ case CP0_REGISTER_23:
switch (sel) {
case 0:
gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
- rn = "Debug";
+ register_name = "Debug";
break;
case 1:
// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
- rn = "TraceControl";
+ register_name = "TraceControl";
goto cp0_unimplemented;
case 2:
// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
- rn = "TraceControl2";
+ register_name = "TraceControl2";
goto cp0_unimplemented;
case 3:
// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
- rn = "UserTraceData";
+ register_name = "UserTraceData";
goto cp0_unimplemented;
case 4:
// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
- rn = "TraceBPC";
+ register_name = "TraceBPC";
goto cp0_unimplemented;
default:
goto cp0_unimplemented;
}
break;
- case 24:
+ case CP0_REGISTER_24:
switch (sel) {
case 0:
/* EJTAG support */
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
- rn = "DEPC";
+ register_name = "DEPC";
break;
default:
goto cp0_unimplemented;
}
break;
- case 25:
+ case CP0_REGISTER_25:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
- rn = "Performance0";
+ register_name = "Performance0";
break;
case 1:
// gen_helper_dmfc0_performance1(arg);
- rn = "Performance1";
+ register_name = "Performance1";
goto cp0_unimplemented;
case 2:
// gen_helper_dmfc0_performance2(arg);
- rn = "Performance2";
+ register_name = "Performance2";
goto cp0_unimplemented;
case 3:
// gen_helper_dmfc0_performance3(arg);
- rn = "Performance3";
+ register_name = "Performance3";
goto cp0_unimplemented;
case 4:
// gen_helper_dmfc0_performance4(arg);
- rn = "Performance4";
+ register_name = "Performance4";
goto cp0_unimplemented;
case 5:
// gen_helper_dmfc0_performance5(arg);
- rn = "Performance5";
+ register_name = "Performance5";
goto cp0_unimplemented;
case 6:
// gen_helper_dmfc0_performance6(arg);
- rn = "Performance6";
+ register_name = "Performance6";
goto cp0_unimplemented;
case 7:
// gen_helper_dmfc0_performance7(arg);
- rn = "Performance7";
+ register_name = "Performance7";
goto cp0_unimplemented;
default:
goto cp0_unimplemented;
}
break;
- case 26:
+ case CP0_REGISTER_26:
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
- rn = "ErrCtl";
+ register_name = "ErrCtl";
break;
default:
goto cp0_unimplemented;
}
break;
- case 27:
+ case CP0_REGISTER_27:
switch (sel) {
/* ignored */
case 0:
case 2:
case 3:
tcg_gen_movi_tl(arg, 0); /* unimplemented */
- rn = "CacheErr";
+ register_name = "CacheErr";
break;
default:
goto cp0_unimplemented;
}
break;
- case 28:
+ case CP0_REGISTER_28:
switch (sel) {
case 0:
case 2:
case 4:
case 6:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
- rn = "TagLo";
+ register_name = "TagLo";
break;
case 1:
case 3:
case 5:
case 7:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
- rn = "DataLo";
+ register_name = "DataLo";
break;
default:
goto cp0_unimplemented;
}
break;
- case 29:
+ case CP0_REGISTER_29:
switch (sel) {
case 0:
case 2:
case 4:
case 6:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
- rn = "TagHi";
+ register_name = "TagHi";
break;
case 1:
case 3:
case 5:
case 7:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
- rn = "DataHi";
+ register_name = "DataHi";
break;
default:
goto cp0_unimplemented;
}
break;
- case 30:
+ case CP0_REGISTER_30:
switch (sel) {
case 0:
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
- rn = "ErrorEPC";
+ register_name = "ErrorEPC";
break;
default:
goto cp0_unimplemented;
}
break;
- case 31:
+ case CP0_REGISTER_31:
switch (sel) {
case 0:
/* EJTAG support */
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
- rn = "DESAVE";
+ register_name = "DESAVE";
break;
case 2:
case 3:
CP0_CHECK(ctx->kscrexist & (1 << sel));
tcg_gen_ld_tl(arg, cpu_env,
offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
- rn = "KScratch";
+ register_name = "KScratch";
break;
default:
goto cp0_unimplemented;
default:
goto cp0_unimplemented;
}
- trace_mips_translate_c0("dmfc0", rn, reg, sel);
+ trace_mips_translate_c0("dmfc0", register_name, reg, sel);
return;
cp0_unimplemented:
- qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
+ qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
+ register_name, reg, sel);
gen_mfc0_unimplemented(ctx, arg);
}
static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
{
- const char *rn = "invalid";
+ const char *register_name = "invalid";
if (sel != 0)
check_insn(ctx, ISA_MIPS64);
}
switch (reg) {
- case 0:
+ case CP0_REGISTER_00:
switch (sel) {
case 0:
gen_helper_mtc0_index(cpu_env, arg);
- rn = "Index";
+ register_name = "Index";
break;
case 1:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_mvpcontrol(cpu_env, arg);
- rn = "MVPControl";
+ register_name = "MVPControl";
break;
case 2:
CP0_CHECK(ctx->insn_flags & ASE_MT);
/* ignored */
- rn = "MVPConf0";
+ register_name = "MVPConf0";
break;
case 3:
CP0_CHECK(ctx->insn_flags & ASE_MT);
/* ignored */
- rn = "MVPConf1";
+ register_name = "MVPConf1";
break;
case 4:
CP0_CHECK(ctx->vp);
/* ignored */
- rn = "VPControl";
+ register_name = "VPControl";
break;
default:
goto cp0_unimplemented;
}
break;
- case 1:
+ case CP0_REGISTER_01:
switch (sel) {
case 0:
/* ignored */
- rn = "Random";
+ register_name = "Random";
break;
case 1:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_vpecontrol(cpu_env, arg);
- rn = "VPEControl";
+ register_name = "VPEControl";
break;
case 2:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_vpeconf0(cpu_env, arg);
- rn = "VPEConf0";
+ register_name = "VPEConf0";
break;
case 3:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_vpeconf1(cpu_env, arg);
- rn = "VPEConf1";
+ register_name = "VPEConf1";
break;
case 4:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_yqmask(cpu_env, arg);
- rn = "YQMask";
+ register_name = "YQMask";
break;
case 5:
CP0_CHECK(ctx->insn_flags & ASE_MT);
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
- rn = "VPESchedule";
+ register_name = "VPESchedule";
break;
case 6:
CP0_CHECK(ctx->insn_flags & ASE_MT);
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
- rn = "VPEScheFBack";
+ register_name = "VPEScheFBack";
break;
case 7:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_vpeopt(cpu_env, arg);
- rn = "VPEOpt";
+ register_name = "VPEOpt";
break;
default:
goto cp0_unimplemented;
}
break;
- case 2:
+ case CP0_REGISTER_02:
switch (sel) {
case 0:
gen_helper_dmtc0_entrylo0(cpu_env, arg);
- rn = "EntryLo0";
+ register_name = "EntryLo0";
break;
case 1:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcstatus(cpu_env, arg);
- rn = "TCStatus";
+ register_name = "TCStatus";
break;
case 2:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcbind(cpu_env, arg);
- rn = "TCBind";
+ register_name = "TCBind";
break;
case 3:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcrestart(cpu_env, arg);
- rn = "TCRestart";
+ register_name = "TCRestart";
break;
case 4:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tchalt(cpu_env, arg);
- rn = "TCHalt";
+ register_name = "TCHalt";
break;
case 5:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tccontext(cpu_env, arg);
- rn = "TCContext";
+ register_name = "TCContext";
break;
case 6:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcschedule(cpu_env, arg);
- rn = "TCSchedule";
+ register_name = "TCSchedule";
break;
case 7:
CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcschefback(cpu_env, arg);
- rn = "TCScheFBack";
+ register_name = "TCScheFBack";
break;
default:
goto cp0_unimplemented;
}
break;
- case 3:
+ case CP0_REGISTER_03:
switch (sel) {
case 0:
gen_helper_dmtc0_entrylo1(cpu_env, arg);
- rn = "EntryLo1";
+ register_name = "EntryLo1";
break;
case 1:
CP0_CHECK(ctx->vp);
/* ignored */
- rn = "GlobalNumber";
+ register_name = "GlobalNumber";
break;
default:
goto cp0_unimplemented;
}
break;
- case 4:
+ case CP0_REGISTER_04:
switch (sel) {
case 0:
gen_helper_mtc0_context(cpu_env, arg);
- rn = "Context";
+ register_name = "Context";
break;
case 1:
// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
- rn = "ContextConfig";
+ register_name = "ContextConfig";
goto cp0_unimplemented;
case 2:
CP0_CHECK(ctx->ulri);
tcg_gen_st_tl(arg, cpu_env,
offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
- rn = "UserLocal";
+ register_name = "UserLocal";
break;
default:
goto cp0_unimplemented;
}
break;
- case 5:
+ case CP0_REGISTER_05:
switch (sel) {
case 0:
gen_helper_mtc0_pagemask(cpu_env, arg);
- rn = "PageMask";
+ register_name = "PageMask";
break;
case 1:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_pagegrain(cpu_env, arg);
- rn = "PageGrain";
+ register_name = "PageGrain";
break;
case 2:
CP0_CHECK(ctx->sc);
gen_helper_mtc0_segctl0(cpu_env, arg);
- rn = "SegCtl0";
+ register_name = "SegCtl0";
break;
case 3:
CP0_CHECK(ctx->sc);
gen_helper_mtc0_segctl1(cpu_env, arg);
- rn = "SegCtl1";
+ register_name = "SegCtl1";
break;
case 4:
CP0_CHECK(ctx->sc);
gen_helper_mtc0_segctl2(cpu_env, arg);
- rn = "SegCtl2";
+ register_name = "SegCtl2";
break;
case 5:
check_pw(ctx);
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
- rn = "PWBase";
+ register_name = "PWBase";
break;
case 6:
check_pw(ctx);
gen_helper_mtc0_pwfield(cpu_env, arg);
- rn = "PWField";
+ register_name = "PWField";
break;
case 7:
check_pw(ctx);
gen_helper_mtc0_pwsize(cpu_env, arg);
- rn = "PWSize";
+ register_name = "PWSize";
break;
default:
goto cp0_unimplemented;
}
break;
- case 6:
+ case CP0_REGISTER_06:
switch (sel) {
case 0:
gen_helper_mtc0_wired(cpu_env, arg);
- rn = "Wired";
+ register_name = "Wired";
break;
case 1:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_srsconf0(cpu_env, arg);
- rn = "SRSConf0";
+ register_name = "SRSConf0";
break;
case 2:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_srsconf1(cpu_env, arg);
- rn = "SRSConf1";
+ register_name = "SRSConf1";
break;
case 3:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_srsconf2(cpu_env, arg);
- rn = "SRSConf2";
+ register_name = "SRSConf2";
break;
case 4:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_srsconf3(cpu_env, arg);
- rn = "SRSConf3";
+ register_name = "SRSConf3";
break;
case 5:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_srsconf4(cpu_env, arg);
- rn = "SRSConf4";
+ register_name = "SRSConf4";
break;
case 6:
check_pw(ctx);
gen_helper_mtc0_pwctl(cpu_env, arg);
- rn = "PWCtl";
+ register_name = "PWCtl";
break;
default:
goto cp0_unimplemented;
}
break;
- case 7:
+ case CP0_REGISTER_07:
switch (sel) {
case 0:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_hwrena(cpu_env, arg);
ctx->base.is_jmp = DISAS_STOP;
- rn = "HWREna";
+ register_name = "HWREna";
break;
default:
goto cp0_unimplemented;
}
break;
- case 8:
+ case CP0_REGISTER_08:
switch (sel) {
case 0:
/* ignored */
- rn = "BadVAddr";
+ register_name = "BadVAddr";
break;
case 1:
/* ignored */
- rn = "BadInstr";
+ register_name = "BadInstr";
break;
case 2:
/* ignored */
- rn = "BadInstrP";
+ register_name = "BadInstrP";
break;
case 3:
/* ignored */
- rn = "BadInstrX";
+ register_name = "BadInstrX";
break;
default:
goto cp0_unimplemented;
}
break;
- case 9:
+ case CP0_REGISTER_09:
switch (sel) {
case 0:
gen_helper_mtc0_count(cpu_env, arg);
- rn = "Count";
+ register_name = "Count";
+ break;
+ case 6:
+ CP0_CHECK(ctx->saar);
+ gen_helper_mtc0_saari(cpu_env, arg);
+ register_name = "SAARI";
+ break;
+ case 7:
+ CP0_CHECK(ctx->saar);
+ gen_helper_mtc0_saar(cpu_env, arg);
+ register_name = "SAAR";
break;
- /* 6,7 are implementation dependent */
default:
goto cp0_unimplemented;
}
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
break;
- case 10:
+ case CP0_REGISTER_10:
switch (sel) {
case 0:
gen_helper_mtc0_entryhi(cpu_env, arg);
- rn = "EntryHi";
+ register_name = "EntryHi";
break;
default:
goto cp0_unimplemented;
}
break;
- case 11:
+ case CP0_REGISTER_11:
switch (sel) {
case 0:
gen_helper_mtc0_compare(cpu_env, arg);
- rn = "Compare";
+ register_name = "Compare";
break;
/* 6,7 are implementation dependent */
default:
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
break;
- case 12:
+ case CP0_REGISTER_12:
switch (sel) {
case 0:
save_cpu_state(ctx, 1);
/* DISAS_STOP isn't good enough here, hflags may have changed. */
gen_save_pc(ctx->base.pc_next + 4);
ctx->base.is_jmp = DISAS_EXIT;
- rn = "Status";
+ register_name = "Status";
break;
case 1:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_intctl(cpu_env, arg);
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
- rn = "IntCtl";
+ register_name = "IntCtl";
break;
case 2:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_srsctl(cpu_env, arg);
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
- rn = "SRSCtl";
+ register_name = "SRSCtl";
break;
case 3:
check_insn(ctx, ISA_MIPS32R2);
gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
- rn = "SRSMap";
+ register_name = "SRSMap";
break;
default:
goto cp0_unimplemented;
}
break;
- case 13:
+ case CP0_REGISTER_13:
switch (sel) {
case 0:
save_cpu_state(ctx, 1);
* translated code to check for pending interrupts. */
gen_save_pc(ctx->base.pc_next + 4);
ctx->base.is_jmp = DISAS_EXIT;
- rn = "Cause";
+ register_name = "Cause";
break;
default:
goto cp0_unimplemented;
}
break;
- case 14:
+ case CP0_REGISTER_14:
switch (sel) {
case 0:
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
- rn = "EPC";
+ register_name = "EPC";
break;
default:
goto cp0_unimplemented;
}
break;
- case 15:
+ case CP0_REGISTER_15:
switch (sel) {
case 0:
/* ignored */
- rn = "PRid";
+ register_name = "PRid";
break;
case 1:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_ebase(cpu_env, arg);
- rn = "EBase";
+ register_name = "EBase";
break;
default:
goto cp0_unimplemented;
}
break;
- case 16:
+ case CP0_REGISTER_16:
switch (sel) {
case 0:
gen_helper_mtc0_config0(cpu_env, arg);
- rn = "Config";
+ register_name = "Config";
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
break;
case 1:
/* ignored, read only */
- rn = "Config1";
+ register_name = "Config1";
break;
case 2:
gen_helper_mtc0_config2(cpu_env, arg);
- rn = "Config2";
+ register_name = "Config2";
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
break;
case 3:
gen_helper_mtc0_config3(cpu_env, arg);
- rn = "Config3";
+ register_name = "Config3";
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
break;
case 4:
/* currently ignored */
- rn = "Config4";
+ register_name = "Config4";
break;
case 5:
gen_helper_mtc0_config5(cpu_env, arg);
- rn = "Config5";
+ register_name = "Config5";
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
break;
/* 6,7 are implementation dependent */
default:
- rn = "Invalid config selector";
+ register_name = "Invalid config selector";
goto cp0_unimplemented;
}
break;
- case 17:
+ case CP0_REGISTER_17:
switch (sel) {
case 0:
gen_helper_mtc0_lladdr(cpu_env, arg);
- rn = "LLAddr";
+ register_name = "LLAddr";
break;
case 1:
CP0_CHECK(ctx->mrp);
gen_helper_mtc0_maar(cpu_env, arg);
- rn = "MAAR";
+ register_name = "MAAR";
break;
case 2:
CP0_CHECK(ctx->mrp);
gen_helper_mtc0_maari(cpu_env, arg);
- rn = "MAARI";
+ register_name = "MAARI";
break;
default:
goto cp0_unimplemented;
}
break;
- case 18:
+ case CP0_REGISTER_18:
switch (sel) {
case 0:
case 1:
case 7:
CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
gen_helper_0e1i(mtc0_watchlo, arg, sel);
- rn = "WatchLo";
+ register_name = "WatchLo";
break;
default:
goto cp0_unimplemented;
}
break;
- case 19:
+ case CP0_REGISTER_19:
switch (sel) {
case 0:
case 1:
case 7:
CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
gen_helper_0e1i(mtc0_watchhi, arg, sel);
- rn = "WatchHi";
+ register_name = "WatchHi";
break;
default:
goto cp0_unimplemented;
}
break;
- case 20:
+ case CP0_REGISTER_20:
switch (sel) {
case 0:
check_insn(ctx, ISA_MIPS3);
gen_helper_mtc0_xcontext(cpu_env, arg);
- rn = "XContext";
+ register_name = "XContext";
break;
default:
goto cp0_unimplemented;
}
break;
- case 21:
+ case CP0_REGISTER_21:
/* Officially reserved, but sel 0 is used for R1x000 framemask */
CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
switch (sel) {
case 0:
gen_helper_mtc0_framemask(cpu_env, arg);
- rn = "Framemask";
+ register_name = "Framemask";
break;
default:
goto cp0_unimplemented;
}
break;
- case 22:
+ case CP0_REGISTER_22:
/* ignored */
- rn = "Diagnostic"; /* implementation dependent */
+ register_name = "Diagnostic"; /* implementation dependent */
break;
- case 23:
+ case CP0_REGISTER_23:
switch (sel) {
case 0:
gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
/* DISAS_STOP isn't good enough here, hflags may have changed. */
gen_save_pc(ctx->base.pc_next + 4);
ctx->base.is_jmp = DISAS_EXIT;
- rn = "Debug";
+ register_name = "Debug";
break;
case 1:
// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
- rn = "TraceControl";
+ register_name = "TraceControl";
goto cp0_unimplemented;
case 2:
// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
- rn = "TraceControl2";
+ register_name = "TraceControl2";
goto cp0_unimplemented;
case 3:
// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
- rn = "UserTraceData";
+ register_name = "UserTraceData";
goto cp0_unimplemented;
case 4:
// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
/* Stop translation as we may have switched the execution mode */
ctx->base.is_jmp = DISAS_STOP;
- rn = "TraceBPC";
+ register_name = "TraceBPC";
goto cp0_unimplemented;
default:
goto cp0_unimplemented;
}
break;
- case 24:
+ case CP0_REGISTER_24:
switch (sel) {
case 0:
/* EJTAG support */
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
- rn = "DEPC";
+ register_name = "DEPC";
break;
default:
goto cp0_unimplemented;
}
break;
- case 25:
+ case CP0_REGISTER_25:
switch (sel) {
case 0:
gen_helper_mtc0_performance0(cpu_env, arg);
- rn = "Performance0";
+ register_name = "Performance0";
break;
case 1:
// gen_helper_mtc0_performance1(cpu_env, arg);
- rn = "Performance1";
+ register_name = "Performance1";
goto cp0_unimplemented;
case 2:
// gen_helper_mtc0_performance2(cpu_env, arg);
- rn = "Performance2";
+ register_name = "Performance2";
goto cp0_unimplemented;
case 3:
// gen_helper_mtc0_performance3(cpu_env, arg);
- rn = "Performance3";
+ register_name = "Performance3";
goto cp0_unimplemented;
case 4:
// gen_helper_mtc0_performance4(cpu_env, arg);
- rn = "Performance4";
+ register_name = "Performance4";
goto cp0_unimplemented;
case 5:
// gen_helper_mtc0_performance5(cpu_env, arg);
- rn = "Performance5";
+ register_name = "Performance5";
goto cp0_unimplemented;
case 6:
// gen_helper_mtc0_performance6(cpu_env, arg);
- rn = "Performance6";
+ register_name = "Performance6";
goto cp0_unimplemented;
case 7:
// gen_helper_mtc0_performance7(cpu_env, arg);
- rn = "Performance7";
+ register_name = "Performance7";
goto cp0_unimplemented;
default:
goto cp0_unimplemented;
}
break;
- case 26:
+ case CP0_REGISTER_26:
switch (sel) {
case 0:
gen_helper_mtc0_errctl(cpu_env, arg);
ctx->base.is_jmp = DISAS_STOP;
- rn = "ErrCtl";
+ register_name = "ErrCtl";
break;
default:
goto cp0_unimplemented;
}
break;
- case 27:
+ case CP0_REGISTER_27:
switch (sel) {
case 0:
case 1:
case 2:
case 3:
/* ignored */
- rn = "CacheErr";
+ register_name = "CacheErr";
break;
default:
goto cp0_unimplemented;
}
break;
- case 28:
+ case CP0_REGISTER_28:
switch (sel) {
case 0:
case 2:
case 4:
case 6:
gen_helper_mtc0_taglo(cpu_env, arg);
- rn = "TagLo";
+ register_name = "TagLo";
break;
case 1:
case 3:
case 5:
case 7:
gen_helper_mtc0_datalo(cpu_env, arg);
- rn = "DataLo";
+ register_name = "DataLo";
break;
default:
goto cp0_unimplemented;
}
break;
- case 29:
+ case CP0_REGISTER_29:
switch (sel) {
case 0:
case 2:
case 4:
case 6:
gen_helper_mtc0_taghi(cpu_env, arg);
- rn = "TagHi";
+ register_name = "TagHi";
break;
case 1:
case 3:
case 5:
case 7:
gen_helper_mtc0_datahi(cpu_env, arg);
- rn = "DataHi";
+ register_name = "DataHi";
break;
default:
- rn = "invalid sel";
+ register_name = "invalid sel";
goto cp0_unimplemented;
}
break;
- case 30:
+ case CP0_REGISTER_30:
switch (sel) {
case 0:
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
- rn = "ErrorEPC";
+ register_name = "ErrorEPC";
break;
default:
goto cp0_unimplemented;
}
break;
- case 31:
+ case CP0_REGISTER_31:
switch (sel) {
case 0:
/* EJTAG support */
gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
- rn = "DESAVE";
+ register_name = "DESAVE";
break;
case 2:
case 3:
CP0_CHECK(ctx->kscrexist & (1 << sel));
tcg_gen_st_tl(arg, cpu_env,
offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
- rn = "KScratch";
+ register_name = "KScratch";
break;
default:
goto cp0_unimplemented;
default:
goto cp0_unimplemented;
}
- trace_mips_translate_c0("dmtc0", rn, reg, sel);
+ trace_mips_translate_c0("dmtc0", register_name, reg, sel);
/* For simplicity assume that all writes can cause interrupts. */
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
return;
cp0_unimplemented:
- qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
+ qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
+ register_name, reg, sel);
}
#endif /* TARGET_MIPS64 */
}
}
+static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
+{
+ int rs = extract32(ctx->opcode, 21, 5);
+ int rt = extract32(ctx->opcode, 16, 5);
+ int rd = extract32(ctx->opcode, 11, 5);
+ uint32_t op1 = MASK_SPECIAL(ctx->opcode);
+
+ switch (op1) {
+ case OPC_MOVN: /* Conditional move */
+ case OPC_MOVZ:
+ gen_cond_move(ctx, op1, rd, rs, rt);
+ break;
+ case OPC_MFHI: /* Move from HI/LO */
+ case OPC_MFLO:
+ gen_HILO(ctx, op1, 0, rd);
+ break;
+ case OPC_MTHI:
+ case OPC_MTLO: /* Move to HI/LO */
+ gen_HILO(ctx, op1, 0, rs);
+ break;
+ case OPC_MULT:
+ case OPC_MULTU:
+ gen_mul_txx9(ctx, op1, rd, rs, rt);
+ break;
+ case OPC_DIV:
+ case OPC_DIVU:
+ gen_muldiv(ctx, op1, 0, rs, rt);
+ break;
+#if defined(TARGET_MIPS64)
+ case OPC_DMULT:
+ case OPC_DMULTU:
+ case OPC_DDIV:
+ case OPC_DDIVU:
+ check_insn_opc_user_only(ctx, INSN_R5900);
+ gen_muldiv(ctx, op1, 0, rs, rt);
+ break;
+#endif
+ case OPC_JR:
+ gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
+ break;
+ default: /* Invalid */
+ MIPS_INVAL("special_tx79");
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+}
+
static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
{
int rs, rt, rd, sa;
case OPC_MOVN: /* Conditional move */
case OPC_MOVZ:
check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
- INSN_LOONGSON2E | INSN_LOONGSON2F | INSN_R5900);
+ INSN_LOONGSON2E | INSN_LOONGSON2F);
gen_cond_move(ctx, op1, rd, rs, rt);
break;
case OPC_MFHI: /* Move from HI/LO */
check_insn(ctx, INSN_VR54XX);
op1 = MASK_MUL_VR54XX(ctx->opcode);
gen_mul_vr54xx(ctx, op1, rd, rs, rt);
- } else if (ctx->insn_flags & INSN_R5900) {
- gen_mul_txx9(ctx, op1, rd, rs, rt);
} else {
gen_muldiv(ctx, op1, rd & 3, rs, rt);
}
case OPC_DDIV:
case OPC_DDIVU:
check_insn(ctx, ISA_MIPS3);
- check_insn_opc_user_only(ctx, INSN_R5900);
check_mips_64(ctx);
gen_muldiv(ctx, op1, 0, rs, rt);
break;
default:
if (ctx->insn_flags & ISA_MIPS32R6) {
decode_opc_special_r6(env, ctx);
+ } else if (ctx->insn_flags & INSN_R5900) {
+ decode_opc_special_tx79(env, ctx);
} else {
decode_opc_special_legacy(env, ctx);
}
}
+#if !defined(TARGET_MIPS64)
+
/* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
#define MXU_APTN1_A 0
#define MXU_APTN1_S 1
#define MXU_EPTN2_SS 3
/* MXU operand getting pattern 'optn2' */
+#define MXU_OPTN2_PTN0 0
+#define MXU_OPTN2_PTN1 1
+#define MXU_OPTN2_PTN2 2
+#define MXU_OPTN2_PTN3 3
+/* alternative naming scheme for 'optn2' */
#define MXU_OPTN2_WW 0
#define MXU_OPTN2_LW 1
#define MXU_OPTN2_HW 2
}
+/*
+ * MXU instruction category: logic
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * S32NOR S32AND S32OR S32XOR
+ */
+
+/*
+ * S32NOR XRa, XRb, XRc
+ * Update XRa with the result of logical bitwise 'nor' operation
+ * applied to the content of XRb and XRc.
+ *
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-----------+---------+-----+-------+-------+-------+-----------+
+ * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
+ * +-----------+---------+-----+-------+-------+-------+-----------+
+ */
+static void gen_mxu_S32NOR(DisasContext *ctx)
+{
+ uint32_t pad, XRc, XRb, XRa;
+
+ pad = extract32(ctx->opcode, 21, 5);
+ XRc = extract32(ctx->opcode, 14, 4);
+ XRb = extract32(ctx->opcode, 10, 4);
+ XRa = extract32(ctx->opcode, 6, 4);
+
+ if (unlikely(pad != 0)) {
+ /* opcode padding incorrect -> do nothing */
+ } else if (unlikely(XRa == 0)) {
+ /* destination is zero register -> do nothing */
+ } else if (unlikely((XRb == 0) && (XRc == 0))) {
+ /* both operands zero registers -> just set destination to all 1s */
+ tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
+ } else if (unlikely(XRb == 0)) {
+ /* XRb zero register -> just set destination to the negation of XRc */
+ tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
+ } else if (unlikely(XRc == 0)) {
+ /* XRa zero register -> just set destination to the negation of XRb */
+ tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+ } else if (unlikely(XRb == XRc)) {
+ /* both operands same -> just set destination to the negation of XRb */
+ tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+ } else {
+ /* the most general case */
+ tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
+ }
+}
+
+/*
+ * S32AND XRa, XRb, XRc
+ * Update XRa with the result of logical bitwise 'and' operation
+ * applied to the content of XRb and XRc.
+ *
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-----------+---------+-----+-------+-------+-------+-----------+
+ * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
+ * +-----------+---------+-----+-------+-------+-------+-----------+
+ */
+static void gen_mxu_S32AND(DisasContext *ctx)
+{
+ uint32_t pad, XRc, XRb, XRa;
+
+ pad = extract32(ctx->opcode, 21, 5);
+ XRc = extract32(ctx->opcode, 14, 4);
+ XRb = extract32(ctx->opcode, 10, 4);
+ XRa = extract32(ctx->opcode, 6, 4);
+
+ if (unlikely(pad != 0)) {
+ /* opcode padding incorrect -> do nothing */
+ } else if (unlikely(XRa == 0)) {
+ /* destination is zero register -> do nothing */
+ } else if (unlikely((XRb == 0) || (XRc == 0))) {
+ /* one of operands zero register -> just set destination to all 0s */
+ tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
+ } else if (unlikely(XRb == XRc)) {
+ /* both operands same -> just set destination to one of them */
+ tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+ } else {
+ /* the most general case */
+ tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
+ }
+}
+
+/*
+ * S32OR XRa, XRb, XRc
+ * Update XRa with the result of logical bitwise 'or' operation
+ * applied to the content of XRb and XRc.
+ *
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-----------+---------+-----+-------+-------+-------+-----------+
+ * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
+ * +-----------+---------+-----+-------+-------+-------+-----------+
+ */
+static void gen_mxu_S32OR(DisasContext *ctx)
+{
+ uint32_t pad, XRc, XRb, XRa;
+
+ pad = extract32(ctx->opcode, 21, 5);
+ XRc = extract32(ctx->opcode, 14, 4);
+ XRb = extract32(ctx->opcode, 10, 4);
+ XRa = extract32(ctx->opcode, 6, 4);
+
+ if (unlikely(pad != 0)) {
+ /* opcode padding incorrect -> do nothing */
+ } else if (unlikely(XRa == 0)) {
+ /* destination is zero register -> do nothing */
+ } else if (unlikely((XRb == 0) && (XRc == 0))) {
+ /* both operands zero registers -> just set destination to all 0s */
+ tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
+ } else if (unlikely(XRb == 0)) {
+ /* XRb zero register -> just set destination to the content of XRc */
+ tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
+ } else if (unlikely(XRc == 0)) {
+ /* XRc zero register -> just set destination to the content of XRb */
+ tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+ } else if (unlikely(XRb == XRc)) {
+ /* both operands same -> just set destination to one of them */
+ tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+ } else {
+ /* the most general case */
+ tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
+ }
+}
+
+/*
+ * S32XOR XRa, XRb, XRc
+ * Update XRa with the result of logical bitwise 'xor' operation
+ * applied to the content of XRb and XRc.
+ *
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-----------+---------+-----+-------+-------+-------+-----------+
+ * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
+ * +-----------+---------+-----+-------+-------+-------+-----------+
+ */
+static void gen_mxu_S32XOR(DisasContext *ctx)
+{
+ uint32_t pad, XRc, XRb, XRa;
+
+ pad = extract32(ctx->opcode, 21, 5);
+ XRc = extract32(ctx->opcode, 14, 4);
+ XRb = extract32(ctx->opcode, 10, 4);
+ XRa = extract32(ctx->opcode, 6, 4);
+
+ if (unlikely(pad != 0)) {
+ /* opcode padding incorrect -> do nothing */
+ } else if (unlikely(XRa == 0)) {
+ /* destination is zero register -> do nothing */
+ } else if (unlikely((XRb == 0) && (XRc == 0))) {
+ /* both operands zero registers -> just set destination to all 0s */
+ tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
+ } else if (unlikely(XRb == 0)) {
+ /* XRb zero register -> just set destination to the content of XRc */
+ tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
+ } else if (unlikely(XRc == 0)) {
+ /* XRc zero register -> just set destination to the content of XRb */
+ tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+ } else if (unlikely(XRb == XRc)) {
+ /* both operands same -> just set destination to all 0s */
+ tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
+ } else {
+ /* the most general case */
+ tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
+ }
+}
+
+
+/*
+ * MXU instruction category max/min
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * S32MAX D16MAX Q8MAX
+ * S32MIN D16MIN Q8MIN
+ */
+
+/*
+ * S32MAX XRa, XRb, XRc
+ * Update XRa with the maximum of signed 32-bit integers contained
+ * in XRb and XRc.
+ *
+ * S32MIN XRa, XRb, XRc
+ * Update XRa with the minimum of signed 32-bit integers contained
+ * in XRb and XRc.
+ *
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-----------+---------+-----+-------+-------+-------+-----------+
+ * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
+ * +-----------+---------+-----+-------+-------+-------+-----------+
+ */
+static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
+{
+ uint32_t pad, opc, XRc, XRb, XRa;
+
+ pad = extract32(ctx->opcode, 21, 5);
+ opc = extract32(ctx->opcode, 18, 3);
+ XRc = extract32(ctx->opcode, 14, 4);
+ XRb = extract32(ctx->opcode, 10, 4);
+ XRa = extract32(ctx->opcode, 6, 4);
+
+ if (unlikely(pad != 0)) {
+ /* opcode padding incorrect -> do nothing */
+ } else if (unlikely(XRa == 0)) {
+ /* destination is zero register -> do nothing */
+ } else if (unlikely((XRb == 0) && (XRc == 0))) {
+ /* both operands zero registers -> just set destination to zero */
+ tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
+ } else if (unlikely((XRb == 0) || (XRc == 0))) {
+ /* exactly one operand is zero register - find which one is not...*/
+ uint32_t XRx = XRb ? XRb : XRc;
+ /* ...and do max/min operation with one operand 0 */
+ if (opc == OPC_MXU_S32MAX) {
+ tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
+ } else {
+ tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
+ }
+ } else if (unlikely(XRb == XRc)) {
+ /* both operands same -> just set destination to one of them */
+ tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+ } else {
+ /* the most general case */
+ if (opc == OPC_MXU_S32MAX) {
+ tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
+ mxu_gpr[XRc - 1]);
+ } else {
+ tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
+ mxu_gpr[XRc - 1]);
+ }
+ }
+}
+
+/*
+ * D16MAX
+ * Update XRa with the 16-bit-wise maximums of signed integers
+ * contained in XRb and XRc.
+ *
+ * D16MIN
+ * Update XRa with the 16-bit-wise minimums of signed integers
+ * contained in XRb and XRc.
+ *
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-----------+---------+-----+-------+-------+-------+-----------+
+ * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
+ * +-----------+---------+-----+-------+-------+-------+-----------+
+ */
+static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
+{
+ uint32_t pad, opc, XRc, XRb, XRa;
+
+ pad = extract32(ctx->opcode, 21, 5);
+ opc = extract32(ctx->opcode, 18, 3);
+ XRc = extract32(ctx->opcode, 14, 4);
+ XRb = extract32(ctx->opcode, 10, 4);
+ XRa = extract32(ctx->opcode, 6, 4);
+
+ if (unlikely(pad != 0)) {
+ /* opcode padding incorrect -> do nothing */
+ } else if (unlikely(XRc == 0)) {
+ /* destination is zero register -> do nothing */
+ } else if (unlikely((XRb == 0) && (XRa == 0))) {
+ /* both operands zero registers -> just set destination to zero */
+ tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
+ } else if (unlikely((XRb == 0) || (XRa == 0))) {
+ /* exactly one operand is zero register - find which one is not...*/
+ uint32_t XRx = XRb ? XRb : XRc;
+ /* ...and do half-word-wise max/min with one operand 0 */
+ TCGv_i32 t0 = tcg_temp_new();
+ TCGv_i32 t1 = tcg_const_i32(0);
+
+ /* the left half-word first */
+ tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
+ if (opc == OPC_MXU_D16MAX) {
+ tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
+ } else {
+ tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
+ }
+
+ /* the right half-word */
+ tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
+ /* move half-words to the leftmost position */
+ tcg_gen_shli_i32(t0, t0, 16);
+ /* t0 will be max/min of t0 and t1 */
+ if (opc == OPC_MXU_D16MAX) {
+ tcg_gen_smax_i32(t0, t0, t1);
+ } else {
+ tcg_gen_smin_i32(t0, t0, t1);
+ }
+ /* return resulting half-words to its original position */
+ tcg_gen_shri_i32(t0, t0, 16);
+ /* finaly update the destination */
+ tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
+
+ tcg_temp_free(t1);
+ tcg_temp_free(t0);
+ } else if (unlikely(XRb == XRc)) {
+ /* both operands same -> just set destination to one of them */
+ tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+ } else {
+ /* the most general case */
+ TCGv_i32 t0 = tcg_temp_new();
+ TCGv_i32 t1 = tcg_temp_new();
+
+ /* the left half-word first */
+ tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
+ tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
+ if (opc == OPC_MXU_D16MAX) {
+ tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
+ } else {
+ tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
+ }
+
+ /* the right half-word */
+ tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
+ tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
+ /* move half-words to the leftmost position */
+ tcg_gen_shli_i32(t0, t0, 16);
+ tcg_gen_shli_i32(t1, t1, 16);
+ /* t0 will be max/min of t0 and t1 */
+ if (opc == OPC_MXU_D16MAX) {
+ tcg_gen_smax_i32(t0, t0, t1);
+ } else {
+ tcg_gen_smin_i32(t0, t0, t1);
+ }
+ /* return resulting half-words to its original position */
+ tcg_gen_shri_i32(t0, t0, 16);
+ /* finaly update the destination */
+ tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
+
+ tcg_temp_free(t1);
+ tcg_temp_free(t0);
+ }
+}
+
+/*
+ * Q8MAX
+ * Update XRa with the 8-bit-wise maximums of signed integers
+ * contained in XRb and XRc.
+ *
+ * Q8MIN
+ * Update XRa with the 8-bit-wise minimums of signed integers
+ * contained in XRb and XRc.
+ *
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-----------+---------+-----+-------+-------+-------+-----------+
+ * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
+ * +-----------+---------+-----+-------+-------+-------+-----------+
+ */
+static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
+{
+ uint32_t pad, opc, XRc, XRb, XRa;
+
+ pad = extract32(ctx->opcode, 21, 5);
+ opc = extract32(ctx->opcode, 18, 3);
+ XRc = extract32(ctx->opcode, 14, 4);
+ XRb = extract32(ctx->opcode, 10, 4);
+ XRa = extract32(ctx->opcode, 6, 4);
+
+ if (unlikely(pad != 0)) {
+ /* opcode padding incorrect -> do nothing */
+ } else if (unlikely(XRa == 0)) {
+ /* destination is zero register -> do nothing */
+ } else if (unlikely((XRb == 0) && (XRc == 0))) {
+ /* both operands zero registers -> just set destination to zero */
+ tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
+ } else if (unlikely((XRb == 0) || (XRc == 0))) {
+ /* exactly one operand is zero register - make it be the first...*/
+ uint32_t XRx = XRb ? XRb : XRc;
+ /* ...and do byte-wise max/min with one operand 0 */
+ TCGv_i32 t0 = tcg_temp_new();
+ TCGv_i32 t1 = tcg_const_i32(0);
+ int32_t i;
+
+ /* the leftmost byte (byte 3) first */
+ tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
+ if (opc == OPC_MXU_Q8MAX) {
+ tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
+ } else {
+ tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
+ }
+
+ /* bytes 2, 1, 0 */
+ for (i = 2; i >= 0; i--) {
+ /* extract the byte */
+ tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
+ /* move the byte to the leftmost position */
+ tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
+ /* t0 will be max/min of t0 and t1 */
+ if (opc == OPC_MXU_Q8MAX) {
+ tcg_gen_smax_i32(t0, t0, t1);
+ } else {
+ tcg_gen_smin_i32(t0, t0, t1);
+ }
+ /* return resulting byte to its original position */
+ tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
+ /* finaly update the destination */
+ tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
+ }
+
+ tcg_temp_free(t1);
+ tcg_temp_free(t0);
+ } else if (unlikely(XRb == XRc)) {
+ /* both operands same -> just set destination to one of them */
+ tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+ } else {
+ /* the most general case */
+ TCGv_i32 t0 = tcg_temp_new();
+ TCGv_i32 t1 = tcg_temp_new();
+ int32_t i;
+
+ /* the leftmost bytes (bytes 3) first */
+ tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
+ tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
+ if (opc == OPC_MXU_Q8MAX) {
+ tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
+ } else {
+ tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
+ }
+
+ /* bytes 2, 1, 0 */
+ for (i = 2; i >= 0; i--) {
+ /* extract corresponding bytes */
+ tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
+ tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
+ /* move the bytes to the leftmost position */
+ tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
+ tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
+ /* t0 will be max/min of t0 and t1 */
+ if (opc == OPC_MXU_Q8MAX) {
+ tcg_gen_smax_i32(t0, t0, t1);
+ } else {
+ tcg_gen_smin_i32(t0, t0, t1);
+ }
+ /* return resulting byte to its original position */
+ tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
+ /* finaly update the destination */
+ tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
+ }
+
+ tcg_temp_free(t1);
+ tcg_temp_free(t0);
+ }
+}
+
+
+/*
+ * MXU instruction category: align
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * S32ALN S32ALNI
+ */
+
+/*
+ * S32ALNI XRc, XRb, XRa, optn3
+ * Arrange bytes from XRb and XRc according to one of five sets of
+ * rules determined by optn3, and place the result in XRa.
+ *
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-----------+-----+---+-----+-------+-------+-------+-----------+
+ * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
+ * +-----------+-----+---+-----+-------+-------+-------+-----------+
+ *
+ */
+static void gen_mxu_S32ALNI(DisasContext *ctx)
+{
+ uint32_t optn3, pad, XRc, XRb, XRa;
+
+ optn3 = extract32(ctx->opcode, 23, 3);
+ pad = extract32(ctx->opcode, 21, 2);
+ XRc = extract32(ctx->opcode, 14, 4);
+ XRb = extract32(ctx->opcode, 10, 4);
+ XRa = extract32(ctx->opcode, 6, 4);
+
+ if (unlikely(pad != 0)) {
+ /* opcode padding incorrect -> do nothing */
+ } else if (unlikely(XRa == 0)) {
+ /* destination is zero register -> do nothing */
+ } else if (unlikely((XRb == 0) && (XRc == 0))) {
+ /* both operands zero registers -> just set destination to all 0s */
+ tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
+ } else if (unlikely(XRb == 0)) {
+ /* XRb zero register -> just appropriatelly shift XRc into XRa */
+ switch (optn3) {
+ case MXU_OPTN3_PTN0:
+ tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
+ break;
+ case MXU_OPTN3_PTN1:
+ case MXU_OPTN3_PTN2:
+ case MXU_OPTN3_PTN3:
+ tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
+ 8 * (4 - optn3));
+ break;
+ case MXU_OPTN3_PTN4:
+ tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
+ break;
+ }
+ } else if (unlikely(XRc == 0)) {
+ /* XRc zero register -> just appropriatelly shift XRb into XRa */
+ switch (optn3) {
+ case MXU_OPTN3_PTN0:
+ tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+ break;
+ case MXU_OPTN3_PTN1:
+ case MXU_OPTN3_PTN2:
+ case MXU_OPTN3_PTN3:
+ tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
+ break;
+ case MXU_OPTN3_PTN4:
+ tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
+ break;
+ }
+ } else if (unlikely(XRb == XRc)) {
+ /* both operands same -> just rotation or moving from any of them */
+ switch (optn3) {
+ case MXU_OPTN3_PTN0:
+ case MXU_OPTN3_PTN4:
+ tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+ break;
+ case MXU_OPTN3_PTN1:
+ case MXU_OPTN3_PTN2:
+ case MXU_OPTN3_PTN3:
+ tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
+ break;
+ }
+ } else {
+ /* the most general case */
+ switch (optn3) {
+ case MXU_OPTN3_PTN0:
+ {
+ /* */
+ /* XRb XRc */
+ /* +---------------+ */
+ /* | A B C D | E F G H */
+ /* +-------+-------+ */
+ /* | */
+ /* XRa */
+ /* */
+
+ tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
+ }
+ break;
+ case MXU_OPTN3_PTN1:
+ {
+ /* */
+ /* XRb XRc */
+ /* +-------------------+ */
+ /* A | B C D E | F G H */
+ /* +---------+---------+ */
+ /* | */
+ /* XRa */
+ /* */
+
+ TCGv_i32 t0 = tcg_temp_new();
+ TCGv_i32 t1 = tcg_temp_new();
+
+ tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
+ tcg_gen_shli_i32(t0, t0, 8);
+
+ tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
+ tcg_gen_shri_i32(t1, t1, 24);
+
+ tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
+
+ tcg_temp_free(t1);
+ tcg_temp_free(t0);
+ }
+ break;
+ case MXU_OPTN3_PTN2:
+ {
+ /* */
+ /* XRb XRc */
+ /* +-------------------+ */
+ /* A B | C D E F | G H */
+ /* +---------+---------+ */
+ /* | */
+ /* XRa */
+ /* */
+
+ TCGv_i32 t0 = tcg_temp_new();
+ TCGv_i32 t1 = tcg_temp_new();
+
+ tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
+ tcg_gen_shli_i32(t0, t0, 16);
+
+ tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
+ tcg_gen_shri_i32(t1, t1, 16);
+
+ tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
+
+ tcg_temp_free(t1);
+ tcg_temp_free(t0);
+ }
+ break;
+ case MXU_OPTN3_PTN3:
+ {
+ /* */
+ /* XRb XRc */
+ /* +-------------------+ */
+ /* A B C | D E F G | H */
+ /* +---------+---------+ */
+ /* | */
+ /* XRa */
+ /* */
+
+ TCGv_i32 t0 = tcg_temp_new();
+ TCGv_i32 t1 = tcg_temp_new();
+
+ tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
+ tcg_gen_shli_i32(t0, t0, 24);
+
+ tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
+ tcg_gen_shri_i32(t1, t1, 8);
+
+ tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
+
+ tcg_temp_free(t1);
+ tcg_temp_free(t0);
+ }
+ break;
+ case MXU_OPTN3_PTN4:
+ {
+ /* */
+ /* XRb XRc */
+ /* +---------------+ */
+ /* A B C D | E F G H | */
+ /* +-------+-------+ */
+ /* | */
+ /* XRa */
+ /* */
+
+ tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
+ }
+ break;
+ }
+ }
+}
+
+
/*
* Decoding engine for MXU
* =======================
switch (opcode) {
case OPC_MXU_S32MAX:
- /* TODO: Implement emulation of S32MAX instruction. */
- MIPS_INVAL("OPC_MXU_S32MAX");
- generate_exception_end(ctx, EXCP_RI);
- break;
case OPC_MXU_S32MIN:
- /* TODO: Implement emulation of S32MIN instruction. */
- MIPS_INVAL("OPC_MXU_S32MIN");
- generate_exception_end(ctx, EXCP_RI);
+ gen_mxu_S32MAX_S32MIN(ctx);
break;
case OPC_MXU_D16MAX:
- /* TODO: Implement emulation of D16MAX instruction. */
- MIPS_INVAL("OPC_MXU_D16MAX");
- generate_exception_end(ctx, EXCP_RI);
- break;
case OPC_MXU_D16MIN:
- /* TODO: Implement emulation of D16MIN instruction. */
- MIPS_INVAL("OPC_MXU_D16MIN");
- generate_exception_end(ctx, EXCP_RI);
+ gen_mxu_D16MAX_D16MIN(ctx);
break;
case OPC_MXU_Q8MAX:
- /* TODO: Implement emulation of Q8MAX instruction. */
- MIPS_INVAL("OPC_MXU_Q8MAX");
- generate_exception_end(ctx, EXCP_RI);
- break;
case OPC_MXU_Q8MIN:
- /* TODO: Implement emulation of Q8MIN instruction. */
- MIPS_INVAL("OPC_MXU_Q8MIN");
- generate_exception_end(ctx, EXCP_RI);
+ gen_mxu_Q8MAX_Q8MIN(ctx);
break;
case OPC_MXU_Q8SLT:
/* TODO: Implement emulation of Q8SLT instruction. */
* | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
* +-----------+-----+---+-----+-------+-------+-------+-----------+
*
- * S32NOR, S32AND, S32OR, S32XOR:
- * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- * +-----------+---------+-----+-------+-------+-------+-----------+
- * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
- * +-----------+---------+-----+-------+-------+-------+-----------+
- *
* S32LUI:
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-----------+-----+---+-----+-------+---------------+-----------+
* | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
* +-----------+-----+---+-----+-------+---------------+-----------+
*
+ * S32NOR, S32AND, S32OR, S32XOR:
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-----------+---------+-----+-------+-------+-------+-----------+
+ * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
+ * +-----------+---------+-----+-------+-------+-------+-----------+
+ *
*/
static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
{
generate_exception_end(ctx, EXCP_RI);
break;
case OPC_MXU_S32ALNI:
- /* TODO: Implement emulation of S32ALNI instruction. */
- MIPS_INVAL("OPC_MXU_S32ALNI");
+ gen_mxu_S32ALNI(ctx);
+ break;
+ case OPC_MXU_S32LUI:
+ /* TODO: Implement emulation of S32LUI instruction. */
+ MIPS_INVAL("OPC_MXU_S32LUI");
generate_exception_end(ctx, EXCP_RI);
break;
case OPC_MXU_S32NOR:
- /* TODO: Implement emulation of S32NOR instruction. */
- MIPS_INVAL("OPC_MXU_S32NOR");
- generate_exception_end(ctx, EXCP_RI);
+ gen_mxu_S32NOR(ctx);
break;
case OPC_MXU_S32AND:
- /* TODO: Implement emulation of S32AND instruction. */
- MIPS_INVAL("OPC_MXU_S32AND");
- generate_exception_end(ctx, EXCP_RI);
+ gen_mxu_S32AND(ctx);
break;
case OPC_MXU_S32OR:
- /* TODO: Implement emulation of S32OR instruction. */
- MIPS_INVAL("OPC_MXU_S32OR");
- generate_exception_end(ctx, EXCP_RI);
+ gen_mxu_S32OR(ctx);
break;
case OPC_MXU_S32XOR:
- /* TODO: Implement emulation of S32XOR instruction. */
- MIPS_INVAL("OPC_MXU_S32XOR");
+ gen_mxu_S32XOR(ctx);
+ break;
+ default:
+ MIPS_INVAL("decode_opc_mxu");
generate_exception_end(ctx, EXCP_RI);
break;
- case OPC_MXU_S32LUI:
- /* TODO: Implement emulation of S32LUI instruction. */
- MIPS_INVAL("OPC_MXU_S32LUI");
+ }
+}
+
+/*
+ *
+ * Decode MXU pool17
+ *
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-----------+---------+---------+---+---------+-----+-----------+
+ * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
+ * +-----------+---------+---------+---+---------+-----+-----------+
+ *
+ */
+static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
+{
+ uint32_t opcode = extract32(ctx->opcode, 6, 2);
+
+ switch (opcode) {
+ case OPC_MXU_LXW:
+ /* TODO: Implement emulation of LXW instruction. */
+ MIPS_INVAL("OPC_MXU_LXW");
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ case OPC_MXU_LXH:
+ /* TODO: Implement emulation of LXH instruction. */
+ MIPS_INVAL("OPC_MXU_LXH");
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ case OPC_MXU_LXHU:
+ /* TODO: Implement emulation of LXHU instruction. */
+ MIPS_INVAL("OPC_MXU_LXHU");
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ case OPC_MXU_LXB:
+ /* TODO: Implement emulation of LXB instruction. */
+ MIPS_INVAL("OPC_MXU_LXB");
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ case OPC_MXU_LXBU:
+ /* TODO: Implement emulation of LXBU instruction. */
+ MIPS_INVAL("OPC_MXU_LXBU");
generate_exception_end(ctx, EXCP_RI);
break;
default:
break;
}
}
-
/*
*
- * Decode MXU pool17
+ * Decode MXU pool18
*
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-----------+---------+-----+-------+-------+-------+-----------+
- * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL17|
+ * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
* +-----------+---------+-----+-------+-------+-------+-----------+
*
*/
-static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
+static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
{
uint32_t opcode = extract32(ctx->opcode, 18, 3);
/*
*
- * Decode MXU pool18
+ * Decode MXU pool19
*
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-----------+---+---+-------+-------+-------+-------+-----------+
- * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL18|
+ * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
* +-----------+---+---+-------+-------+-------+-------+-----------+
*
*/
-static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
+static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
{
uint32_t opcode = extract32(ctx->opcode, 22, 2);
/*
*
- * Decode MXU pool19
+ * Decode MXU pool20
*
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-----------+---------+-----+-------+-------+-------+-----------+
- * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL19|
+ * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
* +-----------+---------+-----+-------+-------+-------+-----------+
*
*/
-static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
+static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
{
uint32_t opcode = extract32(ctx->opcode, 18, 3);
/*
*
- * Decode MXU pool20
+ * Decode MXU pool21
*
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-----------+---+---+-------+-------+-------+-------+-----------+
- * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL20|
+ * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
* +-----------+---+---+-------+-------+-------+-------+-----------+
*
*/
-static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
+static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
{
uint32_t opcode = extract32(ctx->opcode, 22, 2);
case OPC_MXU__POOL16:
decode_opc_mxu__pool16(env, ctx);
break;
- case OPC_MXU_LXB:
- /* TODO: Implement emulation of LXB instruction. */
- MIPS_INVAL("OPC_MXU_LXB");
- generate_exception_end(ctx, EXCP_RI);
+ case OPC_MXU__POOL17:
+ decode_opc_mxu__pool17(env, ctx);
break;
case OPC_MXU_S16LDD:
/* TODO: Implement emulation of S16LDD instruction. */
MIPS_INVAL("OPC_MXU_Q16SLR");
generate_exception_end(ctx, EXCP_RI);
break;
- case OPC_MXU__POOL17:
- decode_opc_mxu__pool17(env, ctx);
+ case OPC_MXU__POOL18:
+ decode_opc_mxu__pool18(env, ctx);
break;
case OPC_MXU_Q16SAR:
/* TODO: Implement emulation of Q16SAR instruction. */
MIPS_INVAL("OPC_MXU_Q16SAR");
generate_exception_end(ctx, EXCP_RI);
break;
- case OPC_MXU__POOL18:
- decode_opc_mxu__pool18(env, ctx);
- break;
case OPC_MXU__POOL19:
decode_opc_mxu__pool19(env, ctx);
break;
case OPC_MXU__POOL20:
decode_opc_mxu__pool20(env, ctx);
break;
+ case OPC_MXU__POOL21:
+ decode_opc_mxu__pool21(env, ctx);
+ break;
case OPC_MXU_Q16SCOP:
/* TODO: Implement emulation of Q16SCOP instruction. */
MIPS_INVAL("OPC_MXU_Q16SCOP");
}
}
+#endif /* !defined(TARGET_MIPS64) */
+
static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
{
}
}
-static void decode_tx79_mmi0(CPUMIPSState *env, DisasContext *ctx)
+static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
{
- uint32_t opc = MASK_TX79_MMI0(ctx->opcode);
+ uint32_t opc = MASK_MMI0(ctx->opcode);
switch (opc) {
- case TX79_MMI0_PADDW: /* TODO: TX79_MMI0_PADDW */
- case TX79_MMI0_PSUBW: /* TODO: TX79_MMI0_PSUBW */
- case TX79_MMI0_PCGTW: /* TODO: TX79_MMI0_PCGTW */
- case TX79_MMI0_PMAXW: /* TODO: TX79_MMI0_PMAXW */
- case TX79_MMI0_PADDH: /* TODO: TX79_MMI0_PADDH */
- case TX79_MMI0_PSUBH: /* TODO: TX79_MMI0_PSUBH */
- case TX79_MMI0_PCGTH: /* TODO: TX79_MMI0_PCGTH */
- case TX79_MMI0_PMAXH: /* TODO: TX79_MMI0_PMAXH */
- case TX79_MMI0_PADDB: /* TODO: TX79_MMI0_PADDB */
- case TX79_MMI0_PSUBB: /* TODO: TX79_MMI0_PSUBB */
- case TX79_MMI0_PCGTB: /* TODO: TX79_MMI0_PCGTB */
- case TX79_MMI0_PADDSW: /* TODO: TX79_MMI0_PADDSW */
- case TX79_MMI0_PSUBSW: /* TODO: TX79_MMI0_PSUBSW */
- case TX79_MMI0_PEXTLW: /* TODO: TX79_MMI0_PEXTLW */
- case TX79_MMI0_PPACW: /* TODO: TX79_MMI0_PPACW */
- case TX79_MMI0_PADDSH: /* TODO: TX79_MMI0_PADDSH */
- case TX79_MMI0_PSUBSH: /* TODO: TX79_MMI0_PSUBSH */
- case TX79_MMI0_PEXTLH: /* TODO: TX79_MMI0_PEXTLH */
- case TX79_MMI0_PPACH: /* TODO: TX79_MMI0_PPACH */
- case TX79_MMI0_PADDSB: /* TODO: TX79_MMI0_PADDSB */
- case TX79_MMI0_PSUBSB: /* TODO: TX79_MMI0_PSUBSB */
- case TX79_MMI0_PEXTLB: /* TODO: TX79_MMI0_PEXTLB */
- case TX79_MMI0_PPACB: /* TODO: TX79_MMI0_PPACB */
- case TX79_MMI0_PEXT5: /* TODO: TX79_MMI0_PEXT5 */
- case TX79_MMI0_PPAC5: /* TODO: TX79_MMI0_PPAC5 */
- generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI0 */
+ case MMI_OPC_0_PADDW: /* TODO: MMI_OPC_0_PADDW */
+ case MMI_OPC_0_PSUBW: /* TODO: MMI_OPC_0_PSUBW */
+ case MMI_OPC_0_PCGTW: /* TODO: MMI_OPC_0_PCGTW */
+ case MMI_OPC_0_PMAXW: /* TODO: MMI_OPC_0_PMAXW */
+ case MMI_OPC_0_PADDH: /* TODO: MMI_OPC_0_PADDH */
+ case MMI_OPC_0_PSUBH: /* TODO: MMI_OPC_0_PSUBH */
+ case MMI_OPC_0_PCGTH: /* TODO: MMI_OPC_0_PCGTH */
+ case MMI_OPC_0_PMAXH: /* TODO: MMI_OPC_0_PMAXH */
+ case MMI_OPC_0_PADDB: /* TODO: MMI_OPC_0_PADDB */
+ case MMI_OPC_0_PSUBB: /* TODO: MMI_OPC_0_PSUBB */
+ case MMI_OPC_0_PCGTB: /* TODO: MMI_OPC_0_PCGTB */
+ case MMI_OPC_0_PADDSW: /* TODO: MMI_OPC_0_PADDSW */
+ case MMI_OPC_0_PSUBSW: /* TODO: MMI_OPC_0_PSUBSW */
+ case MMI_OPC_0_PEXTLW: /* TODO: MMI_OPC_0_PEXTLW */
+ case MMI_OPC_0_PPACW: /* TODO: MMI_OPC_0_PPACW */
+ case MMI_OPC_0_PADDSH: /* TODO: MMI_OPC_0_PADDSH */
+ case MMI_OPC_0_PSUBSH: /* TODO: MMI_OPC_0_PSUBSH */
+ case MMI_OPC_0_PEXTLH: /* TODO: MMI_OPC_0_PEXTLH */
+ case MMI_OPC_0_PPACH: /* TODO: MMI_OPC_0_PPACH */
+ case MMI_OPC_0_PADDSB: /* TODO: MMI_OPC_0_PADDSB */
+ case MMI_OPC_0_PSUBSB: /* TODO: MMI_OPC_0_PSUBSB */
+ case MMI_OPC_0_PEXTLB: /* TODO: MMI_OPC_0_PEXTLB */
+ case MMI_OPC_0_PPACB: /* TODO: MMI_OPC_0_PPACB */
+ case MMI_OPC_0_PEXT5: /* TODO: MMI_OPC_0_PEXT5 */
+ case MMI_OPC_0_PPAC5: /* TODO: MMI_OPC_0_PPAC5 */
+ generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */
break;
default:
MIPS_INVAL("TX79 MMI class MMI0");
}
}
-static void decode_tx79_mmi1(CPUMIPSState *env, DisasContext *ctx)
+static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
{
- uint32_t opc = MASK_TX79_MMI1(ctx->opcode);
+ uint32_t opc = MASK_MMI1(ctx->opcode);
switch (opc) {
- case TX79_MMI1_PABSW: /* TODO: TX79_MMI1_PABSW */
- case TX79_MMI1_PCEQW: /* TODO: TX79_MMI1_PCEQW */
- case TX79_MMI1_PMINW: /* TODO: TX79_MMI1_PMINW */
- case TX79_MMI1_PADSBH: /* TODO: TX79_MMI1_PADSBH */
- case TX79_MMI1_PABSH: /* TODO: TX79_MMI1_PABSH */
- case TX79_MMI1_PCEQH: /* TODO: TX79_MMI1_PCEQH */
- case TX79_MMI1_PMINH: /* TODO: TX79_MMI1_PMINH */
- case TX79_MMI1_PCEQB: /* TODO: TX79_MMI1_PCEQB */
- case TX79_MMI1_PADDUW: /* TODO: TX79_MMI1_PADDUW */
- case TX79_MMI1_PSUBUW: /* TODO: TX79_MMI1_PSUBUW */
- case TX79_MMI1_PEXTUW: /* TODO: TX79_MMI1_PEXTUW */
- case TX79_MMI1_PADDUH: /* TODO: TX79_MMI1_PADDUH */
- case TX79_MMI1_PSUBUH: /* TODO: TX79_MMI1_PSUBUH */
- case TX79_MMI1_PEXTUH: /* TODO: TX79_MMI1_PEXTUH */
- case TX79_MMI1_PADDUB: /* TODO: TX79_MMI1_PADDUB */
- case TX79_MMI1_PSUBUB: /* TODO: TX79_MMI1_PSUBUB */
- case TX79_MMI1_PEXTUB: /* TODO: TX79_MMI1_PEXTUB */
- case TX79_MMI1_QFSRV: /* TODO: TX79_MMI1_QFSRV */
- generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI1 */
+ case MMI_OPC_1_PABSW: /* TODO: MMI_OPC_1_PABSW */
+ case MMI_OPC_1_PCEQW: /* TODO: MMI_OPC_1_PCEQW */
+ case MMI_OPC_1_PMINW: /* TODO: MMI_OPC_1_PMINW */
+ case MMI_OPC_1_PADSBH: /* TODO: MMI_OPC_1_PADSBH */
+ case MMI_OPC_1_PABSH: /* TODO: MMI_OPC_1_PABSH */
+ case MMI_OPC_1_PCEQH: /* TODO: MMI_OPC_1_PCEQH */
+ case MMI_OPC_1_PMINH: /* TODO: MMI_OPC_1_PMINH */
+ case MMI_OPC_1_PCEQB: /* TODO: MMI_OPC_1_PCEQB */
+ case MMI_OPC_1_PADDUW: /* TODO: MMI_OPC_1_PADDUW */
+ case MMI_OPC_1_PSUBUW: /* TODO: MMI_OPC_1_PSUBUW */
+ case MMI_OPC_1_PEXTUW: /* TODO: MMI_OPC_1_PEXTUW */
+ case MMI_OPC_1_PADDUH: /* TODO: MMI_OPC_1_PADDUH */
+ case MMI_OPC_1_PSUBUH: /* TODO: MMI_OPC_1_PSUBUH */
+ case MMI_OPC_1_PEXTUH: /* TODO: MMI_OPC_1_PEXTUH */
+ case MMI_OPC_1_PADDUB: /* TODO: MMI_OPC_1_PADDUB */
+ case MMI_OPC_1_PSUBUB: /* TODO: MMI_OPC_1_PSUBUB */
+ case MMI_OPC_1_PEXTUB: /* TODO: MMI_OPC_1_PEXTUB */
+ case MMI_OPC_1_QFSRV: /* TODO: MMI_OPC_1_QFSRV */
+ generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */
break;
default:
MIPS_INVAL("TX79 MMI class MMI1");
}
}
-static void decode_tx79_mmi2(CPUMIPSState *env, DisasContext *ctx)
+static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
{
- uint32_t opc = MASK_TX79_MMI2(ctx->opcode);
+ uint32_t opc = MASK_MMI2(ctx->opcode);
switch (opc) {
- case TX79_MMI2_PMADDW: /* TODO: TX79_MMI2_PMADDW */
- case TX79_MMI2_PSLLVW: /* TODO: TX79_MMI2_PSLLVW */
- case TX79_MMI2_PSRLVW: /* TODO: TX79_MMI2_PSRLVW */
- case TX79_MMI2_PMSUBW: /* TODO: TX79_MMI2_PMSUBW */
- case TX79_MMI2_PMFHI: /* TODO: TX79_MMI2_PMFHI */
- case TX79_MMI2_PMFLO: /* TODO: TX79_MMI2_PMFLO */
- case TX79_MMI2_PINTH: /* TODO: TX79_MMI2_PINTH */
- case TX79_MMI2_PMULTW: /* TODO: TX79_MMI2_PMULTW */
- case TX79_MMI2_PDIVW: /* TODO: TX79_MMI2_PDIVW */
- case TX79_MMI2_PCPYLD: /* TODO: TX79_MMI2_PCPYLD */
- case TX79_MMI2_PMADDH: /* TODO: TX79_MMI2_PMADDH */
- case TX79_MMI2_PHMADH: /* TODO: TX79_MMI2_PHMADH */
- case TX79_MMI2_PAND: /* TODO: TX79_MMI2_PAND */
- case TX79_MMI2_PXOR: /* TODO: TX79_MMI2_PXOR */
- case TX79_MMI2_PMSUBH: /* TODO: TX79_MMI2_PMSUBH */
- case TX79_MMI2_PHMSBH: /* TODO: TX79_MMI2_PHMSBH */
- case TX79_MMI2_PEXEH: /* TODO: TX79_MMI2_PEXEH */
- case TX79_MMI2_PREVH: /* TODO: TX79_MMI2_PREVH */
- case TX79_MMI2_PMULTH: /* TODO: TX79_MMI2_PMULTH */
- case TX79_MMI2_PDIVBW: /* TODO: TX79_MMI2_PDIVBW */
- case TX79_MMI2_PEXEW: /* TODO: TX79_MMI2_PEXEW */
- case TX79_MMI2_PROT3W: /* TODO: TX79_MMI2_PROT3W */
- generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI2 */
+ case MMI_OPC_2_PMADDW: /* TODO: MMI_OPC_2_PMADDW */
+ case MMI_OPC_2_PSLLVW: /* TODO: MMI_OPC_2_PSLLVW */
+ case MMI_OPC_2_PSRLVW: /* TODO: MMI_OPC_2_PSRLVW */
+ case MMI_OPC_2_PMSUBW: /* TODO: MMI_OPC_2_PMSUBW */
+ case MMI_OPC_2_PMFHI: /* TODO: MMI_OPC_2_PMFHI */
+ case MMI_OPC_2_PMFLO: /* TODO: MMI_OPC_2_PMFLO */
+ case MMI_OPC_2_PINTH: /* TODO: MMI_OPC_2_PINTH */
+ case MMI_OPC_2_PMULTW: /* TODO: MMI_OPC_2_PMULTW */
+ case MMI_OPC_2_PDIVW: /* TODO: MMI_OPC_2_PDIVW */
+ case MMI_OPC_2_PCPYLD: /* TODO: MMI_OPC_2_PCPYLD */
+ case MMI_OPC_2_PMADDH: /* TODO: MMI_OPC_2_PMADDH */
+ case MMI_OPC_2_PHMADH: /* TODO: MMI_OPC_2_PHMADH */
+ case MMI_OPC_2_PAND: /* TODO: MMI_OPC_2_PAND */
+ case MMI_OPC_2_PXOR: /* TODO: MMI_OPC_2_PXOR */
+ case MMI_OPC_2_PMSUBH: /* TODO: MMI_OPC_2_PMSUBH */
+ case MMI_OPC_2_PHMSBH: /* TODO: MMI_OPC_2_PHMSBH */
+ case MMI_OPC_2_PEXEH: /* TODO: MMI_OPC_2_PEXEH */
+ case MMI_OPC_2_PREVH: /* TODO: MMI_OPC_2_PREVH */
+ case MMI_OPC_2_PMULTH: /* TODO: MMI_OPC_2_PMULTH */
+ case MMI_OPC_2_PDIVBW: /* TODO: MMI_OPC_2_PDIVBW */
+ case MMI_OPC_2_PEXEW: /* TODO: MMI_OPC_2_PEXEW */
+ case MMI_OPC_2_PROT3W: /* TODO: MMI_OPC_2_PROT3W */
+ generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
break;
default:
MIPS_INVAL("TX79 MMI class MMI2");
}
}
-static void decode_tx79_mmi3(CPUMIPSState *env, DisasContext *ctx)
+static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
{
- uint32_t opc = MASK_TX79_MMI3(ctx->opcode);
+ uint32_t opc = MASK_MMI3(ctx->opcode);
switch (opc) {
- case TX79_MMI3_PMADDUW: /* TODO: TX79_MMI3_PMADDUW */
- case TX79_MMI3_PSRAVW: /* TODO: TX79_MMI3_PSRAVW */
- case TX79_MMI3_PMTHI: /* TODO: TX79_MMI3_PMTHI */
- case TX79_MMI3_PMTLO: /* TODO: TX79_MMI3_PMTLO */
- case TX79_MMI3_PINTEH: /* TODO: TX79_MMI3_PINTEH */
- case TX79_MMI3_PMULTUW: /* TODO: TX79_MMI3_PMULTUW */
- case TX79_MMI3_PDIVUW: /* TODO: TX79_MMI3_PDIVUW */
- case TX79_MMI3_PCPYUD: /* TODO: TX79_MMI3_PCPYUD */
- case TX79_MMI3_POR: /* TODO: TX79_MMI3_POR */
- case TX79_MMI3_PNOR: /* TODO: TX79_MMI3_PNOR */
- case TX79_MMI3_PEXCH: /* TODO: TX79_MMI3_PEXCH */
- case TX79_MMI3_PCPYH: /* TODO: TX79_MMI3_PCPYH */
- case TX79_MMI3_PEXCW: /* TODO: TX79_MMI3_PEXCW */
- generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI3 */
+ case MMI_OPC_3_PMADDUW: /* TODO: MMI_OPC_3_PMADDUW */
+ case MMI_OPC_3_PSRAVW: /* TODO: MMI_OPC_3_PSRAVW */
+ case MMI_OPC_3_PMTHI: /* TODO: MMI_OPC_3_PMTHI */
+ case MMI_OPC_3_PMTLO: /* TODO: MMI_OPC_3_PMTLO */
+ case MMI_OPC_3_PINTEH: /* TODO: MMI_OPC_3_PINTEH */
+ case MMI_OPC_3_PMULTUW: /* TODO: MMI_OPC_3_PMULTUW */
+ case MMI_OPC_3_PDIVUW: /* TODO: MMI_OPC_3_PDIVUW */
+ case MMI_OPC_3_PCPYUD: /* TODO: MMI_OPC_3_PCPYUD */
+ case MMI_OPC_3_POR: /* TODO: MMI_OPC_3_POR */
+ case MMI_OPC_3_PNOR: /* TODO: MMI_OPC_3_PNOR */
+ case MMI_OPC_3_PEXCH: /* TODO: MMI_OPC_3_PEXCH */
+ case MMI_OPC_3_PCPYH: /* TODO: MMI_OPC_3_PCPYH */
+ case MMI_OPC_3_PEXCW: /* TODO: MMI_OPC_3_PEXCW */
+ generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
break;
default:
MIPS_INVAL("TX79 MMI class MMI3");
}
}
-static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx)
+static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
{
- uint32_t opc = MASK_TX79_MMI(ctx->opcode);
+ uint32_t opc = MASK_MMI(ctx->opcode);
int rs = extract32(ctx->opcode, 21, 5);
int rt = extract32(ctx->opcode, 16, 5);
int rd = extract32(ctx->opcode, 11, 5);
switch (opc) {
- case TX79_MMI_CLASS_MMI0:
- decode_tx79_mmi0(env, ctx);
+ case MMI_OPC_CLASS_MMI0:
+ decode_mmi0(env, ctx);
break;
- case TX79_MMI_CLASS_MMI1:
- decode_tx79_mmi1(env, ctx);
+ case MMI_OPC_CLASS_MMI1:
+ decode_mmi1(env, ctx);
break;
- case TX79_MMI_CLASS_MMI2:
- decode_tx79_mmi2(env, ctx);
+ case MMI_OPC_CLASS_MMI2:
+ decode_mmi2(env, ctx);
break;
- case TX79_MMI_CLASS_MMI3:
- decode_tx79_mmi3(env, ctx);
+ case MMI_OPC_CLASS_MMI3:
+ decode_mmi3(env, ctx);
break;
- case TX79_MMI_MULT1:
- case TX79_MMI_MULTU1:
+ case MMI_OPC_MULT1:
+ case MMI_OPC_MULTU1:
+ case MMI_OPC_MADD:
+ case MMI_OPC_MADDU:
+ case MMI_OPC_MADD1:
+ case MMI_OPC_MADDU1:
gen_mul_txx9(ctx, opc, rd, rs, rt);
break;
- case TX79_MMI_DIV1:
- case TX79_MMI_DIVU1:
- gen_muldiv(ctx, opc, 1, rs, rt);
- break;
- case TX79_MMI_MTLO1:
- case TX79_MMI_MTHI1:
- gen_HILO(ctx, opc, 1, rs);
- break;
- case TX79_MMI_MFLO1:
- case TX79_MMI_MFHI1:
- gen_HILO(ctx, opc, 1, rd);
- break;
- case TX79_MMI_MADD: /* TODO: TX79_MMI_MADD */
- case TX79_MMI_MADDU: /* TODO: TX79_MMI_MADDU */
- case TX79_MMI_PLZCW: /* TODO: TX79_MMI_PLZCW */
- case TX79_MMI_MADD1: /* TODO: TX79_MMI_MADD1 */
- case TX79_MMI_MADDU1: /* TODO: TX79_MMI_MADDU1 */
- case TX79_MMI_PMFHL: /* TODO: TX79_MMI_PMFHL */
- case TX79_MMI_PMTHL: /* TODO: TX79_MMI_PMTHL */
- case TX79_MMI_PSLLH: /* TODO: TX79_MMI_PSLLH */
- case TX79_MMI_PSRLH: /* TODO: TX79_MMI_PSRLH */
- case TX79_MMI_PSRAH: /* TODO: TX79_MMI_PSRAH */
- case TX79_MMI_PSLLW: /* TODO: TX79_MMI_PSLLW */
- case TX79_MMI_PSRLW: /* TODO: TX79_MMI_PSRLW */
- case TX79_MMI_PSRAW: /* TODO: TX79_MMI_PSRAW */
- generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_CLASS_MMI */
+ case MMI_OPC_DIV1:
+ case MMI_OPC_DIVU1:
+ gen_div1_tx79(ctx, opc, rs, rt);
+ break;
+ case MMI_OPC_MTLO1:
+ case MMI_OPC_MTHI1:
+ gen_HILO1_tx79(ctx, opc, rs);
+ break;
+ case MMI_OPC_MFLO1:
+ case MMI_OPC_MFHI1:
+ gen_HILO1_tx79(ctx, opc, rd);
+ break;
+ case MMI_OPC_PLZCW: /* TODO: MMI_OPC_PLZCW */
+ case MMI_OPC_PMFHL: /* TODO: MMI_OPC_PMFHL */
+ case MMI_OPC_PMTHL: /* TODO: MMI_OPC_PMTHL */
+ case MMI_OPC_PSLLH: /* TODO: MMI_OPC_PSLLH */
+ case MMI_OPC_PSRLH: /* TODO: MMI_OPC_PSRLH */
+ case MMI_OPC_PSRAH: /* TODO: MMI_OPC_PSRAH */
+ case MMI_OPC_PSLLW: /* TODO: MMI_OPC_PSLLW */
+ case MMI_OPC_PSRLW: /* TODO: MMI_OPC_PSRLW */
+ case MMI_OPC_PSRAW: /* TODO: MMI_OPC_PSRAW */
+ generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI */
break;
default:
MIPS_INVAL("TX79 MMI class");
}
}
-static void decode_tx79_lq(CPUMIPSState *env, DisasContext *ctx)
+static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
{
- generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_LQ */
+ generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_LQ */
}
-static void gen_tx79_sq(DisasContext *ctx, int base, int rt, int offset)
+static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
{
- generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_SQ */
+ generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_SQ */
}
/*
* In user mode, QEMU must verify the upper and lower 11 bits to distinguish
* between SQ and RDHWR, as the Linux kernel does.
*/
-static void decode_tx79_sq(CPUMIPSState *env, DisasContext *ctx)
+static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
{
int base = extract32(ctx->opcode, 21, 5);
int rt = extract32(ctx->opcode, 16, 5);
}
#endif
- gen_tx79_sq(ctx, base, rt, offset);
+ gen_mmi_sq(ctx, base, rt, offset);
}
static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
break;
case OPC_SPECIAL2:
if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
- decode_tx79_mmi(env, ctx);
+ decode_mmi(env, ctx);
+#if !defined(TARGET_MIPS64)
} else if (ctx->insn_flags & ASE_MXU) {
decode_opc_mxu(env, ctx);
+#endif
} else {
decode_opc_special2_legacy(env, ctx);
}
break;
case OPC_SPECIAL3:
if (ctx->insn_flags & INSN_R5900) {
- decode_tx79_sq(env, ctx); /* TX79_SQ */
+ decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */
} else {
decode_opc_special3(env, ctx);
}
break;
case OPC_LL: /* Load and stores */
check_insn(ctx, ISA_MIPS2);
- check_insn_opc_user_only(ctx, INSN_R5900);
+ if (ctx->insn_flags & INSN_R5900) {
+ check_insn_opc_user_only(ctx, INSN_R5900);
+ }
/* Fallthrough */
case OPC_LWL:
case OPC_LWR:
case OPC_SC:
check_insn(ctx, ISA_MIPS2);
check_insn_opc_removed(ctx, ISA_MIPS32R6);
- check_insn_opc_user_only(ctx, INSN_R5900);
+ if (ctx->insn_flags & INSN_R5900) {
+ check_insn_opc_user_only(ctx, INSN_R5900);
+ }
gen_st_cond(ctx, op, rt, rs, imm);
break;
case OPC_CACHE:
break;
case OPC_PREF:
check_insn_opc_removed(ctx, ISA_MIPS32R6);
- check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
- INSN_R5900);
- /* Treat as NOP. */
+ if (ctx->insn_flags & INSN_R5900) {
+ /* Treat as NOP. */
+ } else {
+ check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
+ /* Treat as NOP. */
+ }
break;
/* Floating point (COP1). */
#if defined(TARGET_MIPS64)
/* MIPS64 opcodes */
case OPC_LLD:
- check_insn_opc_user_only(ctx, INSN_R5900);
+ if (ctx->insn_flags & INSN_R5900) {
+ check_insn_opc_user_only(ctx, INSN_R5900);
+ }
/* fall through */
case OPC_LDL:
case OPC_LDR:
case OPC_SCD:
check_insn_opc_removed(ctx, ISA_MIPS32R6);
check_insn(ctx, ISA_MIPS3);
- check_insn_opc_user_only(ctx, INSN_R5900);
+ if (ctx->insn_flags & INSN_R5900) {
+ check_insn_opc_user_only(ctx, INSN_R5900);
+ }
check_mips_64(ctx);
gen_st_cond(ctx, op, rt, rs, imm);
break;
break;
case OPC_MSA: /* OPC_MDMX */
if (ctx->insn_flags & INSN_R5900) {
- decode_tx79_lq(env, ctx); /* TX79_LQ */
+ gen_mmi_lq(env, ctx); /* MMI_OPC_LQ */
} else {
/* MDMX: Not implemented. */
gen_msa(env, ctx);
offsetof(CPUMIPSState, active_fpu.fcr31),
"fcr31");
+#if defined(TARGET_MIPS64)
+ cpu_mmr[0] = NULL;
+ for (i = 1; i < 32; i++) {
+ cpu_mmr[i] = tcg_global_mem_new_i64(cpu_env,
+ offsetof(CPUMIPSState,
+ active_tc.mmr[i]),
+ regnames[i]);
+ }
+#endif
+
+#if !defined(TARGET_MIPS64)
for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
mxu_gpr[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUMIPSState,
mxu_CR = tcg_global_mem_new(cpu_env,
offsetof(CPUMIPSState, active_tc.mxu_cr),
mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
+#endif
}
#include "translate_init.inc.c"