From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1FFWNV-0000B2-NQ for qemu-devel@nongnu.org; Sat, 04 Mar 2006 08:00:57 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1FFWNR-00007q-9E for qemu-devel@nongnu.org; Sat, 04 Mar 2006 08:00:56 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1FEAWs-0005wb-9c for qemu-devel@nongnu.org; Tue, 28 Feb 2006 14:29:03 -0500 Received: from [193.7.176.20] (helo=bender.bawue.de) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_3DES_EDE_CBC_SHA:24) (Exim 4.52) id 1FE7Uv-0002Sa-Ru for qemu-devel@nongnu.org; Tue, 28 Feb 2006 11:14:50 -0500 Received: from lagash (unknown [194.74.144.146]) (using TLSv1 with cipher DES-CBC3-SHA (168/168 bits)) (No client certificate requested) by bender.bawue.de (Postfix) with ESMTP id 0989944ACD for ; Tue, 28 Feb 2006 17:13:42 +0100 (MET) Received: from ths by lagash with local (Exim 4.60) (envelope-from ) id 1FE7UC-0000Zo-HA for qemu-devel@nongnu.org; Tue, 28 Feb 2006 16:14:04 +0000 Date: Tue, 28 Feb 2006 16:14:04 +0000 Message-ID: <20060228161404.GE13199@networkno.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline From: Thiemo Seufer Subject: [Qemu-devel] [PATCH] Less magic constants Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Hello All, this patch attempt to reduce the number of magic constants used in the MIPS support code, and also adds 64bit and MIPS32 R2 instruction definitions. Thiemo Index: qemu-work/target-mips/translate.c =================================================================== --- qemu-work.orig/target-mips/translate.c 2006-02-20 15:58:38.000000000 +0000 +++ qemu-work/target-mips/translate.c 2006-02-20 17:40:14.000000000 +0000 @@ -49,14 +49,7 @@ #include "gen-op.h" -/* MIPS opcodes */ -#define EXT_SPECIAL 0x100 -#define EXT_SPECIAL2 0x200 -#define EXT_REGIMM 0x300 -#define EXT_CP0 0x400 -#define EXT_CP1 0x500 -#define EXT_CP2 0x600 -#define EXT_CP3 0x700 +/* MIPS major opcodes */ enum { /* indirect opcode tables */ @@ -67,6 +60,7 @@ OPC_CP2 = 0x12, OPC_CP3 = 0x13, OPC_SPECIAL2 = 0x1C, + OPC_SPECIAL3 = 0x1F, /* arithmetic with immediate */ OPC_ADDI = 0x08, OPC_ADDIU = 0x09, @@ -76,6 +70,8 @@ OPC_ORI = 0x0D, OPC_XORI = 0x0E, OPC_LUI = 0x0F, + OPC_DADDI = 0x18, + OPC_DADDIU = 0x19, /* Jump and branches */ OPC_J = 0x02, OPC_JAL = 0x03, @@ -89,6 +85,8 @@ OPC_BGTZL = 0x17, OPC_JALX = 0x1D, /* MIPS 16 only */ /* Load and stores */ + OPC_LDL = 0x1A, + OPC_LDR = 0x1B, OPC_LB = 0x20, OPC_LH = 0x21, OPC_LWL = 0x22, @@ -96,13 +94,20 @@ OPC_LBU = 0x24, OPC_LHU = 0x25, OPC_LWR = 0x26, + OPC_LWU = 0x27, OPC_SB = 0x28, OPC_SH = 0x29, OPC_SWL = 0x2A, OPC_SW = 0x2B, + OPC_SDL = 0x2C, + OPC_SDR = 0x2D, OPC_SWR = 0x2E, OPC_LL = 0x30, + OPC_LLD = 0x34, + OPC_LD = 0x37, OPC_SC = 0x38, + OPC_SCD = 0x3C, + OPC_SD = 0x3F, /* Floating point load/store */ OPC_LWC1 = 0x31, OPC_LWC2 = 0x32, @@ -112,27 +117,54 @@ OPC_SWC2 = 0x3A, OPC_SDC1 = 0x3D, OPC_SDC2 = 0x3E, + /* MDMX ASE specific */ + OPC_MDMX = 0x1E, /* Cache and prefetch */ OPC_CACHE = 0x2F, OPC_PREF = 0x33, + /* Reserved major opcode */ + OPC_MAJOR3B_RESERVED = 0x3B, }; +#define EXT_SPECIAL (OPC_SPECIAL << 26) +#define EXT_BREGIMM (OPC_BREGIMM << 26) +#define EXT_CP0 (OPC_CP0 << 26) +#define EXT_CP1 (OPC_CP1 << 26) +#define EXT_CP2 (OPC_CP2 << 26) +#define EXT_CP3 (OPC_CP3 << 26) +#define EXT_SPECIAL2 (OPC_SPECIAL2 << 26) +#define EXT_SPECIAL3 (OPC_SPECIAL3 << 26) + /* MIPS special opcodes */ enum { /* Shifts */ OPC_SLL = 0x00 | EXT_SPECIAL, /* NOP is SLL r0, r0, 0 */ /* SSNOP is SLL r0, r0, 1 */ + /* EHB is SLL r0, r0, 3 */ OPC_SRL = 0x02 | EXT_SPECIAL, OPC_SRA = 0x03 | EXT_SPECIAL, OPC_SLLV = 0x04 | EXT_SPECIAL, OPC_SRLV = 0x06 | EXT_SPECIAL, OPC_SRAV = 0x07 | EXT_SPECIAL, + OPC_DSLLV = 0x14 | EXT_SPECIAL, + OPC_DSRLV = 0x16 | EXT_SPECIAL, + OPC_DSRAV = 0x17 | EXT_SPECIAL, + OPC_DSLL = 0x38 | EXT_SPECIAL, + OPC_DSRL = 0x3A | EXT_SPECIAL, + OPC_DSRA = 0x3B | EXT_SPECIAL, + OPC_DSLL32 = 0x3C | EXT_SPECIAL, + OPC_DSRL32 = 0x3E | EXT_SPECIAL, + OPC_DSRA32 = 0x3F | EXT_SPECIAL, /* Multiplication / division */ OPC_MULT = 0x18 | EXT_SPECIAL, OPC_MULTU = 0x19 | EXT_SPECIAL, OPC_DIV = 0x1A | EXT_SPECIAL, OPC_DIVU = 0x1B | EXT_SPECIAL, + OPC_DMULT = 0x1C | EXT_SPECIAL, + OPC_DMULTU = 0x1D | EXT_SPECIAL, + OPC_DDIV = 0x1E | EXT_SPECIAL, + OPC_DDIVU = 0x1F | EXT_SPECIAL, /* 2 registers arithmetic / logic */ OPC_ADD = 0x20 | EXT_SPECIAL, OPC_ADDU = 0x21 | EXT_SPECIAL, @@ -144,9 +176,13 @@ OPC_NOR = 0x27 | EXT_SPECIAL, OPC_SLT = 0x2A | EXT_SPECIAL, OPC_SLTU = 0x2B | EXT_SPECIAL, + OPC_DADD = 0x2C | EXT_SPECIAL, + OPC_DADDU = 0x2D | EXT_SPECIAL, + OPC_DSUB = 0x2E | EXT_SPECIAL, + OPC_DSUBU = 0x2F | EXT_SPECIAL, /* Jumps */ - OPC_JR = 0x08 | EXT_SPECIAL, - OPC_JALR = 0x09 | EXT_SPECIAL, + OPC_JR = 0x08 | EXT_SPECIAL, /* Also JR.HB */ + OPC_JALR = 0x09 | EXT_SPECIAL, /* Also JALR.HB */ /* Traps */ OPC_TGE = 0x30 | EXT_SPECIAL, OPC_TGEU = 0x31 | EXT_SPECIAL, @@ -166,14 +202,43 @@ OPC_MOVCI = 0x01 | EXT_SPECIAL, /* Special */ - OPC_PMON = 0x05 | EXT_SPECIAL, + OPC_PMON = 0x05 | EXT_SPECIAL, /* inofficial */ OPC_SYSCALL = 0x0C | EXT_SPECIAL, OPC_BREAK = 0x0D | EXT_SPECIAL, + OPC_SPIM = 0x0E | EXT_SPECIAL, /* inofficial */ OPC_SYNC = 0x0F | EXT_SPECIAL, + + OPC_SPECIAL15_RESERVED = 0x15 | EXT_SPECIAL, + OPC_SPECIAL28_RESERVED = 0x28 | EXT_SPECIAL, + OPC_SPECIAL29_RESERVED = 0x29 | EXT_SPECIAL, + OPC_SPECIAL35_RESERVED = 0x35 | EXT_SPECIAL, + OPC_SPECIAL37_RESERVED = 0x37 | EXT_SPECIAL, + OPC_SPECIAL39_RESERVED = 0x39 | EXT_SPECIAL, + OPC_SPECIAL3D_RESERVED = 0x3D | EXT_SPECIAL, +}; + +/* REGIMM (rt field) opcodes */ +enum { + OPC_BLTZ = (0x00 << 16) | EXT_BREGIMM, + OPC_BLTZL = (0x02 << 16) | EXT_BREGIMM, + OPC_BGEZ = (0x01 << 16) | EXT_BREGIMM, + OPC_BGEZL = (0x03 << 16) | EXT_BREGIMM, + OPC_BLTZAL = (0x10 << 16) | EXT_BREGIMM, + OPC_BLTZALL = (0x12 << 16) | EXT_BREGIMM, + OPC_BGEZAL = (0x11 << 16) | EXT_BREGIMM, + OPC_BGEZALL = (0x13 << 16) | EXT_BREGIMM, + OPC_TGEI = (0x08 << 16) | EXT_BREGIMM, + OPC_TGEIU = (0x09 << 16) | EXT_BREGIMM, + OPC_TLTI = (0x0A << 16) | EXT_BREGIMM, + OPC_TLTIU = (0x0B << 16) | EXT_BREGIMM, + OPC_TEQI = (0x0C << 16) | EXT_BREGIMM, + OPC_TNEI = (0x0E << 16) | EXT_BREGIMM, + OPC_SYNCI = (0x1F << 16) | EXT_BREGIMM, }; +/* Special2 opcodes */ enum { - /* Mutiply & xxx operations */ + /* Multiply & xxx operations */ OPC_MADD = 0x00 | EXT_SPECIAL2, OPC_MADDU = 0x01 | EXT_SPECIAL2, OPC_MUL = 0x02 | EXT_SPECIAL2, @@ -182,42 +247,66 @@ /* Misc */ OPC_CLZ = 0x20 | EXT_SPECIAL2, OPC_CLO = 0x21 | EXT_SPECIAL2, + OPC_DCLZ = 0x24 | EXT_SPECIAL2, + OPC_DCLO = 0x25 | EXT_SPECIAL2, /* Special */ OPC_SDBBP = 0x3F | EXT_SPECIAL2, }; -/* Branch REGIMM */ +/* Special3 opcodes */ +enum { + OPC_EXT = 0x00 | EXT_SPECIAL3, + OPC_DEXTM = 0x01 | EXT_SPECIAL3, + OPC_DEXTU = 0x02 | EXT_SPECIAL3, + OPC_DEXT = 0x03 | EXT_SPECIAL3, + OPC_INS = 0x04 | EXT_SPECIAL3, + OPC_DINSM = 0x05 | EXT_SPECIAL3, + OPC_DINSU = 0x06 | EXT_SPECIAL3, + OPC_DINS = 0x07 | EXT_SPECIAL3, + OPC_BSHFL = 0x20 | EXT_SPECIAL3, + OPC_DBSHFL = 0x24 | EXT_SPECIAL3, + OPC_RDHWR = 0x3B | EXT_SPECIAL3, +}; + +/* Coprocessor 0 (rs field) */ +enum { + OPC_MFC0 = (0x00 << 21) | EXT_CP0, + OPC_DMFC0 = (0x01 << 21) | EXT_CP0, + OPC_MTC0 = (0x04 << 21) | EXT_CP0, + OPC_DMTC0 = (0x05 << 21) | EXT_CP0, + OPC_RDPGPR = (0x0A << 21) | EXT_CP0, + OPC_MFMC0 = (0x0B << 21) | EXT_CP0, + OPC_WRPGPR = (0x0E << 21) | EXT_CP0, + OPC_C0 = (0x10 << 21) | EXT_CP0, + OPC_C0_FIRST = (0x10 << 21) | EXT_CP0, + OPC_C0_LAST = (0x1F << 21) | EXT_CP0, +}; + +/* Coprocessor 0 (with rs=C0) */ enum { - OPC_BLTZ = 0x00 | EXT_REGIMM, - OPC_BLTZL = 0x02 | EXT_REGIMM, - OPC_BGEZ = 0x01 | EXT_REGIMM, - OPC_BGEZL = 0x03 | EXT_REGIMM, - OPC_BLTZAL = 0x10 | EXT_REGIMM, - OPC_BLTZALL = 0x12 | EXT_REGIMM, - OPC_BGEZAL = 0x11 | EXT_REGIMM, - OPC_BGEZALL = 0x13 | EXT_REGIMM, - OPC_TGEI = 0x08 | EXT_REGIMM, - OPC_TGEIU = 0x09 | EXT_REGIMM, - OPC_TLTI = 0x0A | EXT_REGIMM, - OPC_TLTIU = 0x0B | EXT_REGIMM, - OPC_TEQI = 0x0C | EXT_REGIMM, - OPC_TNEI = 0x0E | EXT_REGIMM, + OPC_TLBR = 0x01 | OPC_C0, + OPC_TLBWI = 0x02 | OPC_C0, + OPC_TLBWR = 0x06 | OPC_C0, + OPC_TLBP = 0x08 | OPC_C0, + OPC_RFE = 0x10 | OPC_C0, + OPC_ERET = 0x18 | OPC_C0, + OPC_DERET = 0x1F | OPC_C0, + OPC_WAIT = 0x20 | OPC_C0, }; +/* Coprocessor 1 (rs field) */ enum { - /* Coprocessor 0 (MMU) */ - OPC_MFC0 = 0x00 | EXT_CP0, - OPC_MTC0 = 0x04 | EXT_CP0, - OPC_TLBR = 0x01 | EXT_CP0, - OPC_TLBWI = 0x02 | EXT_CP0, - OPC_TLBWR = 0x06 | EXT_CP0, - OPC_TLBP = 0x08 | EXT_CP0, - OPC_ERET = 0x18 | EXT_CP0, - OPC_DERET = 0x1F | EXT_CP0, - OPC_WAIT = 0x20 | EXT_CP0, + OPC_MFC1 = (0x00 << 21) | EXT_CP1, + OPC_DMFC1 = (0x01 << 21) | EXT_CP1, + OPC_CFC1 = (0x02 << 21) | EXT_CP1, + OPC_MFHCI = (0x03 << 21) | EXT_CP1, + OPC_MTC1 = (0x04 << 21) | EXT_CP1, + OPC_DMTC1 = (0x05 << 21) | EXT_CP1, + OPC_CTC1 = (0x06 << 21) | EXT_CP1, + OPC_MTHCI = (0x07 << 21) | EXT_CP1, }; -const unsigned char *regnames[] = +const char *regnames[] = { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", @@ -399,10 +488,10 @@ OP_ST_TABLE(c); /* Load and store */ -static void gen_ldst (DisasContext *ctx, uint16_t opc, int rt, +static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, int base, int16_t offset) { - const unsigned char *opn = "unk"; + const char *opn = "unk"; if (base == 0) { GEN_LOAD_IMM_TN(T0, offset); @@ -553,11 +642,11 @@ } /* Arithmetic with immediate operand */ -static void gen_arith_imm (DisasContext *ctx, uint16_t opc, int rt, +static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt, int rs, int16_t imm) { uint32_t uimm; - const unsigned char *opn = "unk"; + const char *opn = "unk"; if (rt == 0 && opc != OPC_ADDI) { /* if no destination, treat it as a NOP @@ -634,10 +723,10 @@ } /* Arithmetic */ -static void gen_arith (DisasContext *ctx, uint16_t opc, +static void gen_arith (DisasContext *ctx, uint32_t opc, int rd, int rs, int rt) { - const unsigned char *opn = "unk"; + const char *opn = "unk"; if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB) { /* if no destination, treat it as a NOP @@ -727,9 +816,9 @@ } /* Arithmetic on HI/LO registers */ -static void gen_HILO (DisasContext *ctx, uint16_t opc, int reg) +static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg) { - const unsigned char *opn = "unk"; + const char *opn = "unk"; if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { /* Treat as a NOP */ @@ -766,10 +855,10 @@ MIPS_DEBUG("%s %s", opn, regnames[reg]); } -static void gen_muldiv (DisasContext *ctx, uint16_t opc, +static void gen_muldiv (DisasContext *ctx, uint32_t opc, int rs, int rt) { - const unsigned char *opn = "unk"; + const char *opn = "unk"; GEN_LOAD_REG_TN(T0, rs); GEN_LOAD_REG_TN(T1, rt); @@ -815,10 +904,10 @@ MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]); } -static void gen_cl (DisasContext *ctx, uint16_t opc, +static void gen_cl (DisasContext *ctx, uint32_t opc, int rd, int rs) { - const unsigned char *opn = "unk"; + const char *opn = "unk"; if (rd == 0) { /* Treat as a NOP */ MIPS_DEBUG("NOP"); @@ -847,7 +936,7 @@ } /* Traps */ -static void gen_trap (DisasContext *ctx, uint16_t opc, +static void gen_trap (DisasContext *ctx, uint32_t opc, int rs, int rt, int16_t imm) { int cond; @@ -964,7 +1053,7 @@ } /* Branches (before delay slot) */ -static void gen_compute_branch (DisasContext *ctx, uint16_t opc, +static void gen_compute_branch (DisasContext *ctx, uint32_t opc, int rs, int rt, int32_t offset) { target_ulong btarget; @@ -1188,7 +1277,7 @@ /* CP0 (MMU and control) */ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) { - const unsigned char *rn; + const char *rn; if (sel != 0 && reg != 16 && reg != 28) { rn = "invalid"; @@ -1338,12 +1427,9 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) { - const unsigned char *rn; - uint32_t val, old, mask; + const char *rn; if (sel != 0 && reg != 16 && reg != 28) { - val = -1; - old = -1; rn = "invalid"; goto die; } @@ -1475,9 +1561,9 @@ ctx->bstate = BS_EXCP; } -static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd) +static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd) { - const unsigned char *opn = "unk"; + const char *opn = "unk"; if (!(ctx->CP0_Status & (1 << CP0St_CU0)) && !(ctx->hflags & MIPS_HFLAG_UM) && @@ -1572,7 +1658,7 @@ /* SmartMIPS extension to MIPS32 */ #ifdef TARGET_MIPS64 -static void gen_arith64 (DisasContext *ctx, uint16_t opc) +static void gen_arith64 (DisasContext *ctx, uint32_t opc) { if (func == 0x02 && rd == 0) { /* NOP */ @@ -1617,7 +1703,7 @@ { int32_t offset; int rs, rt, rd, sa; - uint16_t op, op1; + uint32_t op, op1; int16_t imm; if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) { @@ -1632,54 +1718,57 @@ sa = ((ctx->opcode >> 6) & 0x1F); imm = (int16_t)ctx->opcode; switch (op) { - case 0x00: /* Special opcode */ - op1 = ctx->opcode & 0x3F; + case OPC_SPECIAL: + op1 = (ctx->opcode & 0x3F) | EXT_SPECIAL; switch (op1) { - case 0x00: /* Arithmetic with immediate */ - case 0x02 ... 0x03: - gen_arith_imm(ctx, op1 | EXT_SPECIAL, rd, rt, sa); - break; - case 0x04: /* Arithmetic */ - case 0x06 ... 0x07: - case 0x0A ... 0x0B: - case 0x20 ... 0x27: - case 0x2A ... 0x2B: - gen_arith(ctx, op1 | EXT_SPECIAL, rd, rs, rt); + case OPC_SLL: /* Arithmetic with immediate */ + case OPC_SRL ... OPC_SRA: + gen_arith_imm(ctx, op1, rd, rt, sa); + break; + case OPC_SLLV: /* Arithmetic */ + case OPC_SRLV ... OPC_SRAV: + case OPC_MOVZ ... OPC_MOVN: + case OPC_ADD ... OPC_NOR: + case OPC_SLT ... OPC_SLTU: + gen_arith(ctx, op1, rd, rs, rt); break; - case 0x18 ... 0x1B: /* MULT / DIV */ - gen_muldiv(ctx, op1 | EXT_SPECIAL, rs, rt); + case OPC_MULT ... OPC_DIVU: + gen_muldiv(ctx, op1, rs, rt); break; - case 0x08 ... 0x09: /* Jumps */ - gen_compute_branch(ctx, op1 | EXT_SPECIAL, rs, rd, sa); + case OPC_JR ... OPC_JALR: + gen_compute_branch(ctx, op1, rs, rd, sa); return; - case 0x30 ... 0x34: /* Traps */ - case 0x36: - gen_trap(ctx, op1 | EXT_SPECIAL, rs, rt, -1); - break; - case 0x10: /* Move from HI/LO */ - case 0x12: - gen_HILO(ctx, op1 | EXT_SPECIAL, rd); - break; - case 0x11: - case 0x13: /* Move to HI/LO */ - gen_HILO(ctx, op1 | EXT_SPECIAL, rs); + case OPC_TGE ... OPC_TEQ: /* Traps */ + case OPC_TNE: + gen_trap(ctx, op1, rs, rt, -1); + break; + case OPC_MFHI: /* Move from HI/LO */ + case OPC_MFLO: + gen_HILO(ctx, op1, rd); + break; + case OPC_MTHI: + case OPC_MTLO: /* Move to HI/LO */ + gen_HILO(ctx, op1, rs); break; - case 0x0C: /* SYSCALL */ + case OPC_PMON: /* Pmon entry point */ + gen_op_pmon((ctx->opcode >> 6) & 0x1F); + break; + case OPC_SYSCALL: generate_exception(ctx, EXCP_SYSCALL); ctx->bstate = BS_EXCP; break; - case 0x0D: /* BREAK */ + case OPC_BREAK: generate_exception(ctx, EXCP_BREAK); ctx->bstate = BS_EXCP; break; - case 0x0F: /* SYNC */ - /* Treat as a noop */ + case OPC_SPIM: /* SPIM ? */ + /* implemented as RI exception for now */ break; - case 0x05: /* Pmon entry point */ - gen_op_pmon((ctx->opcode >> 6) & 0x1F); + case OPC_SYNC: + /* Treat as a noop */ break; - case 0x01: /* MOVCI */ + case OPC_MOVCI: #if defined (MIPS_HAS_MOVCI) /* XXX */ #else @@ -1690,14 +1779,14 @@ break; #if defined (TARGET_MIPS64) - case 0x14: /* MIPS64 specific opcodes */ - case 0x16: - case 0x17: - case 0x1C ... 0x1F: - case 0x2C ... 0x2F: - case 0x37: - case 0x39 ... 0x3B: - case 0x3E ... 0x3F: + case OPC_DSLLV: /* MIPS64 specific opcodes */ + case OPC_DSRLV ... OPC_DSRAV: + case OPC_DMULT ... OPC_DDIVU: + case OPC_DADD ... OPC_DSUBU: + case OPC_DSLL: + case OPC_DSRL ... OPC_DSRA: + case OPC_DSLL32: + case OPC_DSRL32 ... OPC_DSRA32: #endif default: /* Invalid */ MIPS_INVAL("special"); @@ -1706,23 +1795,23 @@ break; } break; - case 0x1C: /* Special2 opcode */ - op1 = ctx->opcode & 0x3F; + case OPC_SPECIAL2: + op1 = (ctx->opcode & 0x3F) | EXT_SPECIAL2; switch (op1) { #if defined (MIPS_USES_R4K_EXT) /* Those instructions are not part of MIPS32 core */ - case 0x00 ... 0x01: /* Multiply and add/sub */ - case 0x04 ... 0x05: - gen_muldiv(ctx, op1 | EXT_SPECIAL2, rs, rt); + case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */ + case OPC_MSUB ... OPC_MSUBU: + gen_muldiv(ctx, op1, rs, rt); break; - case 0x02: /* MUL */ - gen_arith(ctx, op1 | EXT_SPECIAL2, rd, rs, rt); + case OPC_MUL: + gen_arith(ctx, op1, rd, rs, rt); break; - case 0x20 ... 0x21: /* CLO / CLZ */ - gen_cl(ctx, op1 | EXT_SPECIAL2, rd, rs); + case OPC_CLZ ... OPC_CLO: + gen_cl(ctx, op1, rd, rs); break; #endif - case 0x3F: /* SDBBP */ + case OPC_SDBBP: /* XXX: not clear which exception should be raised * when in debug mode... */ @@ -1742,16 +1831,16 @@ break; } break; - case 0x01: /* B REGIMM opcode */ - op1 = ((ctx->opcode >> 16) & 0x1F); + case OPC_BREGIMM: + op1 = (ctx->opcode & 0x001F0000) | EXT_BREGIMM; switch (op1) { - case 0x00 ... 0x03: /* REGIMM branches */ - case 0x10 ... 0x13: - gen_compute_branch(ctx, op1 | EXT_REGIMM, rs, -1, imm << 2); + case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */ + case OPC_BLTZAL ... OPC_BGEZALL: + gen_compute_branch(ctx, op1, rs, -1, imm << 2); return; - case 0x08 ... 0x0C: /* Traps */ - case 0x0E: - gen_trap(ctx, op1 | EXT_REGIMM, rs, -1, imm); + case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */ + case OPC_TNEI: + gen_trap(ctx, op1, rs, -1, imm); break; default: /* Invalid */ MIPS_INVAL("REGIMM"); @@ -1760,50 +1849,61 @@ break; } break; - case 0x10: /* CP0 opcode */ - op1 = ((ctx->opcode >> 21) & 0x1F); + case OPC_CP0: + op1 = (ctx->opcode & 0x03E00000) | EXT_CP0; switch (op1) { - case 0x00: - case 0x04: - gen_cp0(ctx, op1 | EXT_CP0, rt, rd); - break; - default: - gen_cp0(ctx, (ctx->opcode & 0x3F) | EXT_CP0, rt, rd); + case OPC_MFC0: + case OPC_MTC0: + gen_cp0(ctx, op1, rt, rd); + break; + case OPC_C0_FIRST ... OPC_C0_LAST: + gen_cp0(ctx, (ctx->opcode & 0x3F) | OPC_C0, rt, rd); + break; +#ifdef MIPS_HAS_MIPS64 + case OPC_DMFC0: + case OPC_DMTC0: +#endif + case OPC_RDPGPR: + case OPC_MFMC0: + case OPC_WRPGPR: + default: + generate_exception(ctx, EXCP_RI); + ctx->bstate = BS_EXCP; break; - } + } break; - case 0x08 ... 0x0F: /* Arithmetic with immediate opcode */ + case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */ gen_arith_imm(ctx, op, rt, rs, imm); break; - case 0x02 ... 0x03: /* Jump */ + case OPC_J ... OPC_JAL: /* Jump */ offset = (int32_t)(ctx->opcode & 0x03FFFFFF) << 2; gen_compute_branch(ctx, op, rs, rt, offset); return; - case 0x04 ... 0x07: /* Branch */ - case 0x14 ... 0x17: + case OPC_BEQ ... OPC_BGTZ: /* Branch */ + case OPC_BEQL ... OPC_BGTZL: gen_compute_branch(ctx, op, rs, rt, imm << 2); return; - case 0x20 ... 0x26: /* Load and stores */ - case 0x28 ... 0x2E: - case 0x30: - case 0x38: + case OPC_LB ... OPC_LWR: /* Load and stores */ + case OPC_SB ... OPC_SW: + case OPC_SWR: + case OPC_LL: + case OPC_SC: gen_ldst(ctx, op, rt, rs, imm); break; - case 0x2F: /* Cache operation */ + case OPC_CACHE: /* Treat as a noop */ break; - case 0x33: /* Prefetch */ + case OPC_PREF: /* Treat as a noop */ break; - case 0x3F: /* HACK */ - break; /* Floating point. */ - case 0x31: /* LWC1 */ - case 0x35: /* LDC1 */ - case 0x39: /* SWC1 */ - case 0x3D: /* SDC1 */ - case 0x11: /* CP1 opcode */ + case OPC_LWC1: + case OPC_LDC1: + case OPC_SWC1: + case OPC_SDC1: + case OPC_CP1: + case OPC_CP3: #if defined(MIPS_USES_FPU) /* XXX: not correct */ #else @@ -1813,35 +1913,35 @@ break; /* COP2. */ - case 0x32: /* LWC2 */ - case 0x36: /* LDC2 */ - case 0x3A: /* SWC2 */ - case 0x3E: /* SDC2 */ - case 0x12: /* CP2 opcode */ + case OPC_LWC2: + case OPC_LDC2: + case OPC_SWC2: + case OPC_SDC2: + case OPC_CP2: /* Not implemented */ generate_exception_err(ctx, EXCP_CpU, 2); ctx->bstate = BS_EXCP; break; - case 0x13: /* CP3 opcode */ - /* Not implemented */ - generate_exception_err(ctx, EXCP_CpU, 3); - ctx->bstate = BS_EXCP; - break; - #if defined (TARGET_MIPS64) - case 0x18 ... 0x1B: - case 0x27: - case 0x34: - case 0x37: + case OPC_LWU: + case OPC_DADDI ... OPC_DADDIU: + case OPC_LDL ... OPC_LDR: + case OPC_SDL ... OPC_SDR: + case OPC_LLD: + case OPC_LD: + case OPC_SCD: + case OPC_SD: /* MIPS64 opcodes */ #endif -#if defined (MIPS_HAS_JALX) - case 0x1D: - /* JALX: not implemented */ +#ifdef MIPS_HAS_MIPS16 + case OPC_JALX: + /* MIPS16: not implemented */ +#endif +#ifdef MIPS_HAS_MDMX + case OPC_MDMX: + /* MDMX: not implemented */ #endif - case 0x1E: - /* ASE specific */ default: /* Invalid */ MIPS_INVAL(""); generate_exception(ctx, EXCP_RI);