Index: lib/Target/Mips/Disassembler/MipsDisassembler.cpp =================================================================== --- lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -47,6 +47,8 @@ bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; } + bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; } + bool hasCOP3() const { // Only present in MIPS-I and MIPS-II return !hasMips32() && !hasMips3(); @@ -889,6 +891,16 @@ } } + if (hasCnMips()) { + DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n"); + Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn, + Address, this, STI); + if (Result != MCDisassembler::Fail) { + Size = 4; + return Result; + } + } + if (isGP64()) { DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n"); Result = decodeInstruction(DecoderTableMips6432, Instr, Insn, Index: lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64InstrInfo.td +++ lib/Target/Mips/Mips64InstrInfo.td @@ -305,8 +305,9 @@ def LONG_BRANCH_DADDiu : PseudoSE<(outs GPR64Opnd:$dst), (ins GPR64Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>; -// Cavium Octeon cmMIPS instructions -let EncodingPredicates = [], // FIXME: The lack of HasStdEnc is probably a bug +// Cavium Octeon cnMIPS instructions +let DecoderNamespace = "CnMips", + EncodingPredicates = [], // FIXME: The lack of HasStdEnc is probably a bug AdditionalPredicates = [HasCnMips] in { class Count1s: @@ -353,6 +354,10 @@ let Defs = [AT]; } +class MFC2OP : + InstSE<(outs RO:$rt, uimm16:$imm16), (ins), + !strconcat(asmstr, "\t$rt, $imm16"), [], NoItinerary, FrmFR>; + // Unsigned Byte Add let Pattern = [(set GPR64Opnd:$rd, (and (add GPR64Opnd:$rs, GPR64Opnd:$rt), 255))] in @@ -415,6 +420,9 @@ def VMULU : ArithLogicR<"vmulu", GPR64Opnd, 0, II_DMUL>, ADD_FM<0x1c, 0x0f>; +// Move between CPU and coprocessor registers +def DMFC2_OCTEON : MFC2OP<"dmfc2", GPR64Opnd>, MFC2OP_FM<0x12, 1>; +def DMTC2_OCTEON : MFC2OP<"dmtc2", GPR64Opnd>, MFC2OP_FM<0x12, 5>; } } Index: lib/Target/Mips/MipsInstrFormats.td =================================================================== --- lib/Target/Mips/MipsInstrFormats.td +++ lib/Target/Mips/MipsInstrFormats.td @@ -226,6 +226,18 @@ let Inst{2-0} = sel; } +class MFC2OP_FM op, bits<5> mfmt> : StdArch { + bits<5> rt; + bits<16> imm16; + + bits<32> Inst; + + let Inst{31-26} = op; + let Inst{25-21} = mfmt; + let Inst{20-16} = rt; + let Inst{15-0} = imm16; +} + class ADD_FM op, bits<6> funct> : StdArch { bits<5> rd; bits<5> rs; Index: test/MC/Mips/octeon-instructions.s =================================================================== --- test/MC/Mips/octeon-instructions.s +++ test/MC/Mips/octeon-instructions.s @@ -15,6 +15,8 @@ # CHECK: cins32 $22, $22, 9, 22 # encoding: [0x72,0xd6,0xb2,0x73] # CHECK: cins32 $24, $ra, 0, 31 # encoding: [0x73,0xf8,0xf8,0x33] # CHECK: cins32 $15, $15, 5, 5 # encoding: [0x71,0xef,0x29,0x73] +# CHECK: dmtc2 $2, 16455 # encoding: [0x,0x,0x40,0x47] +# CHECK: dmfc2 $2, 64 # encoding: [0x48,0x22,0x00,0x40] # CHECK: dmul $9, $6, $7 # encoding: [0x70,0xc7,0x48,0x03] # CHECK: dmul $19, $24, $25 # encoding: [0x73,0x19,0x98,0x03] # CHECK: dmul $9, $9, $6 # encoding: [0x71,0x26,0x48,0x03] @@ -72,6 +74,8 @@ cins32 $22, 9, 22 cins $24, $31, 32, 31 cins $15, 37, 5 + dmtc2 $2, 0x4047 + dmfc2 $2, 0x0040 dmul $9, $6, $7 dmul $19, $24, $25 dmul $9, $6