blob: 4bff585bd63ce1985b1ebb174cb59915871c1ffe [file] [log] [blame]
/*
* MIPS emulation for QEMU - main translation routines
*
* Copyright (c) 2004-2005 Jocelyn Mayer
* Copyright (c) 2006 Marius Groeger (FPU operations)
* Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
* Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
* Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "cpu.h"
#include "internal.h"
#include "disas/disas.h"
#include "exec/exec-all.h"
#include "tcg-op.h"
#include "exec/cpu_ldst.h"
#include "hw/mips/cpudevs.h"
#include "exec/helper-proto.h"
#include "exec/helper-gen.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
/* MIPS major opcodes */
#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
enum {
/* indirect opcode tables */
OPC_SPECIAL = (0x00 << 26),
OPC_REGIMM = (0x01 << 26),
OPC_CP0 = (0x10 << 26),
OPC_CP1 = (0x11 << 26),
OPC_CP2 = (0x12 << 26),
OPC_CP3 = (0x13 << 26),
OPC_SPECIAL2 = (0x1C << 26),
OPC_SPECIAL3 = (0x1F << 26),
/* arithmetic with immediate */
OPC_ADDI = (0x08 << 26),
OPC_ADDIU = (0x09 << 26),
OPC_SLTI = (0x0A << 26),
OPC_SLTIU = (0x0B << 26),
/* logic with immediate */
OPC_ANDI = (0x0C << 26),
OPC_ORI = (0x0D << 26),
OPC_XORI = (0x0E << 26),
OPC_LUI = (0x0F << 26),
/* arithmetic with immediate */
OPC_DADDI = (0x18 << 26),
OPC_DADDIU = (0x19 << 26),
/* Jump and branches */
OPC_J = (0x02 << 26),
OPC_JAL = (0x03 << 26),
OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
OPC_BEQL = (0x14 << 26),
OPC_BNE = (0x05 << 26),
OPC_BNEL = (0x15 << 26),
OPC_BLEZ = (0x06 << 26),
OPC_BLEZL = (0x16 << 26),
OPC_BGTZ = (0x07 << 26),
OPC_BGTZL = (0x17 << 26),
OPC_JALX = (0x1D << 26),
OPC_DAUI = (0x1D << 26),
/* Load and stores */
OPC_LDL = (0x1A << 26),
OPC_LDR = (0x1B << 26),
OPC_LB = (0x20 << 26),
OPC_LH = (0x21 << 26),
OPC_LWL = (0x22 << 26),
OPC_LW = (0x23 << 26),
OPC_LWPC = OPC_LW | 0x5,
OPC_LBU = (0x24 << 26),
OPC_LHU = (0x25 << 26),
OPC_LWR = (0x26 << 26),
OPC_LWU = (0x27 << 26),
OPC_SB = (0x28 << 26),
OPC_SH = (0x29 << 26),
OPC_SWL = (0x2A << 26),
OPC_SW = (0x2B << 26),
OPC_SDL = (0x2C << 26),
OPC_SDR = (0x2D << 26),
OPC_SWR = (0x2E << 26),
OPC_LL = (0x30 << 26),
OPC_LLD = (0x34 << 26),
OPC_LD = (0x37 << 26),
OPC_LDPC = OPC_LD | 0x5,
OPC_SC = (0x38 << 26),
OPC_SCD = (0x3C << 26),
OPC_SD = (0x3F << 26),
/* Floating point load/store */
OPC_LWC1 = (0x31 << 26),
OPC_LWC2 = (0x32 << 26),
OPC_LDC1 = (0x35 << 26),
OPC_LDC2 = (0x36 << 26),
OPC_SWC1 = (0x39 << 26),
OPC_SWC2 = (0x3A << 26),
OPC_SDC1 = (0x3D << 26),
OPC_SDC2 = (0x3E << 26),
/* Compact Branches */
OPC_BLEZALC = (0x06 << 26),
OPC_BGEZALC = (0x06 << 26),
OPC_BGEUC = (0x06 << 26),
OPC_BGTZALC = (0x07 << 26),
OPC_BLTZALC = (0x07 << 26),
OPC_BLTUC = (0x07 << 26),
OPC_BOVC = (0x08 << 26),
OPC_BEQZALC = (0x08 << 26),
OPC_BEQC = (0x08 << 26),
OPC_BLEZC = (0x16 << 26),
OPC_BGEZC = (0x16 << 26),
OPC_BGEC = (0x16 << 26),
OPC_BGTZC = (0x17 << 26),
OPC_BLTZC = (0x17 << 26),
OPC_BLTC = (0x17 << 26),
OPC_BNVC = (0x18 << 26),
OPC_BNEZALC = (0x18 << 26),
OPC_BNEC = (0x18 << 26),
OPC_BC = (0x32 << 26),
OPC_BEQZC = (0x36 << 26),
OPC_JIC = (0x36 << 26),
OPC_BALC = (0x3A << 26),
OPC_BNEZC = (0x3E << 26),
OPC_JIALC = (0x3E << 26),
/* MDMX ASE specific */
OPC_MDMX = (0x1E << 26),
/* MSA ASE, same as MDMX */
OPC_MSA = OPC_MDMX,
/* Cache and prefetch */
OPC_CACHE = (0x2F << 26),
OPC_PREF = (0x33 << 26),
/* PC-relative address computation / loads */
OPC_PCREL = (0x3B << 26),
};
/* PC-relative address computation / loads */
#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
enum {
/* Instructions determined by bits 19 and 20 */
OPC_ADDIUPC = OPC_PCREL | (0 << 19),
R6_OPC_LWPC = OPC_PCREL | (1 << 19),
OPC_LWUPC = OPC_PCREL | (2 << 19),
/* Instructions determined by bits 16 ... 20 */
OPC_AUIPC = OPC_PCREL | (0x1e << 16),
OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
/* Other */
R6_OPC_LDPC = OPC_PCREL | (6 << 18),
};
/* MIPS special opcodes */
#define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
enum {
/* Shifts */
OPC_SLL = 0x00 | OPC_SPECIAL,
/* NOP is SLL r0, r0, 0 */
/* SSNOP is SLL r0, r0, 1 */
/* EHB is SLL r0, r0, 3 */
OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
OPC_ROTR = OPC_SRL | (1 << 21),
OPC_SRA = 0x03 | OPC_SPECIAL,
OPC_SLLV = 0x04 | OPC_SPECIAL,
OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
OPC_ROTRV = OPC_SRLV | (1 << 6),
OPC_SRAV = 0x07 | OPC_SPECIAL,
OPC_DSLLV = 0x14 | OPC_SPECIAL,
OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
OPC_DROTRV = OPC_DSRLV | (1 << 6),
OPC_DSRAV = 0x17 | OPC_SPECIAL,
OPC_DSLL = 0x38 | OPC_SPECIAL,
OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
OPC_DROTR = OPC_DSRL | (1 << 21),
OPC_DSRA = 0x3B | OPC_SPECIAL,
OPC_DSLL32 = 0x3C | OPC_SPECIAL,
OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
OPC_DSRA32 = 0x3F | OPC_SPECIAL,
/* Multiplication / division */
OPC_MULT = 0x18 | OPC_SPECIAL,
OPC_MULTU = 0x19 | OPC_SPECIAL,
OPC_DIV = 0x1A | OPC_SPECIAL,
OPC_DIVU = 0x1B | OPC_SPECIAL,
OPC_DMULT = 0x1C | OPC_SPECIAL,
OPC_DMULTU = 0x1D | OPC_SPECIAL,
OPC_DDIV = 0x1E | OPC_SPECIAL,
OPC_DDIVU = 0x1F | OPC_SPECIAL,
/* 2 registers arithmetic / logic */
OPC_ADD = 0x20 | OPC_SPECIAL,
OPC_ADDU = 0x21 | OPC_SPECIAL,
OPC_SUB = 0x22 | OPC_SPECIAL,
OPC_SUBU = 0x23 | OPC_SPECIAL,
OPC_AND = 0x24 | OPC_SPECIAL,
OPC_OR = 0x25 | OPC_SPECIAL,
OPC_XOR = 0x26 | OPC_SPECIAL,
OPC_NOR = 0x27 | OPC_SPECIAL,
OPC_SLT = 0x2A | OPC_SPECIAL,
OPC_SLTU = 0x2B | OPC_SPECIAL,
OPC_DADD = 0x2C | OPC_SPECIAL,
OPC_DADDU = 0x2D | OPC_SPECIAL,
OPC_DSUB = 0x2E | OPC_SPECIAL,
OPC_DSUBU = 0x2F | OPC_SPECIAL,
/* Jumps */
OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
/* Traps */
OPC_TGE = 0x30 | OPC_SPECIAL,
OPC_TGEU = 0x31 | OPC_SPECIAL,
OPC_TLT = 0x32 | OPC_SPECIAL,
OPC_TLTU = 0x33 | OPC_SPECIAL,
OPC_TEQ = 0x34 | OPC_SPECIAL,
OPC_TNE = 0x36 | OPC_SPECIAL,
/* HI / LO registers load & stores */
OPC_MFHI = 0x10 | OPC_SPECIAL,
OPC_MTHI = 0x11 | OPC_SPECIAL,
OPC_MFLO = 0x12 | OPC_SPECIAL,
OPC_MTLO = 0x13 | OPC_SPECIAL,
/* Conditional moves */
OPC_MOVZ = 0x0A | OPC_SPECIAL,
OPC_MOVN = 0x0B | OPC_SPECIAL,
OPC_SELEQZ = 0x35 | OPC_SPECIAL,
OPC_SELNEZ = 0x37 | OPC_SPECIAL,
OPC_MOVCI = 0x01 | OPC_SPECIAL,
/* Special */
OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
OPC_SYSCALL = 0x0C | OPC_SPECIAL,
OPC_BREAK = 0x0D | OPC_SPECIAL,
OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
OPC_SYNC = 0x0F | OPC_SPECIAL,
OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
};
/*
* R6 Multiply and Divide instructions have the same opcode
* and function field as legacy OPC_MULT[U]/OPC_DIV[U]
*/
#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
enum {
R6_OPC_MUL = OPC_MULT | (2 << 6),
R6_OPC_MUH = OPC_MULT | (3 << 6),
R6_OPC_MULU = OPC_MULTU | (2 << 6),
R6_OPC_MUHU = OPC_MULTU | (3 << 6),
R6_OPC_DIV = OPC_DIV | (2 << 6),
R6_OPC_MOD = OPC_DIV | (3 << 6),
R6_OPC_DIVU = OPC_DIVU | (2 << 6),
R6_OPC_MODU = OPC_DIVU | (3 << 6),
R6_OPC_DMUL = OPC_DMULT | (2 << 6),
R6_OPC_DMUH = OPC_DMULT | (3 << 6),
R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
R6_OPC_DDIV = OPC_DDIV | (2 << 6),
R6_OPC_DMOD = OPC_DDIV | (3 << 6),
R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
R6_OPC_CLO = 0x11 | OPC_SPECIAL,
R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
OPC_LSA = 0x05 | OPC_SPECIAL,
OPC_DLSA = 0x15 | OPC_SPECIAL,
};
/* Multiplication variants of the vr54xx. */
#define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6)))
enum {
OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
};
/* REGIMM (rt field) opcodes */
#define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
enum {
OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
OPC_DATI = (0x1e << 16) | OPC_REGIMM,
};
/* Special2 opcodes */
#define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
enum {
/* Multiply & xxx operations */
OPC_MADD = 0x00 | OPC_SPECIAL2,
OPC_MADDU = 0x01 | OPC_SPECIAL2,
OPC_MUL = 0x02 | OPC_SPECIAL2,
OPC_MSUB = 0x04 | OPC_SPECIAL2,
OPC_MSUBU = 0x05 | OPC_SPECIAL2,
/* Loongson 2F */
OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
/* Misc */
OPC_CLZ = 0x20 | OPC_SPECIAL2,
OPC_CLO = 0x21 | OPC_SPECIAL2,
OPC_DCLZ = 0x24 | OPC_SPECIAL2,
OPC_DCLO = 0x25 | OPC_SPECIAL2,
/* Special */
OPC_SDBBP = 0x3F | OPC_SPECIAL2,
};
/* Special3 opcodes */
#define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
enum {
OPC_EXT = 0x00 | OPC_SPECIAL3,
OPC_DEXTM = 0x01 | OPC_SPECIAL3,
OPC_DEXTU = 0x02 | OPC_SPECIAL3,
OPC_DEXT = 0x03 | OPC_SPECIAL3,
OPC_INS = 0x04 | OPC_SPECIAL3,
OPC_DINSM = 0x05 | OPC_SPECIAL3,
OPC_DINSU = 0x06 | OPC_SPECIAL3,
OPC_DINS = 0x07 | OPC_SPECIAL3,
OPC_FORK = 0x08 | OPC_SPECIAL3,
OPC_YIELD = 0x09 | OPC_SPECIAL3,
OPC_BSHFL = 0x20 | OPC_SPECIAL3,
OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
OPC_RDHWR = 0x3B | OPC_SPECIAL3,
/* Loongson 2E */
OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
/* MIPS DSP Load */
OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
/* MIPS DSP Arithmetic */
OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
/* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
/* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
/* MIPS DSP GPR-Based Shift Sub-class */
OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
/* MIPS DSP Multiply Sub-class insns */
/* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
/* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
/* DSP Bit/Manipulation Sub-class */
OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
/* MIPS DSP Append Sub-class */
OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
/* MIPS DSP Accumulator and DSPControl Access Sub-class */
OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
/* EVA */
OPC_LWLE = 0x19 | OPC_SPECIAL3,
OPC_LWRE = 0x1A | OPC_SPECIAL3,
OPC_CACHEE = 0x1B | OPC_SPECIAL3,
OPC_SBE = 0x1C | OPC_SPECIAL3,
OPC_SHE = 0x1D | OPC_SPECIAL3,
OPC_SCE = 0x1E | OPC_SPECIAL3,
OPC_SWE = 0x1F | OPC_SPECIAL3,
OPC_SWLE = 0x21 | OPC_SPECIAL3,
OPC_SWRE = 0x22 | OPC_SPECIAL3,
OPC_PREFE = 0x23 | OPC_SPECIAL3,
OPC_LBUE = 0x28 | OPC_SPECIAL3,
OPC_LHUE = 0x29 | OPC_SPECIAL3,
OPC_LBE = 0x2C | OPC_SPECIAL3,
OPC_LHE = 0x2D | OPC_SPECIAL3,
OPC_LLE = 0x2E | OPC_SPECIAL3,
OPC_LWE = 0x2F | OPC_SPECIAL3,
/* R6 */
R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
R6_OPC_LL = 0x36 | OPC_SPECIAL3,
R6_OPC_SC = 0x26 | OPC_SPECIAL3,
R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
};
/* BSHFL opcodes */
#define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
OPC_SEB = (0x10 << 6) | OPC_BSHFL,
OPC_SEH = (0x18 << 6) | OPC_BSHFL,
OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL,
OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL,
OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL,
OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
};
/* DBSHFL opcodes */
#define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL,
OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL,
OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL,
OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL,
OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL,
OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL,
OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL,
OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
};
/* MIPS DSP REGIMM opcodes */
enum {
OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
};
#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
/* MIPS DSP Load */
enum {
OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
};
#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
/* MIPS DSP Arithmetic Sub-class */
OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
/* MIPS DSP Multiply Sub-class insns */
OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
};
#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
/* MIPS DSP Arithmetic Sub-class */
OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
/* MIPS DSP Multiply Sub-class insns */
OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
};
#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
/* MIPS DSP Arithmetic Sub-class */
OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
/* DSP Bit/Manipulation Sub-class */
OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
};
#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
/* MIPS DSP Arithmetic Sub-class */
OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
/* DSP Compare-Pick Sub-class */
OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
};
#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
/* MIPS DSP GPR-Based Shift Sub-class */
OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
};
#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
/* MIPS DSP Multiply Sub-class insns */
OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
};
#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
/* DSP Bit/Manipulation Sub-class */
OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
};
#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
/* MIPS DSP Append Sub-class */
OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
};
#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
/* MIPS DSP Accumulator and DSPControl Access Sub-class */
OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
};
#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
/* MIPS DSP Arithmetic Sub-class */
OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
/* DSP Bit/Manipulation Sub-class */
OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
};
#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
/* MIPS DSP Multiply Sub-class insns */
OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
/* MIPS DSP Arithmetic Sub-class */
OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
};
#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
/* DSP Compare-Pick Sub-class */
OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
/* MIPS DSP Arithmetic Sub-class */
OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
};
#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
/* DSP Append Sub-class */
OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
};
#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
/* MIPS DSP Accumulator and DSPControl Access Sub-class */
OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
};
#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
/* DSP Bit/Manipulation Sub-class */
OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
};
#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
/* MIPS DSP Multiply Sub-class insns */
OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
};
#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
enum {
/* MIPS DSP GPR-Based Shift Sub-class */
OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
};
/* Coprocessor 0 (rs field) */
#define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
enum {
OPC_MFC0 = (0x00 << 21) | OPC_CP0,
OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
OPC_MTC0 = (0x04 << 21) | OPC_CP0,
OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
OPC_MFTR = (0x08 << 21) | OPC_CP0,
OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
OPC_MTTR = (0x0C << 21) | OPC_CP0,
OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
OPC_C0 = (0x10 << 21) | OPC_CP0,
OPC_C0_1 = (0x11 << 21) | OPC_CP0,
OPC_C0_2 = (0x12 << 21) | OPC_CP0,
OPC_C0_3 = (0x13 << 21) | OPC_CP0,
OPC_C0_4 = (0x14 << 21) | OPC_CP0,
OPC_C0_5 = (0x15 << 21) | OPC_CP0,
OPC_C0_6 = (0x16 << 21) | OPC_CP0,
OPC_C0_7 = (0x17 << 21) | OPC_CP0,
OPC_C0_8 = (0x18 << 21) | OPC_CP0,
OPC_C0_9 = (0x19 << 21) | OPC_CP0,
OPC_C0_A = (0x1A << 21) | OPC_CP0,
OPC_C0_B = (0x1B << 21) | OPC_CP0,
OPC_C0_C = (0x1C << 21) | OPC_CP0,
OPC_C0_D = (0x1D << 21) | OPC_CP0,
OPC_C0_E = (0x1E << 21) | OPC_CP0,
OPC_C0_F = (0x1F << 21) | OPC_CP0,
};
/* MFMC0 opcodes */
#define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
enum {
OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
};
/* Coprocessor 0 (with rs == C0) */
#define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
enum {
OPC_TLBR = 0x01 | OPC_C0,
OPC_TLBWI = 0x02 | OPC_C0,
OPC_TLBINV = 0x03 | OPC_C0,
OPC_TLBINVF = 0x04 | 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) */
#define MASK_CP1(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
/* Values for the fmt field in FP instructions */
enum {
/* 0 - 15 are reserved */
FMT_S = 16, /* single fp */
FMT_D = 17, /* double fp */
FMT_E = 18, /* extended fp */
FMT_Q = 19, /* quad fp */
FMT_W = 20, /* 32-bit fixed */
FMT_L = 21, /* 64-bit fixed */
FMT_PS = 22, /* paired single fp */
/* 23 - 31 are reserved */
};
enum {
OPC_MFC1 = (0x00 << 21) | OPC_CP1,
OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
OPC_CFC1 = (0x02 << 21) | OPC_CP1,
OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
OPC_MTC1 = (0x04 << 21) | OPC_CP1,
OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
OPC_CTC1 = (0x06 << 21) | OPC_CP1,
OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
OPC_BZ_V = (0x0B << 21) | OPC_CP1,
OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
OPC_BZ_B = (0x18 << 21) | OPC_CP1,
OPC_BZ_H = (0x19 << 21) | OPC_CP1,
OPC_BZ_W = (0x1A << 21) | OPC_CP1,
OPC_BZ_D = (0x1B << 21) | OPC_CP1,
OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
};
#define MASK_CP1_FUNC(op) (MASK_CP1(op) | (op & 0x3F))
#define MASK_BC1(op) (MASK_CP1(op) | (op & (0x3 << 16)))
enum {
OPC_BC1F = (0x00 << 16) | OPC_BC1,
OPC_BC1T = (0x01 << 16) | OPC_BC1,
OPC_BC1FL = (0x02 << 16) | OPC_BC1,
OPC_BC1TL = (0x03 << 16) | OPC_BC1,
};
enum {
OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
};
enum {
OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
};
#define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
enum {
OPC_MFC2 = (0x00 << 21) | OPC_CP2,
OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
OPC_CFC2 = (0x02 << 21) | OPC_CP2,
OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
OPC_MTC2 = (0x04 << 21) | OPC_CP2,
OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
OPC_CTC2 = (0x06 << 21) | OPC_CP2,
OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
OPC_BC2 = (0x08 << 21) | OPC_CP2,
OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
};
#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
enum {
OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
};
#define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
enum {
OPC_LWXC1 = 0x00 | OPC_CP3,
OPC_LDXC1 = 0x01 | OPC_CP3,
OPC_LUXC1 = 0x05 | OPC_CP3,
OPC_SWXC1 = 0x08 | OPC_CP3,
OPC_SDXC1 = 0x09 | OPC_CP3,
OPC_SUXC1 = 0x0D | OPC_CP3,
OPC_PREFX = 0x0F | OPC_CP3,
OPC_ALNV_PS = 0x1E | OPC_CP3,
OPC_MADD_S = 0x20 | OPC_CP3,
OPC_MADD_D = 0x21 | OPC_CP3,
OPC_MADD_PS = 0x26 | OPC_CP3,
OPC_MSUB_S = 0x28 | OPC_CP3,
OPC_MSUB_D = 0x29 | OPC_CP3,
OPC_MSUB_PS = 0x2E | OPC_CP3,
OPC_NMADD_S = 0x30 | OPC_CP3,
OPC_NMADD_D = 0x31 | OPC_CP3,
OPC_NMADD_PS = 0x36 | OPC_CP3,
OPC_NMSUB_S = 0x38 | OPC_CP3,
OPC_NMSUB_D = 0x39 | OPC_CP3,
OPC_NMSUB_PS = 0x3E | OPC_CP3,
};
/* MSA Opcodes */
#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
enum {
OPC_MSA_I8_00 = 0x00 | OPC_MSA,
OPC_MSA_I8_01 = 0x01 | OPC_MSA,
OPC_MSA_I8_02 = 0x02 | OPC_MSA,
OPC_MSA_I5_06 = 0x06 | OPC_MSA,
OPC_MSA_I5_07 = 0x07 | OPC_MSA,
OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
OPC_MSA_3R_0D = 0x0D | OPC_MSA,
OPC_MSA_3R_0E = 0x0E | OPC_MSA,
OPC_MSA_3R_0F = 0x0F | OPC_MSA,
OPC_MSA_3R_10 = 0x10 | OPC_MSA,
OPC_MSA_3R_11 = 0x11 | OPC_MSA,
OPC_MSA_3R_12 = 0x12 | OPC_MSA,
OPC_MSA_3R_13 = 0x13 | OPC_MSA,
OPC_MSA_3R_14 = 0x14 | OPC_MSA,
OPC_MSA_3R_15 = 0x15 | OPC_MSA,
OPC_MSA_ELM = 0x19 | OPC_MSA,
OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
OPC_MSA_VEC = 0x1E | OPC_MSA,
/* MI10 instruction */
OPC_LD_B = (0x20) | OPC_MSA,
OPC_LD_H = (0x21) | OPC_MSA,
OPC_LD_W = (0x22) | OPC_MSA,
OPC_LD_D = (0x23) | OPC_MSA,
OPC_ST_B = (0x24) | OPC_MSA,
OPC_ST_H = (0x25) | OPC_MSA,
OPC_ST_W = (0x26) | OPC_MSA,
OPC_ST_D = (0x27) | OPC_MSA,
};
enum {
/* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
/* I8 instruction */
OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
/* VEC/2R/2RF instruction */
OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
/* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
/* 2RF instruction df(bit 16) = _w, _d */
OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
/* 3R instruction df(bits 22..21) = _b, _h, _w, d */
OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
/* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
/* 3RF instruction _df(bit 21) = _w, _d */
OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
/* BIT instruction df(bits 22..16) = _B _H _W _D */
OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
};
/*
*
* 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
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Register operands:
*
* XRa, XRb, XRc, XRd - MXU registers
* Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
*
* 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
*
* Prefixes:
*
* 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:
*
* ADD - Add or subtract
* ADDC - Add with carry-in
* ACC - Accumulate
* ASUM - Sum together then accumulate (add or subtract)
* ASUMC - Sum together then accumulate (add or subtract) with carry-in
* AVG - Average between 2 operands
* ABD - Absolute difference
* ALN - Align data
* AND - Logical bitwise 'and' operation
* CPS - Copy sign
* EXTR - Extract bits
* I2M - Move from GPR register to MXU register
* LDD - Load data from memory to XRF
* LDI - Load data from memory to XRF (and increase the address base)
* LUI - Load unsigned immediate
* MUL - Multiply
* MULU - Unsigned multiply
* MADD - 64-bit operand add 32x32 product
* MSUB - 64-bit operand subtract 32x32 product
* MAC - Multiply and accumulate (add or subtract)
* MAD - Multiply and add or subtract
* MAX - Maximum between 2 operands
* MIN - Minimum between 2 operands
* M2I - Move from MXU register to GPR register
* MOVZ - Move if zero
* MOVN - Move if non-zero
* NOR - Logical bitwise 'nor' operation
* OR - Logical bitwise 'or' operation
* STD - Store data from XRF to memory
* SDI - Store data from XRF to memory (and increase the address base)
* SLT - Set of less than comparison
* SAD - Sum of absolute differences
* SLL - Logical shift left
* SLR - Logical shift right
* SAR - Arithmetic shift right
* SAT - Saturation
* SFL - Shuffle
* 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
* ----------------------- ---------------------------
*
* S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
* S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
* S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt
* S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt
* S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
* S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
* S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
* S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
* S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
* S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
* S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
* S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
* S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
* S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
* S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
* S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
* S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
* S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
* S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
* S16SDI XRa, Rb, s10, eptn2
* S8LDD XRa, Rb, s8, eptn3
* S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
* S8LDI XRa, Rb, s8, eptn3 -------------------------------------
* S8SDI XRa, Rb, s8, eptn3
* LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
* LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
* LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
* LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
* LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
* S32CPS XRa, XRb, XRc
* Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
* Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
* ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
* D16ASUM XRa, XRb, XRc, XRd, eptn2
* S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
* S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
* S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
* S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
* S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
* D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
* D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
* D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
* D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
* D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
* Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
* Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
* Q8SLT XRa, XRb, XRc
* Q8SLTU XRa, XRb, XRc
* Q8MOVZ XRa, XRb, XRc Shift instructions
* Q8MOVN XRa, XRb, XRc ------------------
*
* D32SLL XRa, XRb, XRc, XRd, sft4
* Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
* -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
* D32SARL XRa, XRb, XRc, sft4
* S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
* S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
* S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
* S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
* Q16SLL XRa, XRb, XRc, XRd, sft4
* Q16SLR XRa, XRb, XRc, XRd, sft4
* Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
* ------------------------- Q16SLLV XRa, XRb, Rb
* Q16SLRV XRa, XRb, Rb
* S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
* S32ALN XRa, XRb, XRc, Rb
* S32ALNI XRa, XRb, XRc, s3
* S32LUI XRa, s8, optn3 Move instructions
* S32EXTR XRa, XRb, Rb, bits5 -----------------
* S32EXTRV XRa, XRb, Rs, Rt
* Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
* 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
*
* ┌─ 000000 ─ OPC_MXU_S32MADD
* ├─ 000001 ─ OPC_MXU_S32MADDU
* ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
* │
* │ 20..18
* ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
* │ ├─ 001 ─ OPC_MXU_S32MIN
* │ ├─ 010 ─ OPC_MXU_D16MAX
* │ ├─ 011 ─ OPC_MXU_D16MIN
* │ ├─ 100 ─ OPC_MXU_Q8MAX
* │ ├─ 101 ─ OPC_MXU_Q8MIN
* │ ├─ 110 ─ OPC_MXU_Q8SLT
* │ └─ 111 ─ OPC_MXU_Q8SLTU
* ├─ 000100 ─ OPC_MXU_S32MSUB
* ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
* ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
* │ ├─ 001 ─ OPC_MXU_D16SLT
* │ ├─ 010 ─ OPC_MXU_D16AVG
* │ ├─ 011 ─ OPC_MXU_D16AVGR
* │ ├─ 100 ─ OPC_MXU_Q8AVG
* │ ├─ 101 ─ OPC_MXU_Q8AVGR
* │ └─ 111 ─ OPC_MXU_Q8ADD
* │
* │ 20..18
* ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
* │ ├─ 010 ─ OPC_MXU_D16CPS
* │ ├─ 100 ─ OPC_MXU_Q8ABD
* │ └─ 110 ─ OPC_MXU_Q16SAT
* ├─ 001000 ─ OPC_MXU_D16MUL
* │ 25..24
* ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
* │ └─ 01 ─ OPC_MXU_D16MULE
* ├─ 001010 ─ OPC_MXU_D16MAC
* ├─ 001011 ─ OPC_MXU_D16MACF
* ├─ 001100 ─ OPC_MXU_D16MADL
* ├─ 001101 ─ OPC_MXU_S16MAD
* ├─ 001110 ─ OPC_MXU_Q16ADD
* ├─ 001111 ─ OPC_MXU_D16MACE 23
* │ ┌─ 0 ─ OPC_MXU_S32LDD
* ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
* │
* │ 23
* ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
* │ └─ 1 ─ OPC_MXU_S32STDR
* │
* │ 13..10
* ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
* │ └─ 0001 ─ OPC_MXU_S32LDDVR
* │
* │ 13..10
* ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
* │ └─ 0001 ─ OPC_MXU_S32STDVR
* │
* │ 23
* ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
* │ └─ 1 ─ OPC_MXU_S32LDIR
* │
* │ 23
* ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
* │ └─ 1 ─ OPC_MXU_S32SDIR
* │
* │ 13..10
* ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
* │ └─ 0001 ─ OPC_MXU_S32LDIVR
* │
* │ 13..10
* ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
* │ └─ 0001 ─ OPC_MXU_S32SDIVR
* ├─ 011000 ─ OPC_MXU_D32ADD
* │ 23..22
* MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
* opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
* │ └─ 10 ─ OPC_MXU_D32ASUM
* ├─ 011010 ─ <not assigned>
* │ 23..22
* ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
* │ ├─ 01 ─ OPC_MXU_Q16ACCM
* │ └─ 10 ─ OPC_MXU_Q16ASUM
* │
* │ 23..22
* ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
* │ ├─ 01 ─ OPC_MXU_D8SUM
* ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
* ├─ 011110 ─ <not assigned>
* ├─ 011111 ─ <not assigned>
* ├─ 100000 ─ <not assigned> (overlaps with CLZ)
* ├─ 100001 ─ <not assigned> (overlaps with CLO)
* ├─ 100010 ─ OPC_MXU_S8LDD
* ├─ 100011 ─ OPC_MXU_S8STD 15..14
* ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
* ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
* │ ├─ 00 ─ OPC_MXU_S32EXTR
* ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
* │
* │ 20..18
* ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
* │ ├─ 001 ─ OPC_MXU_S32ALN
* │ ├─ 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
* ├─ 110001 ─ OPC_MXU_D32SLR 20..18
* ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
* ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
* ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
* ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
* │ ├─ 100 ─ OPC_MXU_Q16SLRV
* ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
* │
* ├─ 110111 ─ OPC_MXU_Q16SAR
* │ 23..22
* ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
* │ └─ 01 ─ OPC_MXU_Q8MULSU
* │
* │ 20..18
* ├─ 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_S32MOVN
* │
* │ 23..22
* ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
* │ └─ 10 ─ OPC_MXU_Q8MACSU
* ├─ 111011 ─ OPC_MXU_Q16SCOP
* ├─ 111100 ─ OPC_MXU_Q8MADL
* ├─ 111101 ─ OPC_MXU_S32SFL
* ├─ 111110 ─ OPC_MXU_Q8SAD
* └─ 111111 ─ <not assigned> (overlaps with SDBBP)
*
*
* Compiled after:
*
* "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
* Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
*/
enum {
OPC_MXU_S32MADD = 0x00,
OPC_MXU_S32MADDU = 0x01,
OPC__MXU_MUL = 0x02,
OPC_MXU__POOL00 = 0x03,
OPC_MXU_S32MSUB = 0x04,
OPC_MXU_S32MSUBU = 0x05,
OPC_MXU__POOL01 = 0x06,
OPC_MXU__POOL02 = 0x07,
OPC_MXU_D16MUL = 0x08,
OPC_MXU__POOL03 = 0x09,
OPC_MXU_D16MAC = 0x0A,
OPC_MXU_D16MACF = 0x0B,
OPC_MXU_D16MADL = 0x0C,
OPC_MXU_S16MAD = 0x0D,
OPC_MXU_Q16ADD = 0x0E,
OPC_MXU_D16MACE = 0x0F,
OPC_MXU__POOL04 = 0x10,
OPC_MXU__POOL05 = 0x11,
OPC_MXU__POOL06 = 0x12,
OPC_MXU__POOL07 = 0x13,
OPC_MXU__POOL08 = 0x14,
OPC_MXU__POOL09 = 0x15,
OPC_MXU__POOL10 = 0x16,
OPC_MXU__POOL11 = 0x17,
OPC_MXU_D32ADD = 0x18,
OPC_MXU__POOL12 = 0x19,
/* not assigned 0x1A */
OPC_MXU__POOL13 = 0x1B,
OPC_MXU__POOL14 = 0x1C,
OPC_MXU_Q8ACCE = 0x1D,
/* not assigned 0x1E */
/* not assigned 0x1F */
/* not assigned 0x20 */
/* not assigned 0x21 */
OPC_MXU_S8LDD = 0x22,
OPC_MXU_S8STD = 0x23,
OPC_MXU_S8LDI = 0x24,
OPC_MXU_S8SDI = 0x25,
OPC_MXU__POOL15 = 0x26,
OPC_MXU__POOL16 = 0x27,
OPC_MXU__POOL17 = 0x28,
/* not assigned 0x29 */
OPC_MXU_S16LDD = 0x2A,
OPC_MXU_S16STD = 0x2B,
OPC_MXU_S16LDI = 0x2C,
OPC_MXU_S16SDI = 0x2D,
OPC_MXU_S32M2I = 0x2E,
OPC_MXU_S32I2M = 0x2F,
OPC_MXU_D32SLL = 0x30,
OPC_MXU_D32SLR = 0x31,
OPC_MXU_D32SARL = 0x32,
OPC_MXU_D32SAR = 0x33,
OPC_MXU_Q16SLL = 0x34,
OPC_MXU_Q16SLR = 0x35,
OPC_MXU__POOL18 = 0x36,
OPC_MXU_Q16SAR = 0x37,
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_Q8SAD = 0x3E,
/* not assigned 0x3F */
};
/*
* MXU pool 00
*/
enum {
OPC_MXU_S32MAX = 0x00,
OPC_MXU_S32MIN = 0x01,
OPC_MXU_D16MAX = 0x02,
OPC_MXU_D16MIN = 0x03,
OPC_MXU_Q8MAX = 0x04,
OPC_MXU_Q8MIN = 0x05,
OPC_MXU_Q8SLT = 0x06,
OPC_MXU_Q8SLTU = 0x07,
};
/*
* MXU pool 01
*/
enum {
OPC_MXU_S32SLT = 0x00,
OPC_MXU_D16SLT = 0x01,
OPC_MXU_D16AVG = 0x02,
OPC_MXU_D16AVGR = 0x03,
OPC_MXU_Q8AVG = 0x04,
OPC_MXU_Q8AVGR = 0x05,
OPC_MXU_Q8ADD = 0x07,
};
/*
* MXU pool 02
*/
enum {
OPC_MXU_S32CPS = 0x00,
OPC_MXU_D16CPS = 0x02,
OPC_MXU_Q8ABD = 0x04,
OPC_MXU_Q16SAT = 0x06,
};
/*
* MXU pool 03
*/
enum {
OPC_MXU_D16MULF = 0x00,
OPC_MXU_D16MULE = 0x01,
};
/*
* MXU pool 04
*/
enum {
OPC_MXU_S32LDD = 0x00,
OPC_MXU_S32LDDR = 0x01,
};
/*
* MXU pool 05
*/
enum {
OPC_MXU_S32STD = 0x00,
OPC_MXU_S32STDR = 0x01,
};
/*
* MXU pool 06
*/
enum {
OPC_MXU_S32LDDV = 0x00,
OPC_MXU_S32LDDVR = 0x01,
};
/*
* MXU pool 07
*/
enum {
OPC_MXU_S32STDV = 0x00,
OPC_MXU_S32STDVR = 0x01,
};
/*
* MXU pool 08
*/
enum {
OPC_MXU_S32LDI = 0x00,
OPC_MXU_S32LDIR = 0x01,
};
/*
* MXU pool 09
*/
enum {
OPC_MXU_S32SDI = 0x00,
OPC_MXU_S32SDIR = 0x01,
};
/*
* MXU pool 10
*/
enum {
OPC_MXU_S32LDIV = 0x00,
OPC_MXU_S32LDIVR = 0x01,
};
/*
* MXU pool 11
*/
enum {
OPC_MXU_S32SDIV = 0x00,
OPC_MXU_S32SDIVR = 0x01,
};
/*
* MXU pool 12
*/
enum {
OPC_MXU_D32ACC = 0x00,
OPC_MXU_D32ACCM = 0x01,
OPC_MXU_D32ASUM = 0x02,
};
/*
* MXU pool 13
*/
enum {
OPC_MXU_Q16ACC = 0x00,
OPC_MXU_Q16ACCM = 0x01,
OPC_MXU_Q16ASUM = 0x02,
};
/*
* MXU pool 14
*/
enum {
OPC_MXU_Q8ADDE = 0x00,
OPC_MXU_D8SUM = 0x01,
OPC_MXU_D8SUMC = 0x02,
};
/*
* MXU pool 15
*/
enum {
OPC_MXU_S32MUL = 0x00,
OPC_MXU_S32MULU = 0x01,
OPC_MXU_S32EXTR = 0x02,
OPC_MXU_S32EXTRV = 0x03,
};
/*
* MXU pool 16
*/
enum {
OPC_MXU_D32SARW = 0x00,
OPC_MXU_S32ALN = 0x01,
OPC_MXU_S32ALNI = 0x02,
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,
OPC_MXU_D32SARV = 0x03,
OPC_MXU_Q16SLLV = 0x04,
OPC_MXU_Q16SLRV = 0x05,
OPC_MXU_Q16SARV = 0x07,
};
/*
* MXU pool 19
*/
enum {
OPC_MXU_Q8MUL = 0x00,
OPC_MXU_Q8MULSU = 0x01,
};
/*
* MXU pool 20
*/
enum {
OPC_MXU_Q8MOVZ = 0x00,
OPC_MXU_Q8MOVN = 0x01,
OPC_MXU_D16MOVZ = 0x02,
OPC_MXU_D16MOVN = 0x03,
OPC_MXU_S32MOVZ = 0x04,
OPC_MXU_S32MOVN = 0x05,
};
/*
* MXU pool 21
*/
enum {
OPC_MXU_Q8MAC = 0x00,
OPC_MXU_Q8MACSU = 0x01,
};
/*
* Overview of the TX79-specific instruction set
* =============================================
*
* The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
* are only used by the specific quadword (128-bit) LQ/SQ load/store
* instructions and certain multimedia instructions (MMIs). These MMIs
* configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
* or sixteen 8-bit paths.
*
* Reference:
*
* The Toshiba TX System RISC TX79 Core Architecture manual,
* https://wiki.qemu.org/File:C790.pdf
*
* Three-Operand Multiply and Multiply-Add (4 instructions)
* --------------------------------------------------------
* MADD [rd,] rs, rt Multiply/Add
* MADDU [rd,] rs, rt Multiply/Add Unsigned
* MULT [rd,] rs, rt Multiply (3-operand)
* MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
*
* Multiply Instructions for Pipeline 1 (10 instructions)
* ------------------------------------------------------
* MULT1 [rd,] rs, rt Multiply Pipeline 1
* MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
* DIV1 rs, rt Divide Pipeline 1
* DIVU1 rs, rt Divide Unsigned Pipeline 1
* MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
* MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
* MFHI1 rd Move From HI1 Register
* MFLO1 rd Move From LO1 Register
* MTHI1 rs Move To HI1 Register
* MTLO1 rs Move To LO1 Register
*
* Arithmetic (19 instructions)
* ----------------------------
* PADDB rd, rs, rt Parallel Add Byte
* PSUBB rd, rs, rt Parallel Subtract Byte
* PADDH rd, rs, rt Parallel Add Halfword
* PSUBH rd, rs, rt Parallel Subtract Halfword
* PADDW rd, rs, rt Parallel Add Word
* PSUBW rd, rs, rt Parallel Subtract Word
* PADSBH rd, rs, rt Parallel Add/Subtract Halfword
* PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
* PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
* PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
* PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
* PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
* PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
* PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
* PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
* PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
* PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
* PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
* PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
*
* Min/Max (4 instructions)
* ------------------------
* PMAXH rd, rs, rt Parallel Maximum Halfword
* PMINH rd, rs, rt Parallel Minimum Halfword
* PMAXW rd, rs, rt Parallel Maximum Word
* PMINW rd, rs, rt Parallel Minimum Word
*
* Absolute (2 instructions)
* -------------------------
* PABSH rd, rt Parallel Absolute Halfword
* PABSW rd, rt Parallel Absolute Word
*
* Logical (4 instructions)
* ------------------------
* PAND rd, rs, rt Parallel AND
* POR rd, rs, rt Parallel OR
* PXOR rd, rs, rt Parallel XOR
* PNOR rd, rs, rt Parallel NOR
*
* Shift (9 instructions)
* ----------------------
* PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
* PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
* PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
* PSLLW rd, rt, sa Parallel Shift Left Logical Word
* PSRLW rd, rt, sa Parallel Shift Right Logical Word
* PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
* PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
* PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
* PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
*
* Compare (6 instructions)
* ------------------------
* PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
* PCEQB rd, rs, rt Parallel Compare for Equal Byte
* PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
* PCEQH rd, rs, rt Parallel Compare for Equal Halfword
* PCGTW rd, rs, rt Parallel Compare for Greater Than Word
* PCEQW rd, rs, rt Parallel Compare for Equal Word
*
* LZC (1 instruction)
* -------------------
* PLZCW rd, rs Parallel Leading Zero or One Count Word
*
* Quadword Load and Store (2 instructions)
* ----------------------------------------
* LQ rt, offset(base) Load Quadword
* SQ rt, offset(base) Store Quadword
*
* Multiply and Divide (19 instructions)
* -------------------------------------
* PMULTW rd, rs, rt Parallel Multiply Word
* PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
* PDIVW rs, rt Parallel Divide Word
* PDIVUW rs, rt Parallel Divide Unsigned Word
* PMADDW rd, rs, rt Parallel Multiply-Add Word
* PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
* PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
* PMULTH rd, rs, rt Parallel Multiply Halfword
* PMADDH rd, rs, rt Parallel Multiply-Add Halfword
* PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
* PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
* PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
* PDIVBW rs, rt Parallel Divide Broadcast Word
* PMFHI rd Parallel Move From HI Register
* PMFLO rd Parallel Move From LO Register
* PMTHI rs Parallel Move To HI Register
* PMTLO rs Parallel Move To LO Register
* PMFHL rd Parallel Move From HI/LO Register
* PMTHL rs Parallel Move To HI/LO Register
*
* Pack/Extend (11 instructions)
* -----------------------------
* PPAC5 rd, rt Parallel Pack to 5 bits
* PPACB rd, rs, rt Parallel Pack to Byte
* PPACH rd, rs, rt Parallel Pack to Halfword
* PPACW rd, rs, rt Parallel Pack to Word
* PEXT5 rd, rt Parallel Extend Upper from 5 bits
* PEXTUB rd, rs, rt Parallel Extend Upper from Byte
* PEXTLB rd, rs, rt Parallel Extend Lower from Byte
* PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
* PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
* PEXTUW rd, rs, rt Parallel Extend Upper from Word
* PEXTLW rd, rs, rt Parallel Extend Lower from Word
*
* Others (16 instructions)
* ------------------------
* PCPYH rd, rt Parallel Copy Halfword
* PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
* PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
* PREVH rd, rt Parallel Reverse Halfword
* PINTH rd, rs, rt Parallel Interleave Halfword
* PINTEH rd, rs, rt Parallel Interleave Even Halfword
* PEXEH rd, rt Parallel Exchange Even Halfword
* PEXCH rd, rt Parallel Exchange Center Halfword
* PEXEW rd, rt Parallel Exchange Even Word
* PEXCW rd, rt Parallel Exchange Center Word
* QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
* MFSA rd Move from Shift Amount Register
* MTSA rs Move to Shift Amount Register
* MTSAB rs, immediate Move Byte Count to Shift Amount Register
* MTSAH rs, immediate Move Halfword Count to Shift Amount Register
* PROT3W rd, rt Parallel Rotate 3 Words
*
* MMI (MultiMedia Instruction) encodings
* ======================================
*
* MMI instructions encoding table keys:
*
* * This code is reserved for future use. An attempt to execute it
* causes a Reserved Instruction exception.
* % This code indicates an instruction class. The instruction word
* must be further decoded by examining additional tables that show
* the values for other instruction fields.
* # This code is reserved for the unsupported instructions DMULT,
* DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
* to execute it causes a Reserved Instruction exception.
*
* MMI instructions encoded by opcode field (MMI, LQ, SQ):
*
* 31 26 0
* +--------+----------------------------------------+
* | opcode | |
* +--------+----------------------------------------+
*
* opcode bits 28..26
* bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
* 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
* -------+-------+-------+-------+-------+-------+-------+-------+-------
* 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
* 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
* 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
* 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
* 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
* 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
* 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
* 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
*/
enum {
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 */
};
/*
* MMI instructions with opcode field = MMI:
*
* 31 26 5 0
* +--------+-------------------------------+--------+
* | MMI | |function|
* +--------+-------------------------------+--------+
*
* function bits 2..0
* bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
* 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
* -------+-------+-------+-------+-------+-------+-------+-------+-------
* 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
* 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
* 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
* 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
* 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
* 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
* 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
* 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
*/
#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
enum {
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,
};
/*
* MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
*
* 31 26 10 6 5 0
* +--------+----------------------+--------+--------+
* | MMI | |function| MMI0 |
* +--------+----------------------+--------+--------+
*
* function bits 7..6
* bits | 0 | 1 | 2 | 3
* 10..8 | 00 | 01 | 10 | 11
* -------+-------+-------+-------+-------
* 0 000 | PADDW | PSUBW | PCGTW | PMAXW
* 1 001 | PADDH | PSUBH | PCGTH | PMAXH
* 2 010 | PADDB | PSUBB | PCGTB | *
* 3 011 | * | * | * | *
* 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
* 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
* 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
* 7 111 | * | * | PEXT5 | PPAC5
*/
#define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
enum {
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_