Index: lib/Target/Mips/MicroMipsDSPInstrFormats.td =================================================================== --- lib/Target/Mips/MicroMipsDSPInstrFormats.td +++ lib/Target/Mips/MicroMipsDSPInstrFormats.td @@ -10,12 +10,13 @@ class MMDSPInst : MipsInst<(outs), (ins), "", [], NoItinerary, FrmOther>, PredicateControl { let InsnPredicates = [HasDSP]; + let AdditionalPredicates = [InMicroMips]; string BaseOpcode = opstr; string Arch = "mmdsp"; let DecoderNamespace = "MicroMips"; } -class POOL32A_3R_FMT op> : MMDSPInst { +class POOL32A_3R_FMT op> : MMDSPInst { bits<5> rd; bits<5> rs; bits<5> rt; @@ -26,3 +27,27 @@ let Inst{15-11} = rd; let Inst{10-0} = op; } + +class POOL32A_2R_FMT op> : MMDSPInst { + bits<5> rt; + bits<5> rs; + + let Inst{31-26} = 0b000000; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-6} = op; + let Inst{5-0} = 0b111100; +} + +class POOL32A_2RAC_FMT op> : MMDSPInst { + bits<5> rt; + bits<5> rs; + bits<2> ac; + + let Inst{31-26} = 0b000000; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-14} = ac; + let Inst{13-6} = op; + let Inst{5-0} = 0b111100; +} Index: lib/Target/Mips/MicroMipsDSPInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsDSPInstrInfo.td +++ lib/Target/Mips/MicroMipsDSPInstrInfo.td @@ -12,8 +12,46 @@ //===----------------------------------------------------------------------===// // Instruction encoding. -class ADDU_QB_MM_ENC : POOL32A_3R_FMT<0b00011001101>; +class ADDU_QB_MM_ENC : POOL32A_3R_FMT<"addu.qb", 0b00011001101>; +class ABSQ_S_PH_MM_ENC : POOL32A_2R_FMT<"absq_s.ph", 0b0001000100>; +class ABSQ_S_W_MM_ENC : POOL32A_2R_FMT<"absq_s.w", 0b0010000100>; +class ABSQ_S_QB_MMR2_ENC : POOL32A_2R_FMT<"absq_s.qb", 0b0000000100>; +class INSV_MM_ENC : POOL32A_2R_FMT<"insv", 0b0100000100>; +class MADD_DSP_MM_ENC : POOL32A_2RAC_FMT<"madd", 0b00101010>; +class MADDU_DSP_MM_ENC : POOL32A_2RAC_FMT<"maddu", 0b01101010>; +class MSUB_DSP_MM_ENC : POOL32A_2RAC_FMT<"msub", 0b10101010>; +class MSUBU_DSP_MM_ENC : POOL32A_2RAC_FMT<"msubu", 0b11101010>; +class MULT_DSP_MM_ENC : POOL32A_2RAC_FMT<"mult", 0b00110010>; +class MULTU_DSP_MM_ENC : POOL32A_2RAC_FMT<"multu", 0b01110010>; // Instruction defs. -// MIPS DSP Rev 1 -def ADDU_QB_MM : DspMMRel, ADDU_QB_MM_ENC, ADDU_QB_DESC, ISA_MICROMIPS; +class ABSQ_S_PH_MM_R2_DESC_BASE { + dag OutOperandList = (outs ROD:$rt); + dag InOperandList = (ins ROS:$rs); + string AsmString = !strconcat(opstr, "\t$rt, $rs"); + list Pattern = [(set ROD:$rt, (OpNode ROS:$rs))]; + InstrItinClass Itinerary = itin; +} +class ABSQ_S_PH_MM_DESC : ABSQ_S_PH_MM_R2_DESC_BASE< + "absq_s.ph", int_mips_absq_s_ph, NoItinerary, DSPROpnd>, Defs<[DSPOutFlag20]>; +class ABSQ_S_W_MM_DESC : ABSQ_S_PH_MM_R2_DESC_BASE< + "absq_s.w", int_mips_absq_s_w, NoItinerary, GPR32Opnd>, Defs<[DSPOutFlag20]>; +class ABSQ_S_QB_MMR2_DESC : ABSQ_S_PH_MM_R2_DESC_BASE< + "absq_s.qb", int_mips_absq_s_qb, NoItinerary, DSPROpnd>, Defs<[DSPOutFlag20]>; + +// microMIPS DSP Rev 1 +def ADDU_QB_MM : DspMMRel, ADDU_QB_MM_ENC, ADDU_QB_DESC; +def ABSQ_S_PH_MM : DspMMRel, ABSQ_S_PH_MM_ENC, ABSQ_S_PH_MM_DESC; +def ABSQ_S_W_MM : DspMMRel, ABSQ_S_W_MM_ENC, ABSQ_S_W_MM_DESC; +def INSV_MM : DspMMRel, INSV_MM_ENC, INSV_DESC; +def MADD_DSP_MM : DspMMRel, MADD_DSP_MM_ENC, MADD_DSP_DESC; +def MADDU_DSP_MM : DspMMRel, MADDU_DSP_MM_ENC, MADDU_DSP_DESC; +def MSUB_DSP_MM : DspMMRel, MSUB_DSP_MM_ENC, MSUB_DSP_DESC; +def MSUBU_DSP_MM : DspMMRel, MSUBU_DSP_MM_ENC, MSUBU_DSP_DESC; +def MULT_DSP_MM : DspMMRel, MULT_DSP_MM_ENC, MULT_DSP_DESC; +def MULTU_DSP_MM : DspMMRel, MULTU_DSP_MM_ENC, MULTU_DSP_DESC; +// microMIPS DSP Rev 2 +def ABSQ_S_QB_MMR2 : DspMMRel, ABSQ_S_QB_MMR2_ENC, ABSQ_S_QB_MMR2_DESC, + ISA_DSPR2; Index: lib/Target/Mips/MipsDSPInstrFormats.td =================================================================== --- lib/Target/Mips/MipsDSPInstrFormats.td +++ lib/Target/Mips/MipsDSPInstrFormats.td @@ -28,6 +28,10 @@ def HasDSPR3 : Predicate<"Subtarget->hasDSPR3()">, AssemblerPredicate<"FeatureDSPR3">; +class ISA_DSPR2 { + list InsnPredicates = [HasDSPR2]; +} + // Fields. class Field6 val> { bits<6> V = val; Index: lib/Target/Mips/MipsDSPInstrInfo.td =================================================================== --- lib/Target/Mips/MipsDSPInstrInfo.td +++ lib/Target/Mips/MipsDSPInstrInfo.td @@ -314,6 +314,7 @@ string AsmString = !strconcat(instr_asm, "\t$rd, $rt"); list Pattern = [(set ROD:$rd, (OpNode ROT:$rt))]; InstrItinClass Itinerary = itin; + string BaseOpcode = instr_asm; } class REPL_DESC_BASE Pattern = [(set ACC64DSPOpnd:$ac, (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt))]; InstrItinClass Itinerary = itin; bit isCommutable = 1; + string BaseOpcode = instr_asm; } class MADD_DESC_BASE Pattern = [(set GPR32Opnd:$rt, (OpNode GPR32Opnd:$src, GPR32Opnd:$rs))]; InstrItinClass Itinerary = itin; string Constraints = "$src = $rt"; + string BaseOpcode = instr_asm; } //===----------------------------------------------------------------------===// @@ -1086,8 +1090,8 @@ def ADDWC : ADDWC_ENC, ADDWC_DESC; def MODSUB : MODSUB_ENC, MODSUB_DESC; def RADDU_W_QB : RADDU_W_QB_ENC, RADDU_W_QB_DESC; -def ABSQ_S_PH : ABSQ_S_PH_ENC, ABSQ_S_PH_DESC; -def ABSQ_S_W : ABSQ_S_W_ENC, ABSQ_S_W_DESC; +def ABSQ_S_PH : DspMMRel, ABSQ_S_PH_ENC, ABSQ_S_PH_DESC; +def ABSQ_S_W : DspMMRel, ABSQ_S_W_ENC, ABSQ_S_W_DESC; def PRECRQ_QB_PH : PRECRQ_QB_PH_ENC, PRECRQ_QB_PH_DESC; def PRECRQ_PH_W : PRECRQ_PH_W_ENC, PRECRQ_PH_W_DESC; def PRECRQ_RS_PH_W : PRECRQ_RS_PH_W_ENC, PRECRQ_RS_PH_W_DESC; @@ -1140,12 +1144,12 @@ def DPSQ_S_W_PH : DPSQ_S_W_PH_ENC, DPSQ_S_W_PH_DESC; def DPAQ_SA_L_W : DPAQ_SA_L_W_ENC, DPAQ_SA_L_W_DESC; def DPSQ_SA_L_W : DPSQ_SA_L_W_ENC, DPSQ_SA_L_W_DESC; -def MULT_DSP : MULT_DSP_ENC, MULT_DSP_DESC; -def MULTU_DSP : MULTU_DSP_ENC, MULTU_DSP_DESC; -def MADD_DSP : MADD_DSP_ENC, MADD_DSP_DESC; -def MADDU_DSP : MADDU_DSP_ENC, MADDU_DSP_DESC; -def MSUB_DSP : MSUB_DSP_ENC, MSUB_DSP_DESC; -def MSUBU_DSP : MSUBU_DSP_ENC, MSUBU_DSP_DESC; +def MULT_DSP : DspMMRel, MULT_DSP_ENC, MULT_DSP_DESC; +def MULTU_DSP : DspMMRel, MULTU_DSP_ENC, MULTU_DSP_DESC; +def MADD_DSP : DspMMRel, MADD_DSP_ENC, MADD_DSP_DESC; +def MADDU_DSP : DspMMRel, MADDU_DSP_ENC, MADDU_DSP_DESC; +def MSUB_DSP : DspMMRel, MSUB_DSP_ENC, MSUB_DSP_DESC; +def MSUBU_DSP : DspMMRel, MSUBU_DSP_ENC, MSUBU_DSP_DESC; def CMPU_EQ_QB : CMPU_EQ_QB_ENC, CMPU_EQ_QB_DESC; def CMPU_LT_QB : CMPU_LT_QB_ENC, CMPU_LT_QB_DESC; def CMPU_LE_QB : CMPU_LE_QB_ENC, CMPU_LE_QB_DESC; @@ -1167,7 +1171,7 @@ def LHX : LHX_ENC, LHX_DESC; def LBUX : LBUX_ENC, LBUX_DESC; def BPOSGE32 : BPOSGE32_ENC, BPOSGE32_DESC; -def INSV : INSV_ENC, INSV_DESC; +def INSV : DspMMRel, INSV_ENC, INSV_DESC; def EXTP : EXTP_ENC, EXTP_DESC; def EXTPV : EXTPV_ENC, EXTPV_DESC; def EXTPDP : EXTPDP_ENC, EXTPDP_DESC; @@ -1196,7 +1200,7 @@ def CMPGDU_EQ_QB : CMPGDU_EQ_QB_ENC, CMPGDU_EQ_QB_DESC; def CMPGDU_LT_QB : CMPGDU_LT_QB_ENC, CMPGDU_LT_QB_DESC; def CMPGDU_LE_QB : CMPGDU_LE_QB_ENC, CMPGDU_LE_QB_DESC; -def ABSQ_S_QB : ABSQ_S_QB_ENC, ABSQ_S_QB_DESC; +def ABSQ_S_QB : DspMMRel, ABSQ_S_QB_ENC, ABSQ_S_QB_DESC; def ADDUH_QB : ADDUH_QB_ENC, ADDUH_QB_DESC; def ADDUH_R_QB : ADDUH_R_QB_ENC, ADDUH_R_QB_DESC; def SUBUH_QB : SUBUH_QB_ENC, SUBUH_QB_DESC; Index: test/MC/Disassembler/Mips/micromips-dsp/valid.txt =================================================================== --- test/MC/Disassembler/Mips/micromips-dsp/valid.txt +++ test/MC/Disassembler/Mips/micromips-dsp/valid.txt @@ -1,4 +1,12 @@ # 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 - +0x00 0x64 0x11 0x3c # CHECK: absq_s.ph $3, $4 +0x00 0x64 0x21 0x3c # CHECK: absq_s.w $3, $4 +0x00 0x64 0x41 0x3c # CHECK: insv $3, $4 +0x00 0xe6 0x4a 0xbc # CHECK: madd $ac1, $6, $7 +0x01 0x28 0x1a 0xbc # CHECK: maddu $ac0, $8, $9 +0x01 0x6a 0xea 0xbc # CHECK: msub $ac3, $10, $11 +0x01 0xac 0xba 0xbc # CHECK: msubu $ac2, $12, $13 +0x00 0x62 0xcc 0xbc # CHECK: mult $ac3, $2, $3 +0x00 0xa4 0x9c 0xbc # CHECK: multu $ac2, $4, $5 Index: test/MC/Disassembler/Mips/micromips-dspr2/valid.txt =================================================================== --- /dev/null +++ test/MC/Disassembler/Mips/micromips-dspr2/valid.txt @@ -0,0 +1,3 @@ +# RUN: llvm-mc --disassemble %s -triple=mips-unknown-linux -mcpu=mips32r6 -mattr=micromips -mattr=+dspr2 | FileCheck %s + +0x00 0x64 0x01 0x3c # CHECK: absq_s.qb $3, $4 Index: test/MC/Mips/micromips-dsp/valid.s =================================================================== --- test/MC/Mips/micromips-dsp/valid.s +++ test/MC/Mips/micromips-dsp/valid.s @@ -2,4 +2,13 @@ .set noat addu.qb $3, $4, $5 # CHECK: addu.qb $3, $4, $5 # encoding: [0x00,0xa4,0x18,0xcd] + absq_s.ph $3, $4 # CHECK: absq_s.ph $3, $4 # encoding: [0x00,0x64,0x11,0x3c] + absq_s.w $3, $4 # CHECK: absq_s.w $3, $4 # encoding: [0x00,0x64,0x21,0x3c] + insv $3, $4 # CHECK: insv $3, $4 # encoding: [0x00,0x64,0x41,0x3c] + madd $ac1, $6, $7 # CHECK: madd $ac1, $6, $7 # encoding: [0x00,0xe6,0x4a,0xbc] + maddu $ac0, $8, $9 # CHECK: maddu $ac0, $8, $9 # encoding: [0x01,0x28,0x1a,0xbc] + msub $ac3, $10, $11 # CHECK: msub $ac3, $10, $11 # encoding: [0x01,0x6a,0xea,0xbc] + msubu $ac2, $12, $13 # CHECK: msubu $ac2, $12, $13 # encoding: [0x01,0xac,0xba,0xbc] + mult $ac3, $2, $3 # CHECK: mult $ac3, $2, $3 # encoding: [0x00,0x62,0xcc,0xbc] + multu $ac2, $4, $5 # CHECK: multu $ac2, $4, $5 # encoding: [0x00,0xa4,0x9c,0xbc] Index: test/MC/Mips/micromips-dspr2/valid.s =================================================================== --- /dev/null +++ test/MC/Mips/micromips-dspr2/valid.s @@ -0,0 +1,4 @@ +# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r6 -mattr=micromips -mattr=+dspr2 | FileCheck %s + + .set noat + absq_s.qb $3, $4 # CHECK: absq_s.qb $3, $4 # encoding: [0x00,0x64,0x01,0x3c]