#include "exec/helper-proto.h"
#include "exec/helper-gen.h"
-#include "exec/semihost.h"
+#include "hw/semihosting/semihost.h"
#include "target/mips/trace.h"
#include "trace-tcg.h"
#include "exec/translator.h"
#include "exec/log.h"
+#include "qemu/qemu-print.h"
#define MIPS_DEBUG_DISAS 0
/*
- * 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 cpu_gpr[32], cpu_PC;
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
static TCGv cpu_dspctrl, btarget, bcond;
+static TCGv cpu_lladdr, cpu_llval;
static TCGv_i32 hflags;
static TCGv_i32 fpu_fcr0, fpu_fcr31;
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 */
#endif
#undef OP_LD_ATOMIC
-#ifdef CONFIG_USER_ONLY
-#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
-static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
- DisasContext *ctx) \
-{ \
- TCGv t0 = tcg_temp_new(); \
- TCGLabel *l1 = gen_new_label(); \
- TCGLabel *l2 = gen_new_label(); \
- \
- tcg_gen_andi_tl(t0, arg2, almask); \
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
- tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
- generate_exception(ctx, EXCP_AdES); \
- gen_set_label(l1); \
- tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
- tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
- tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
- tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
- tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
- generate_exception_end(ctx, EXCP_SC); \
- gen_set_label(l2); \
- tcg_gen_movi_tl(t0, 0); \
- gen_store_gpr(t0, rt); \
- tcg_temp_free(t0); \
-}
-#else
-#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
-static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
- DisasContext *ctx) \
-{ \
- TCGv t0 = tcg_temp_new(); \
- gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
- gen_store_gpr(t0, rt); \
- tcg_temp_free(t0); \
-}
-#endif
-OP_ST_ATOMIC(sc,st32,ld32s,0x3);
-#if defined(TARGET_MIPS64)
-OP_ST_ATOMIC(scd,st64,ld64,0x7);
-#endif
-#undef OP_ST_ATOMIC
-
static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
int base, int offset)
{
/* Store conditional */
-static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
- int base, int16_t offset)
+static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
+ TCGMemOp tcg_mo, bool eva)
{
- TCGv t0, t1;
- int mem_idx = ctx->mem_idx;
+ TCGv addr, t0, val;
+ TCGLabel *l1 = gen_new_label();
+ TCGLabel *done = gen_new_label();
-#ifdef CONFIG_USER_ONLY
- t0 = tcg_temp_local_new();
- t1 = tcg_temp_local_new();
-#else
t0 = tcg_temp_new();
- t1 = tcg_temp_new();
-#endif
- gen_base_offset_addr(ctx, t0, base, offset);
- gen_load_gpr(t1, rt);
- switch (opc) {
-#if defined(TARGET_MIPS64)
- case OPC_SCD:
- case R6_OPC_SCD:
- op_st_scd(t1, t0, rt, mem_idx, ctx);
- break;
-#endif
- case OPC_SCE:
- mem_idx = MIPS_HFLAG_UM;
- /* fall through */
- case OPC_SC:
- case R6_OPC_SC:
- op_st_sc(t1, t0, rt, mem_idx, ctx);
- break;
- }
- tcg_temp_free(t1);
+ addr = tcg_temp_new();
+ /* compare the address against that of the preceeding LL */
+ gen_base_offset_addr(ctx, addr, base, offset);
+ tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
+ tcg_temp_free(addr);
+ tcg_gen_movi_tl(t0, 0);
+ gen_store_gpr(t0, rt);
+ tcg_gen_br(done);
+
+ gen_set_label(l1);
+ /* generate cmpxchg */
+ val = tcg_temp_new();
+ gen_load_gpr(val, rt);
+ tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
+ eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
+ tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
+ gen_store_gpr(t0, rt);
+ tcg_temp_free(val);
+
+ gen_set_label(done);
tcg_temp_free(t0);
}
+
static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
- uint32_t reg1, uint32_t reg2)
+ uint32_t reg1, uint32_t reg2, bool eva)
{
TCGv taddr = tcg_temp_local_new();
TCGv lladdr = tcg_temp_local_new();
tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
- ctx->mem_idx, MO_64);
+ eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64);
if (reg1 != 0) {
tcg_gen_movi_tl(cpu_gpr[reg1], 1);
}
tcg_temp_free(t1);
}
+#if defined(TARGET_MIPS64)
/* 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 == TX79_MMI_MFHI1 || opc == TX79_MMI_MFLO1)) {
+ if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
/* Treat as NOP. */
return;
}
switch (opc) {
- case TX79_MMI_MFHI1:
+ case MMI_OPC_MFHI1:
tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
break;
- case TX79_MMI_MFLO1:
+ case MMI_OPC_MFLO1:
tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
break;
- case TX79_MMI_MTHI1:
+ 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 TX79_MMI_MTLO1:
+ case MMI_OPC_MTLO1:
if (reg != 0) {
tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
} else {
break;
}
}
+#endif
/* Arithmetic on HI/LO registers */
static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
tcg_temp_free(t1);
}
+#if defined(TARGET_MIPS64)
static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
{
TCGv t0, t1;
gen_load_gpr(t1, rt);
switch (opc) {
- case TX79_MMI_DIV1:
+ case MMI_OPC_DIV1:
{
TCGv t2 = tcg_temp_new();
TCGv t3 = tcg_temp_new();
tcg_temp_free(t2);
}
break;
- case TX79_MMI_DIVU1:
+ case MMI_OPC_DIVU1:
{
TCGv t2 = tcg_const_tl(0);
TCGv t3 = tcg_const_tl(1);
tcg_temp_free(t0);
tcg_temp_free(t1);
}
+#endif
static void gen_muldiv(DisasContext *ctx, uint32_t opc,
int acc, int rs, int rt)
}
/*
- * 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),
+ gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_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 */
#endif
}
+#ifdef CONFIG_USER_ONLY
+/* The above should dead-code away any calls to this..*/
+static inline void gen_helper_do_semihosting(void *env)
+{
+ g_assert_not_reached();
+}
+#endif
+
static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
{
int rx, ry;
gen_st(ctx, mips32_op, rt, rs, offset);
break;
case SC:
- gen_st_cond(ctx, OPC_SC, rt, rs, offset);
+ gen_st_cond(ctx, rt, rs, offset, MO_TESL, false);
break;
#if defined(TARGET_MIPS64)
case SCD:
check_insn(ctx, ISA_MIPS3);
check_mips_64(ctx);
- gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
+ gen_st_cond(ctx, rt, rs, offset, MO_TEQ, false);
break;
#endif
case LD_EVA:
mips32_op = OPC_SHE;
goto do_st_lr;
case SCE:
- gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
+ gen_st_cond(ctx, rt, rs, offset, MO_TESL, true);
break;
case SWE:
mips32_op = OPC_SWE;
/* extraction utilities */
-#define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
-#define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
-#define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
-#define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
+#define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
+#define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
+#define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
}
-/* extraction utilities */
-
-#define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
-#define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
-#define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
-#define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
-#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
-#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
-
-
static void gen_adjust_sp(DisasContext *ctx, int u)
{
gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
static void gen_pool16c_nanomips_insn(DisasContext *ctx)
{
- int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
- int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
+ int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
+ int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
switch (extract32(ctx->opcode, 2, 2)) {
case NM_NOT16:
goto out;
}
+ /* branch completion */
+ clear_branch_hflags(ctx);
+ ctx->base.is_jmp = DISAS_NORETURN;
+
if (bcond_compute == 0) {
/* Uncoditional compact branch */
gen_goto_tb(ctx, 0, ctx->btarget);
tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
gen_op_addr_add(ctx, btarget, t1, t0);
+ /* branch completion */
+ clear_branch_hflags(ctx);
+ ctx->base.is_jmp = DISAS_NORETURN;
+
/* unconditional branch to register */
tcg_gen_mov_tl(cpu_PC, btarget);
tcg_gen_lookup_and_goto_ptr();
goto out;
}
+ /* branch completion */
+ clear_branch_hflags(ctx);
+ ctx->base.is_jmp = DISAS_NORETURN;
+
/* Generating branch here as compact branches don't have delay slot */
gen_goto_tb(ctx, 1, ctx->btarget);
gen_set_label(fs);
case NM_P_SC:
switch (ctx->opcode & 0x03) {
case NM_SC:
- gen_st_cond(ctx, OPC_SC, rt, rs, s);
+ gen_st_cond(ctx, rt, rs, s, MO_TESL, false);
break;
case NM_SCWP:
check_xnp(ctx);
- gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
+ gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
+ false);
break;
}
break;
check_xnp(ctx);
check_eva(ctx);
check_cp0_enabled(ctx);
- gen_st_cond(ctx, OPC_SCE, rt, rs, s);
+ gen_st_cond(ctx, rt, rs, s, MO_TESL, true);
break;
case NM_SCWPE:
check_xnp(ctx);
check_eva(ctx);
check_cp0_enabled(ctx);
- gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
+ gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
+ true);
break;
default:
generate_exception_end(ctx, EXCP_RI);
static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
{
uint32_t op;
- int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
- int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
- int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
+ int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
+ int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
+ int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode));
int offset;
int imm;
break;
case NM_SB16:
rt = decode_gpr_gpr3_src_store(
- NANOMIPS_EXTRACT_RD(ctx->opcode));
+ NANOMIPS_EXTRACT_RT3(ctx->opcode));
gen_st(ctx, OPC_SB, rt, rs, offset);
break;
case NM_LBU16:
break;
case NM_SH16:
rt = decode_gpr_gpr3_src_store(
- NANOMIPS_EXTRACT_RD(ctx->opcode));
+ NANOMIPS_EXTRACT_RT3(ctx->opcode));
gen_st(ctx, OPC_SH, rt, rs, offset);
break;
case NM_LHU16:
break;
case NM_SW16:
rt = decode_gpr_gpr3_src_store(
- NANOMIPS_EXTRACT_RD(ctx->opcode));
- rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
+ NANOMIPS_EXTRACT_RT3(ctx->opcode));
+ rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
offset = extract32(ctx->opcode, 0, 4) << 2;
gen_st(ctx, OPC_SW, rt, rs, offset);
break;
case NM_SWGP16:
rt = decode_gpr_gpr3_src_store(
- NANOMIPS_EXTRACT_RD(ctx->opcode));
+ NANOMIPS_EXTRACT_RT3(ctx->opcode));
offset = extract32(ctx->opcode, 0, 7) << 2;
gen_st(ctx, OPC_SW, rt, 28, offset);
break;
}
-/* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
-#define MXU_APTN1_A 0
+#if defined(TARGET_MIPS64)
+
+/*
+ *
+ * MMI (MultiMedia Interface) ASE instructions
+ * ===========================================
+ */
+
+/*
+ * MMI instructions category: data communication
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH
+ * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W
+ * PCPYUD PEXEH PEXTLW PPACW
+ * PEXEW PEXTUB
+ * PEXTUH
+ * PEXTUW
+ */
+
+/*
+ * PCPYH rd, rt
+ *
+ * Parallel Copy Halfword
+ *
+ * 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
+ * +-----------+---------+---------+---------+---------+-----------+
+ * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 |
+ * +-----------+---------+---------+---------+---------+-----------+
+ */
+static void gen_mmi_pcpyh(DisasContext *ctx)
+{
+ uint32_t pd, rt, rd;
+ uint32_t opcode;
+
+ opcode = ctx->opcode;
+
+ pd = extract32(opcode, 21, 5);
+ rt = extract32(opcode, 16, 5);
+ rd = extract32(opcode, 11, 5);
+
+ if (unlikely(pd != 0)) {
+ generate_exception_end(ctx, EXCP_RI);
+ } else if (rd == 0) {
+ /* nop */
+ } else if (rt == 0) {
+ tcg_gen_movi_i64(cpu_gpr[rd], 0);
+ tcg_gen_movi_i64(cpu_mmr[rd], 0);
+ } else {
+ TCGv_i64 t0 = tcg_temp_new();
+ TCGv_i64 t1 = tcg_temp_new();
+ uint64_t mask = (1ULL << 16) - 1;
+
+ tcg_gen_andi_i64(t0, cpu_gpr[rt], mask);
+ tcg_gen_movi_i64(t1, 0);
+ tcg_gen_or_i64(t1, t0, t1);
+ tcg_gen_shli_i64(t0, t0, 16);
+ tcg_gen_or_i64(t1, t0, t1);
+ tcg_gen_shli_i64(t0, t0, 16);
+ tcg_gen_or_i64(t1, t0, t1);
+ tcg_gen_shli_i64(t0, t0, 16);
+ tcg_gen_or_i64(t1, t0, t1);
+
+ tcg_gen_mov_i64(cpu_gpr[rd], t1);
+
+ tcg_gen_andi_i64(t0, cpu_mmr[rt], mask);
+ tcg_gen_movi_i64(t1, 0);
+ tcg_gen_or_i64(t1, t0, t1);
+ tcg_gen_shli_i64(t0, t0, 16);
+ tcg_gen_or_i64(t1, t0, t1);
+ tcg_gen_shli_i64(t0, t0, 16);
+ tcg_gen_or_i64(t1, t0, t1);
+ tcg_gen_shli_i64(t0, t0, 16);
+ tcg_gen_or_i64(t1, t0, t1);
+
+ tcg_gen_mov_i64(cpu_mmr[rd], t1);
+
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+ }
+}
+
+/*
+ * PCPYLD rd, rs, rt
+ *
+ * Parallel Copy Lower Doubleword
+ *
+ * 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
+ * +-----------+---------+---------+---------+---------+-----------+
+ * | MMI | rs | rt | rd | PCPYLD | MMI2 |
+ * +-----------+---------+---------+---------+---------+-----------+
+ */
+static void gen_mmi_pcpyld(DisasContext *ctx)
+{
+ uint32_t rs, rt, rd;
+ uint32_t opcode;
+
+ opcode = ctx->opcode;
+
+ rs = extract32(opcode, 21, 5);
+ rt = extract32(opcode, 16, 5);
+ rd = extract32(opcode, 11, 5);
+
+ if (rd == 0) {
+ /* nop */
+ } else {
+ if (rs == 0) {
+ tcg_gen_movi_i64(cpu_mmr[rd], 0);
+ } else {
+ tcg_gen_mov_i64(cpu_mmr[rd], cpu_gpr[rs]);
+ }
+ if (rt == 0) {
+ tcg_gen_movi_i64(cpu_gpr[rd], 0);
+ } else {
+ if (rd != rt) {
+ tcg_gen_mov_i64(cpu_gpr[rd], cpu_gpr[rt]);
+ }
+ }
+ }
+}
+
+/*
+ * PCPYUD rd, rs, rt
+ *
+ * Parallel Copy Upper Doubleword
+ *
+ * 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
+ * +-----------+---------+---------+---------+---------+-----------+
+ * | MMI | rs | rt | rd | PCPYUD | MMI3 |
+ * +-----------+---------+---------+---------+---------+-----------+
+ */
+static void gen_mmi_pcpyud(DisasContext *ctx)
+{
+ uint32_t rs, rt, rd;
+ uint32_t opcode;
+
+ opcode = ctx->opcode;
+
+ rs = extract32(opcode, 21, 5);
+ rt = extract32(opcode, 16, 5);
+ rd = extract32(opcode, 11, 5);
+
+ if (rd == 0) {
+ /* nop */
+ } else {
+ if (rs == 0) {
+ tcg_gen_movi_i64(cpu_gpr[rd], 0);
+ } else {
+ tcg_gen_mov_i64(cpu_gpr[rd], cpu_mmr[rs]);
+ }
+ if (rt == 0) {
+ tcg_gen_movi_i64(cpu_mmr[rd], 0);
+ } else {
+ if (rd != rt) {
+ tcg_gen_mov_i64(cpu_mmr[rd], cpu_mmr[rt]);
+ }
+ }
+ }
+}
+
+#endif
+
+
+#if !defined(TARGET_MIPS64)
+
+/* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
+#define MXU_APTN1_A 0
#define MXU_APTN1_S 1
/* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
#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)
{
}
break;
case R6_OPC_SC:
- gen_st_cond(ctx, op1, rt, rs, imm);
+ gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
break;
case R6_OPC_LL:
gen_ld(ctx, op1, rt, rs, imm);
break;
#if defined(TARGET_MIPS64)
case R6_OPC_SCD:
- gen_st_cond(ctx, op1, rt, rs, imm);
+ gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
break;
case R6_OPC_LLD:
gen_ld(ctx, op1, rt, rs, imm);
}
}
-static void decode_tx79_mmi0(CPUMIPSState *env, DisasContext *ctx)
+
+#if defined(TARGET_MIPS64)
+
+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_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;
+ case MMI_OPC_2_PCPYLD:
+ gen_mmi_pcpyld(ctx);
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_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_PEXCW: /* TODO: MMI_OPC_3_PEXCW */
+ generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
+ break;
+ case MMI_OPC_3_PCPYH:
+ gen_mmi_pcpyh(ctx);
+ break;
+ case MMI_OPC_3_PCPYUD:
+ gen_mmi_pcpyud(ctx);
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:
+ case MMI_OPC_DIV1:
+ case MMI_OPC_DIVU1:
gen_div1_tx79(ctx, opc, rs, rt);
break;
- case TX79_MMI_MTLO1:
- case TX79_MMI_MTHI1:
+ case MMI_OPC_MTLO1:
+ case MMI_OPC_MTHI1:
gen_HILO1_tx79(ctx, opc, rs);
break;
- case TX79_MMI_MFLO1:
- case TX79_MMI_MFHI1:
+ case MMI_OPC_MFLO1:
+ case MMI_OPC_MFHI1:
gen_HILO1_tx79(ctx, opc, 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_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);
}
+#endif
+
static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
{
int rs, rt, rd, sa;
return;
case OPC_SCE:
check_cp0_enabled(ctx);
- gen_st_cond(ctx, op1, rt, rs, imm);
+ gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
return;
case OPC_CACHEE:
check_cp0_enabled(ctx);
generate_exception_end(ctx, EXCP_RI);
break;
}
+ if ((MASK_MSA_ELM(ctx->opcode) == OPC_COPY_U_df) &&
+ (df == DF_WORD)) {
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
#endif
switch (MASK_MSA_ELM(ctx->opcode)) {
case OPC_COPY_S_df:
if (likely(wd != 0)) {
- gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
+ switch (df) {
+ case DF_BYTE:
+ gen_helper_msa_copy_s_b(cpu_env, twd, tws, tn);
+ break;
+ case DF_HALF:
+ gen_helper_msa_copy_s_h(cpu_env, twd, tws, tn);
+ break;
+ case DF_WORD:
+ gen_helper_msa_copy_s_w(cpu_env, twd, tws, tn);
+ break;
+#if defined(TARGET_MIPS64)
+ case DF_DOUBLE:
+ gen_helper_msa_copy_s_d(cpu_env, twd, tws, tn);
+ break;
+#endif
+ default:
+ assert(0);
+ }
}
break;
case OPC_COPY_U_df:
if (likely(wd != 0)) {
- gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
+ switch (df) {
+ case DF_BYTE:
+ gen_helper_msa_copy_u_b(cpu_env, twd, tws, tn);
+ break;
+ case DF_HALF:
+ gen_helper_msa_copy_u_h(cpu_env, twd, tws, tn);
+ break;
+#if defined(TARGET_MIPS64)
+ case DF_WORD:
+ gen_helper_msa_copy_u_w(cpu_env, twd, tws, tn);
+ break;
+#endif
+ default:
+ assert(0);
+ }
}
break;
case OPC_INSERT_df:
- gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
+ switch (df) {
+ case DF_BYTE:
+ gen_helper_msa_insert_b(cpu_env, twd, tws, tn);
+ break;
+ case DF_HALF:
+ gen_helper_msa_insert_h(cpu_env, twd, tws, tn);
+ break;
+ case DF_WORD:
+ gen_helper_msa_insert_w(cpu_env, twd, tws, tn);
+ break;
+#if defined(TARGET_MIPS64)
+ case DF_DOUBLE:
+ gen_helper_msa_insert_d(cpu_env, twd, tws, tn);
+ break;
+#endif
+ default:
+ assert(0);
+ }
break;
}
break;
decode_opc_special(env, ctx);
break;
case OPC_SPECIAL2:
+#if defined(TARGET_MIPS64)
if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
- decode_tx79_mmi(env, ctx);
- } else if (ctx->insn_flags & ASE_MXU) {
+ decode_mmi(env, ctx);
+#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 defined(TARGET_MIPS64)
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);
}
+#else
+ decode_opc_special3(env, ctx);
+#endif
break;
case OPC_REGIMM:
op1 = MASK_REGIMM(ctx->opcode);
if (ctx->insn_flags & INSN_R5900) {
check_insn_opc_user_only(ctx, INSN_R5900);
}
- gen_st_cond(ctx, op, rt, rs, imm);
- break;
+ gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
+ break;
case OPC_CACHE:
check_insn_opc_removed(ctx, ISA_MIPS32R6);
check_cp0_enabled(ctx);
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). */
check_insn_opc_user_only(ctx, INSN_R5900);
}
check_mips_64(ctx);
- gen_st_cond(ctx, op, rt, rs, imm);
+ gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
break;
case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
if (ctx->insn_flags & ISA_MIPS32R6) {
break;
case OPC_MSA: /* OPC_MDMX */
if (ctx->insn_flags & INSN_R5900) {
- decode_tx79_lq(env, ctx); /* TX79_LQ */
+#if defined(TARGET_MIPS64)
+ gen_mmi_lq(env, ctx); /* MMI_OPC_LQ */
+#endif
} else {
/* MDMX: Not implemented. */
gen_msa(env, ctx);
.disas_log = mips_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
{
DisasContext ctx;
- translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
+ translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
}
-static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
- int flags)
+static void fpu_dump_state(CPUMIPSState *env, FILE *f, int flags)
{
int i;
int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
#define printfpr(fp) \
do { \
if (is_fpu64) \
- fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
- " fd:%13g fs:%13g psu: %13g\n", \
- (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
- (double)(fp)->fd, \
- (double)(fp)->fs[FP_ENDIAN_IDX], \
- (double)(fp)->fs[!FP_ENDIAN_IDX]); \
+ qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
+ " fd:%13g fs:%13g psu: %13g\n", \
+ (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
+ (double)(fp)->fd, \
+ (double)(fp)->fs[FP_ENDIAN_IDX], \
+ (double)(fp)->fs[!FP_ENDIAN_IDX]); \
else { \
fpr_t tmp; \
tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
- fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
- " fd:%13g fs:%13g psu:%13g\n", \
- tmp.w[FP_ENDIAN_IDX], tmp.d, \
- (double)tmp.fd, \
- (double)tmp.fs[FP_ENDIAN_IDX], \
- (double)tmp.fs[!FP_ENDIAN_IDX]); \
+ qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
+ " fd:%13g fs:%13g psu:%13g\n", \
+ tmp.w[FP_ENDIAN_IDX], tmp.d, \
+ (double)tmp.fd, \
+ (double)tmp.fs[FP_ENDIAN_IDX], \
+ (double)tmp.fs[!FP_ENDIAN_IDX]); \
} \
} while(0)
- fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
- env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
- get_float_exception_flags(&env->active_fpu.fp_status));
+ qemu_fprintf(f,
+ "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
+ env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
+ get_float_exception_flags(&env->active_fpu.fp_status));
for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
- fpu_fprintf(f, "%3s: ", fregnames[i]);
+ qemu_fprintf(f, "%3s: ", fregnames[i]);
printfpr(&env->active_fpu.fpr[i]);
}
#undef printfpr
}
-void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
- int flags)
+void mips_cpu_dump_state(CPUState *cs, FILE *f, int flags)
{
MIPSCPU *cpu = MIPS_CPU(cs);
CPUMIPSState *env = &cpu->env;
int i;
- cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
- " LO=0x" TARGET_FMT_lx " ds %04x "
- TARGET_FMT_lx " " TARGET_FMT_ld "\n",
- env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
- env->hflags, env->btarget, env->bcond);
+ qemu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
+ " LO=0x" TARGET_FMT_lx " ds %04x "
+ TARGET_FMT_lx " " TARGET_FMT_ld "\n",
+ env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
+ env->hflags, env->btarget, env->bcond);
for (i = 0; i < 32; i++) {
if ((i & 3) == 0)
- cpu_fprintf(f, "GPR%02d:", i);
- cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
+ qemu_fprintf(f, "GPR%02d:", i);
+ qemu_fprintf(f, " %s " TARGET_FMT_lx,
+ regnames[i], env->active_tc.gpr[i]);
if ((i & 3) == 3)
- cpu_fprintf(f, "\n");
- }
-
- cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
- env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
- cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
- PRIx64 "\n",
- env->CP0_Config0, env->CP0_Config1, env->lladdr);
- cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
- env->CP0_Config2, env->CP0_Config3);
- cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
- env->CP0_Config4, env->CP0_Config5);
+ qemu_fprintf(f, "\n");
+ }
+
+ qemu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
+ env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
+ qemu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
+ PRIx64 "\n",
+ env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
+ qemu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
+ env->CP0_Config2, env->CP0_Config3);
+ qemu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
+ env->CP0_Config4, env->CP0_Config5);
if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
- fpu_dump_state(env, f, cpu_fprintf, flags);
+ fpu_dump_state(env, f, flags);
}
}
fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
offsetof(CPUMIPSState, active_fpu.fcr31),
"fcr31");
+ cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
+ "lladdr");
+ cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
+ "llval");
+#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"
return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
}
-bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
+bool cpu_supports_isa(const char *cpu_type, uint64_t isa)
{
const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
return (mcc->cpu_def->insn_flags & isa) != 0;
void cpu_state_reset(CPUMIPSState *env)
{
- MIPSCPU *cpu = mips_env_get_cpu(env);
- CPUState *cs = CPU(cpu);
+ CPUState *cs = env_cpu(env);
/* Reset registers to their default values */
env->CP0_PRid = env->cpu_model->CP0_PRid;