diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td index d1c2079f06a2..02c8a06b79fd 100644 --- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -1335,11 +1335,12 @@ class TLBINV_MMR6_DESC : TLBINV_MMR6_DESC_BASE<"tlbinv", II_TLBINV>; class TLBINVF_MMR6_DESC : TLBINV_MMR6_DESC_BASE<"tlbinvf", II_TLBINVF>; class DVPEVP_MMR6_DESC_BASE { - dag OutOperandList = (outs); - dag InOperandList = (ins GPR32Opnd:$rs); + dag OutOperandList = (outs GPR32Opnd:$rs); + dag InOperandList = (ins); string AsmString = !strconcat(opstr, "\t$rs"); list Pattern = []; InstrItinClass Itinerary = Itin; + bit hasUnModeledSideEffects = 1; } class DVP_MMR6_DESC : DVPEVP_MMR6_DESC_BASE<"dvp", II_DVP>; diff --git a/llvm/lib/Target/Mips/Mips32r6InstrFormats.td b/llvm/lib/Target/Mips/Mips32r6InstrFormats.td index a20c683c1e5e..516caa34fbf2 100644 --- a/llvm/lib/Target/Mips/Mips32r6InstrFormats.td +++ b/llvm/lib/Target/Mips/Mips32r6InstrFormats.td @@ -45,6 +45,7 @@ class MipsR6Inst : MipsInst<(outs), (ins), "", [], NoItinerary, FrmOther>, class OPGROUP Val> { bits<6> Value = Val; } +def OPGROUP_COP0 : OPGROUP<0b010000>; def OPGROUP_COP1 : OPGROUP<0b010001>; def OPGROUP_COP2 : OPGROUP<0b010010>; def OPGROUP_ADDI : OPGROUP<0b001000>; @@ -201,6 +202,21 @@ class BAL_FM : MipsR6Inst { let Inst{15-0} = offset; } +class COP0_EVP_DVP_FM sc> : MipsR6Inst { + bits<5> rt; + + bits<32> Inst; + + let Inst{31-26} = OPGROUP_COP0.Value; + let Inst{25-21} = 0b01011; + let Inst{20-16} = rt; + let Inst{15-11} = 0b00000; + let Inst{10-6} = 0b00000; + let Inst{5} = sc; + let Inst{4-3} = 0b00; + let Inst{2-0} = 0b100; +} + class COP1_2R_FM funct, FIELD_FMT Format> : MipsR6Inst { bits<5> fs; bits<5> fd; diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td index e81869513b6e..7f0e254602c9 100644 --- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td @@ -98,6 +98,9 @@ class BC1NEZ_ENC : COP1_BCCZ_FM; class BC2EQZ_ENC : COP2_BCCZ_FM; class BC2NEZ_ENC : COP2_BCCZ_FM; +class DVP_ENC : COP0_EVP_DVP_FM<0b1>; +class EVP_ENC : COP0_EVP_DVP_FM<0b0>; + class JIALC_ENC : JMP_IDX_COMPACT_FM<0b111110>; class JIC_ENC : JMP_IDX_COMPACT_FM<0b110110>; class JR_HB_R6_ENC : JR_HB_R6_FM; @@ -506,6 +509,19 @@ class DIVMOD_DESC_BASE + : MipsR6Arch { + dag OutOperandList = (outs GPR32Opnd:$rt); + dag InOperandList = (ins); + string AsmString = !strconcat(instr_asm, "\t$rt"); + list Pattern = []; + InstrItinClass Itinerary = Itin; + bit hasUnModeledSideEffects = 1; +} + +class DVP_DESC : DVPEVP_DESC_BASE<"dvp", II_DVP>; +class EVP_DESC : DVPEVP_DESC_BASE<"evp", II_EVP>; + class DIV_DESC : DIVMOD_DESC_BASE<"div", GPR32Opnd, II_DIV, sdiv>; class DIVU_DESC : DIVMOD_DESC_BASE<"divu", GPR32Opnd, II_DIVU, udiv>; class MOD_DESC : DIVMOD_DESC_BASE<"mod", GPR32Opnd, II_MOD, srem>; @@ -819,6 +835,10 @@ let AdditionalPredicates = [NotInMicroMips] in { def DIV : R6MMR6Rel, DIV_ENC, DIV_DESC, ISA_MIPS32R6; def DIVU : R6MMR6Rel, DIVU_ENC, DIVU_DESC, ISA_MIPS32R6; } + +def DVP : R6MMR6Rel, DVP_ENC, DVP_DESC, ISA_MIPS32R6; +def EVP : R6MMR6Rel, EVP_ENC, EVP_DESC, ISA_MIPS32R6; + def JIALC : R6MMR6Rel, JIALC_ENC, JIALC_DESC, ISA_MIPS32R6; def JIC : R6MMR6Rel, JIC_ENC, JIC_DESC, ISA_MIPS32R6; def JR_HB_R6 : JR_HB_R6_ENC, JR_HB_R6_DESC, ISA_MIPS32R6; @@ -884,6 +904,9 @@ let AdditionalPredicates = [NotInMicroMips] in { // //===----------------------------------------------------------------------===// +def : MipsInstAlias<"dvp", (DVP ZERO), 0>, ISA_MIPS32R6; +def : MipsInstAlias<"evp", (EVP ZERO), 0>, ISA_MIPS32R6; + let AdditionalPredicates = [NotInMicroMips] in { def : MipsInstAlias<"sdbbp", (SDBBP_R6 0)>, ISA_MIPS32R6; def : MipsInstAlias<"jr $rs", (JALR ZERO, GPR32Opnd:$rs), 1>, ISA_MIPS32R6, GPR_32; diff --git a/llvm/lib/Target/Mips/MipsEVAInstrFormats.td b/llvm/lib/Target/Mips/MipsEVAInstrFormats.td index 11e191ad6d82..8c3024810d27 100644 --- a/llvm/lib/Target/Mips/MipsEVAInstrFormats.td +++ b/llvm/lib/Target/Mips/MipsEVAInstrFormats.td @@ -50,7 +50,7 @@ def OPCODE6_TLBINVF : OPCODE6<0b000100>; def OPCODE6_CACHEE : OPCODE6<0b011011>; def OPCODE6_PREFE : OPCODE6<0b100011>; -def OPGROUP_COP0 : OPGROUP<0b010000>; +def OPGROUP_COP0_TLB : OPGROUP<0b010000>; //===----------------------------------------------------------------------===// // @@ -77,7 +77,7 @@ class SPECIAL3_EVA_LOAD_STORE_FM : MipsEVAInst { class TLB_FM : MipsEVAInst { bits<32> Inst; - let Inst{31-26} = OPGROUP_COP0.Value; + let Inst{31-26} = OPGROUP_COP0_TLB.Value; let Inst{25} = 1; // CO let Inst{24-6} = 0; let Inst{5-0} = Operation.Value; diff --git a/llvm/test/MC/Disassembler/Mips/micromips32r6/valid.txt b/llvm/test/MC/Disassembler/Mips/micromips32r6/valid.txt index b84b16045db0..150d17deaf92 100644 --- a/llvm/test/MC/Disassembler/Mips/micromips32r6/valid.txt +++ b/llvm/test/MC/Disassembler/Mips/micromips32r6/valid.txt @@ -65,11 +65,15 @@ 0x00 0x00 0xe3 0x7c # CHECK: deret 0x00 0xa4 0x19 0x18 # CHECK: div $3, $4, $5 0x00 0xa4 0x19 0x98 # CHECK: divu $3, $4, $5 +0x00 0x11 0x19 0x7c # CHECK: dvp $17 +0x00 0x00 0x19 0x7c # CHECK: dvp $zero 0x00 0x00 0x18 0x00 # CHECK: ehb 0x00 0x00 0x57 0x7c # CHECK: ei 0x00 0x0a 0x57 0x7c # CHECK: ei $10 0x00 0x00 0xf3 0x7c # CHECK: eret 0x00 0x01 0xf3 0x7c # CHECK: eretnc +0x00 0x10 0x39 0x7c # CHECK: evp $16 +0x00 0x00 0x39 0x7c # CHECK: evp $zero 0x80 0x05 0x01 0x00 # CHECK: jialc $5, 256 0xa0 0x05 0x01 0x00 # CHECK: jic $5, 256 0x3c 0x44 0x00 0x08 # CHECK: lh $2, 8($4) diff --git a/llvm/test/MC/Disassembler/Mips/micromips64r6/valid.txt b/llvm/test/MC/Disassembler/Mips/micromips64r6/valid.txt index d29133045f21..75eb4833ae73 100644 --- a/llvm/test/MC/Disassembler/Mips/micromips64r6/valid.txt +++ b/llvm/test/MC/Disassembler/Mips/micromips64r6/valid.txt @@ -183,6 +183,10 @@ 0x00 0x00 0xe3 0x7c # CHECK: deret 0x00 0x00 0x47 0x7c # CHECK: di 0x00 0x0f 0x47 0x7c # CHECK: di $15 +0x00 0x11 0x19 0x7c # CHECK: dvp $17 +0x00 0x00 0x19 0x7c # CHECK: dvp $zero +0x00 0x10 0x39 0x7c # CHECK: evp $16 +0x00 0x00 0x39 0x7c # CHECK: evp $zero 0x00 0x00 0x43 0x7c # CHECK: tlbinv 0x00 0x00 0x53 0x7c # CHECK: tlbinvf 0x58 0x82 0x20 0x34 # CHECK: dinsu $4, $2, 32, 5 diff --git a/llvm/test/MC/Disassembler/Mips/mips32r6/valid-mips32r6-el.txt b/llvm/test/MC/Disassembler/Mips/mips32r6/valid-mips32r6-el.txt index 271ff904f172..d21317e00dd6 100644 --- a/llvm/test/MC/Disassembler/Mips/mips32r6/valid-mips32r6-el.txt +++ b/llvm/test/MC/Disassembler/Mips/mips32r6/valid-mips32r6-el.txt @@ -89,10 +89,14 @@ 0x8f 0x18 0xa4 0x46 # CHECK: cmp.sule.d $f2, $f3, $f4 0x00 0x60 0x7e 0x41 # CHECK: di $fp 0x00 0x60 0x60 0x41 # CHECK: di +0x24 0x00 0x71 0x41 # CHECK: dvp $17 +0x24 0x00 0x60 0x41 # CHECK: dvp $zero 0x9a 0x10 0x64 0x00 # CHECK: div $2, $3, $4 0x9b 0x10 0x64 0x00 # CHECK: divu $2, $3, $4 0x20 0x60 0x6e 0x41 # CHECK: ei $14 0x20 0x60 0x60 0x41 # CHECK: ei +0x04 0x00 0x70 0x41 # CHECK: evp $16 +0x04 0x00 0x60 0x41 # CHECK: evp $zero 0xc5 0x10 0x64 0x00 # CHECK: lsa $2, $3, $4, 4 0x43 0x00 0x48 0xec # CHECK: lwpc $2, 268 0x43 0x00 0x50 0xec # CHECK: lwupc $2, 268 diff --git a/llvm/test/MC/Disassembler/Mips/mips32r6/valid-mips32r6.txt b/llvm/test/MC/Disassembler/Mips/mips32r6/valid-mips32r6.txt index b796f48d566f..1b8cd1119744 100644 --- a/llvm/test/MC/Disassembler/Mips/mips32r6/valid-mips32r6.txt +++ b/llvm/test/MC/Disassembler/Mips/mips32r6/valid-mips32r6.txt @@ -66,7 +66,11 @@ 0x40 0x89 0x78 0x01 # CHECK: mtc0 $9, $15, 1 0x41 0x60 0x60 0x00 # CHECK: di 0x41 0x60 0x60 0x20 # CHECK: ei +0x41 0x60 0x00 0x24 # CHECK: dvp $zero +0x41 0x60 0x00 0x04 # CHECK: evp $zero 0x41 0x6e 0x60 0x20 # CHECK: ei $14 +0x41 0x70 0x00 0x04 # CHECK: evp $16 +0x41 0x71 0x00 0x24 # CHECK: dvp $17 0x41 0x7e 0x60 0x00 # CHECK: di $fp # FIXME: The encode/decode functions are not inverses of each other. # The immediate should be 4 but the disassembler currently emits 8 diff --git a/llvm/test/MC/Disassembler/Mips/mips64r6/valid-mips64r6-el.txt b/llvm/test/MC/Disassembler/Mips/mips64r6/valid-mips64r6-el.txt index 15821640ff39..776cfb85542e 100644 --- a/llvm/test/MC/Disassembler/Mips/mips64r6/valid-mips64r6-el.txt +++ b/llvm/test/MC/Disassembler/Mips/mips64r6/valid-mips64r6-el.txt @@ -115,8 +115,12 @@ 0xdd 0x10 0x64 0x00 # CHECK: dmuhu $2, $3, $4 0x9c 0x10 0x64 0x00 # CHECK: dmul $2, $3, $4 0x9d 0x10 0x64 0x00 # CHECK: dmulu $2, $3, $4 +0x24 0x00 0x71 0x41 # CHECK: dvp $17 +0x24 0x00 0x60 0x41 # CHECK: dvp $zero 0x20 0x60 0x60 0x41 # CHECK: ei 0x20 0x60 0x6e 0x41 # CHECK: ei $14 +0x04 0x00 0x70 0x41 # CHECK: evp $16 +0x04 0x00 0x60 0x41 # CHECK: evp $zero 0x09 0xfc 0x80 0x00 # CHECK: jalr.hb $4 0x09 0x24 0xa0 0x00 # CHECK: jalr.hb $4, $5 0x00 0x00 0x19 0xf8 # CHECK: jalrc $25 diff --git a/llvm/test/MC/Disassembler/Mips/mips64r6/valid-mips64r6.txt b/llvm/test/MC/Disassembler/Mips/mips64r6/valid-mips64r6.txt index 066c3d4a2739..29f82a846cbc 100644 --- a/llvm/test/MC/Disassembler/Mips/mips64r6/valid-mips64r6.txt +++ b/llvm/test/MC/Disassembler/Mips/mips64r6/valid-mips64r6.txt @@ -83,9 +83,13 @@ 0x40 0x38 0x50 0x00 # CHECK: dmfc0 $24, $10, 0 0x40 0x89 0x78 0x01 # CHECK: mtc0 $9, $15, 1 0x40 0xa4 0x50 0x00 # CHECK: dmtc0 $4, $10, 0 +0x41 0x60 0x00 0x24 # CHECK: dvp $zero +0x41 0x60 0x00 0x04 # CHECK: evp $zero 0x41 0x60 0x60 0x00 # CHECK: di 0x41 0x60 0x60 0x20 # CHECK: ei 0x41 0x6e 0x60 0x20 # CHECK: ei $14 +0x41 0x70 0x00 0x04 # CHECK: evp $16 +0x41 0x71 0x00 0x24 # CHECK: dvp $17 0x41 0x7e 0x60 0x00 # CHECK: di $fp # FIXME: The encode/decode functions are not inverses of each other. # The immediate should be 4 but the disassembler currently emits 8 diff --git a/llvm/test/MC/Mips/mips32r6/invalid.s b/llvm/test/MC/Mips/mips32r6/invalid.s index 287a99f2a8fe..4866d433e200 100644 --- a/llvm/test/MC/Mips/mips32r6/invalid.s +++ b/llvm/test/MC/Mips/mips32r6/invalid.s @@ -113,6 +113,12 @@ local_label: bnezc $2, 4194303 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: branch to misaligned address cache -1, 255($7) # CHECK: :[[@LINE]]:15: error: expected 5-bit unsigned immediate cache 32, 255($7) # CHECK: :[[@LINE]]:15: error: expected 5-bit unsigned immediate + dvp $17, $3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + dvp $17, 3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + dvp 3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + evp $16, $3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + evp $16, 3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + evp 3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction jalr.hb $31 # CHECK: :[[@LINE]]:9: error: source and destination must be different jalr.hb $31, $31 # CHECK: :[[@LINE]]:9: error: source and destination must be different ldc2 $20, -1025($s2) # CHECK: :[[@LINE]]:9: error: instruction requires a CPU feature not currently enabled diff --git a/llvm/test/MC/Mips/mips32r6/valid.s b/llvm/test/MC/Mips/mips32r6/valid.s index bb4c7c577f1e..0896131d5eae 100644 --- a/llvm/test/MC/Mips/mips32r6/valid.s +++ b/llvm/test/MC/Mips/mips32r6/valid.s @@ -101,10 +101,14 @@ a: di # CHECK: di # encoding: [0x41,0x60,0x60,0x00] div $2,$3,$4 # CHECK: div $2, $3, $4 # encoding: [0x00,0x64,0x10,0x9a] divu $2,$3,$4 # CHECK: divu $2, $3, $4 # encoding: [0x00,0x64,0x10,0x9b] + dvp $4 # CHECK: dvp $4 # encoding: [0x41,0x64,0x00,0x24] + dvp # CHECK: dvp $zero # encoding: [0x41,0x60,0x00,0x24] ei $14 # CHECK: ei $14 # encoding: [0x41,0x6e,0x60,0x20] ei # CHECK: ei # encoding: [0x41,0x60,0x60,0x20] eret eretnc # CHECK: eretnc # encoding: [0x42,0x00,0x00,0x58] + evp $5 # CHECK: evp $5 # encoding: [0x41,0x65,0x00,0x04] + evp # CHECK: evp $zero # encoding: [0x41,0x60,0x00,0x04] jialc $5, 256 # CHECK: jialc $5, 256 # encoding: [0xf8,0x05,0x01,0x00] jic $5, 256 # CHECK: jic $5, 256 # encoding: [0xd8,0x05,0x01,0x00] l.s $f2, 8($3) # CHECK: lwc1 $f2, 8($3) # encoding: [0xc4,0x62,0x00,0x08] diff --git a/llvm/test/MC/Mips/mips64r6/invalid.s b/llvm/test/MC/Mips/mips64r6/invalid.s index 1fdcca9f4409..636b2ddbff93 100644 --- a/llvm/test/MC/Mips/mips64r6/invalid.s +++ b/llvm/test/MC/Mips/mips64r6/invalid.s @@ -116,6 +116,12 @@ local_label: dlsa $2, $3, $4, 5 # CHECK: :[[@LINE]]:29: error: expected immediate in range 1 .. 4 drotr32 $2, $3, -1 # CHECK: :[[@LINE]]:25: error: expected 5-bit unsigned immediate drotr32 $2, $3, 32 # CHECK: :[[@LINE]]:25: error: expected 5-bit unsigned immediate + dvp $17, $3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + dvp $17, 3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + dvp 3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + evp $16, $3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + evp $16, 3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + evp 3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction jalr.hb $31 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: source and destination must be different jalr.hb $31, $31 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: source and destination must be different lsa $2, $3, $4, 0 # CHECK: :[[@LINE]]:29: error: expected immediate in range 1 .. 4 diff --git a/llvm/test/MC/Mips/mips64r6/valid.s b/llvm/test/MC/Mips/mips64r6/valid.s index 7ad4dc3c3d21..15c8da150a0d 100644 --- a/llvm/test/MC/Mips/mips64r6/valid.s +++ b/llvm/test/MC/Mips/mips64r6/valid.s @@ -130,9 +130,13 @@ a: dnegu $2,$3 # CHECK: dnegu $2, $3 # encoding: [0x00,0x03,0x10,0x2f] dsubu $14,-4586 # CHECK: daddiu $14, $14, 4586 # encoding: [0x65,0xce,0x11,0xea] dsubu $15,$11,5025 # CHECK: daddiu $15, $11, -5025 # encoding: [0x65,0x6f,0xec,0x5f] + dvp $4 # CHECK: dvp $4 # encoding: [0x41,0x64,0x00,0x24] + dvp # CHECK: dvp $zero # encoding: [0x41,0x60,0x00,0x24] ei # CHECK: ei # encoding: [0x41,0x60,0x60,0x20] ei $14 # CHECK: ei $14 # encoding: [0x41,0x6e,0x60,0x20] eretnc # CHECK: eretnc # encoding: [0x42,0x00,0x00,0x58] + evp $5 # CHECK: evp $5 # encoding: [0x41,0x65,0x00,0x04] + evp # CHECK: evp $zero # encoding: [0x41,0x60,0x00,0x04] j 1f # CHECK: j $tmp0 # encoding: [0b000010AA,A,A,A] # CHECK: # fixup A - offset: 0, value: ($tmp0), kind: fixup_Mips_26 j a # CHECK: j a # encoding: [0b000010AA,A,A,A]