Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -479,6 +479,7 @@ bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; } bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; } + bool hasDSPR3() const { return STI.getFeatureBits()[Mips::FeatureDSPR3]; } bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; } bool hasCnMips() const { return (STI.getFeatureBits()[Mips::FeatureCnMips]); Index: lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -190,6 +190,10 @@ else NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips); + // Check whether it is Dsp instruction. + if (NewOpcode == -1) + NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp); + if (NewOpcode != -1) { if (Fixups.size() > N) Fixups.pop_back(); Index: lib/Target/Mips/MicroMipsDSPInstrFormats.td =================================================================== --- /dev/null +++ lib/Target/Mips/MicroMipsDSPInstrFormats.td @@ -0,0 +1,29 @@ +//===-- MicroMipsDSPInstrFormats.td - Micromips DSP Instruction Formats -*- +//tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +class MMDSPInst + : MipsInst<(outs), (ins), "", [], NoItinerary, FrmOther> { + let Predicates = [HasDSP]; + string BaseOpcode = opstr; + string Arch = "mmdsp"; + let DecoderNamespace = "MicroMips"; +} + +class POOL32A_3R_FMT op> : MMDSPInst { + bits<5> rd; + bits<5> rs; + bits<5> rt; + + let Inst{31-26} = 0b000000; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-11} = rd; + let Inst{10-0} = op; +} Index: lib/Target/Mips/MicroMipsDSPInstrInfo.td =================================================================== --- /dev/null +++ lib/Target/Mips/MicroMipsDSPInstrInfo.td @@ -0,0 +1,19 @@ +//===- MicroMipsDSPInstrInfo.td - Micromips DSP instructions -*- tablegen *-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file describes MicroMips DSP instructions. +// +//===----------------------------------------------------------------------===// + +// Instruction encoding. +class ADDU_QB_MM_ENC : POOL32A_3R_FMT<0b00011001101>; + +// Instruction defs. +// MIPS DSP Rev 1 +def ADDU_QB_MM : DspMMRel, ADDU_QB_MM_ENC, ADDU_QB_DESC; Index: lib/Target/Mips/Mips.td =================================================================== --- lib/Target/Mips/Mips.td +++ lib/Target/Mips/Mips.td @@ -154,6 +154,9 @@ def FeatureDSP : SubtargetFeature<"dsp", "HasDSP", "true", "Mips DSP ASE">; def FeatureDSPR2 : SubtargetFeature<"dspr2", "HasDSPR2", "true", "Mips DSP-R2 ASE", [FeatureDSP]>; +def FeatureDSPR3 + : SubtargetFeature<"dspr3", "HasDSPR3", "true", "Mips DSP-R3 ASE", + [ FeatureDSP, FeatureDSPR2 ]>; def FeatureMSA : SubtargetFeature<"msa", "HasMSA", "true", "Mips MSA ASE">; Index: lib/Target/Mips/MipsDSPInstrFormats.td =================================================================== --- lib/Target/Mips/MipsDSPInstrFormats.td +++ lib/Target/Mips/MipsDSPInstrFormats.td @@ -7,10 +7,26 @@ // //===----------------------------------------------------------------------===// +class DspMMRel; + +def Dsp2MicroMips : InstrMapping { + let FilterClass = "DspMMRel"; + // Instructions with the same BaseOpcode and isNVStore values form a row. + let RowFields = ["BaseOpcode"]; + // Instructions with the same predicate sense form a column. + let ColFields = ["Arch"]; + // The key column is the unpredicated instructions. + let KeyCol = ["dsp"]; + // Value columns are PredSense=true and PredSense=false + let ValueCols = [["dsp"], ["mmdsp"]]; +} + def HasDSP : Predicate<"Subtarget->hasDSP()">, AssemblerPredicate<"FeatureDSP">; def HasDSPR2 : Predicate<"Subtarget->hasDSPR2()">, AssemblerPredicate<"FeatureDSPR2">; +def HasDSPR3 : Predicate<"Subtarget->hasDSPR3()">, + AssemblerPredicate<"FeatureDSPR3">; // Fields. class Field6 val> { @@ -20,8 +36,11 @@ def SPECIAL3_OPCODE : Field6<0b011111>; def REGIMM_OPCODE : Field6<0b000001>; -class DSPInst : MipsInst<(outs), (ins), "", [], NoItinerary, FrmOther> { +class DSPInst + : MipsInst<(outs), (ins), "", [], NoItinerary, FrmOther> { let Predicates = [HasDSP]; + string BaseOpcode = opstr; + string Arch = "dsp"; } class PseudoDSP pattern, Index: lib/Target/Mips/MipsDSPInstrInfo.td =================================================================== --- lib/Target/Mips/MipsDSPInstrInfo.td +++ lib/Target/Mips/MipsDSPInstrInfo.td @@ -1072,7 +1072,7 @@ // Instruction defs. // MIPS DSP Rev 1 -def ADDU_QB : ADDU_QB_ENC, ADDU_QB_DESC; +def ADDU_QB : DspMMRel, ADDU_QB_ENC, ADDU_QB_DESC; def ADDU_S_QB : ADDU_S_QB_ENC, ADDU_S_QB_DESC; def SUBU_QB : SUBU_QB_ENC, SUBU_QB_DESC; def SUBU_S_QB : SUBU_S_QB_ENC, SUBU_S_QB_DESC; Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -2011,3 +2011,7 @@ // Micromips64 r6 include "MicroMips64r6InstrFormats.td" include "MicroMips64r6InstrInfo.td" + +// Micromips DSP +include "MicroMipsDSPInstrFormats.td" +include "MicroMipsDSPInstrInfo.td" Index: lib/Target/Mips/MipsSEISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsSEISelLowering.cpp +++ lib/Target/Mips/MipsSEISelLowering.cpp @@ -932,7 +932,8 @@ } } - if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget.hasDSPR2())) + if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || (!Subtarget.hasDSPR2() && + !Subtarget.hasDSPR3()))) return SDValue(); return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget); @@ -944,7 +945,8 @@ const MipsSubtarget &Subtarget) { EVT Ty = N->getValueType(0); - if (((Ty != MVT::v2i16) || !Subtarget.hasDSPR2()) && (Ty != MVT::v4i8)) + if (((Ty != MVT::v2i16) || (!Subtarget.hasDSPR2() && + !Subtarget.hasDSPR3())) && (Ty != MVT::v4i8)) return SDValue(); return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget); Index: lib/Target/Mips/MipsSubtarget.h =================================================================== --- lib/Target/Mips/MipsSubtarget.h +++ lib/Target/Mips/MipsSubtarget.h @@ -116,8 +116,8 @@ // InMicroMips -- can process MicroMips instructions bool InMicroMipsMode; - // HasDSP, HasDSPR2 -- supports DSP ASE. - bool HasDSP, HasDSPR2; + // HasDSP, HasDSPR2, HasDSPR3 -- supports DSP ASE. + bool HasDSP, HasDSPR2, HasDSPR3; // Allow mixed Mips16 and Mips32 in one source file bool AllowMixed16_32; @@ -234,6 +234,7 @@ bool inMicroMips64r6Mode() const { return InMicroMipsMode && hasMips64r6(); } bool hasDSP() const { return HasDSP; } bool hasDSPR2() const { return HasDSPR2; } + bool hasDSPR3() const { return HasDSPR3; } bool hasMSA() const { return HasMSA; } bool useSmallSection() const { return UseSmallSection; } Index: lib/Target/Mips/MipsSubtarget.cpp =================================================================== --- lib/Target/Mips/MipsSubtarget.cpp +++ lib/Target/Mips/MipsSubtarget.cpp @@ -69,8 +69,9 @@ HasMips3_32(false), HasMips3_32r2(false), HasMips4_32(false), HasMips4_32r2(false), HasMips5_32r2(false), InMips16Mode(false), InMips16HardFloat(Mips16HardFloat), InMicroMipsMode(false), HasDSP(false), - HasDSPR2(false), AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16), - HasMSA(false), UseTCCInDIV(false), TM(TM), TargetTriple(TT), TSInfo(), + HasDSPR2(false), HasDSPR3(false), AllowMixed16_32(Mixed16_32 | Mips_Os16), + Os16(Mips_Os16), HasMSA(false), UseTCCInDIV(false), TM(TM), + TargetTriple(TT), TSInfo(), InstrInfo( MipsInstrInfo::create(initializeSubtargetDependencies(CPU, FS, TM))), FrameLowering(MipsFrameLowering::create(*this)), Index: test/MC/Disassembler/Mips/micromips32r6_dsp.txt =================================================================== --- /dev/null +++ test/MC/Disassembler/Mips/micromips32r6_dsp.txt @@ -0,0 +1,4 @@ +# RUN: llvm-mc --disassemble %s -triple=mips-unknown-linux -mcpu=mips32r6 -mattr=micromips -mattr=+dsp | FileCheck %s + +0x00 0xa4 0x18 0xcd # CHECK: addu.qb $3, $4, $5 + Index: test/MC/Mips/micromips32r6/micromips-dsp-instructioins.s =================================================================== --- /dev/null +++ test/MC/Mips/micromips32r6/micromips-dsp-instructioins.s @@ -0,0 +1,5 @@ +# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r6 -mattr=micromips -mattr=+dsp | FileCheck %s + + .set noat + addu.qb $3, $4, $5 # CHECK: addu.qb $3, $4, $5 # encoding: [0x00,0xa4,0x18,0xcd] +