Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1528,6 +1528,12 @@ if (Imm < -1 || Imm > 14) return Error(IDLoc, "immediate operand value out of range"); break; + case Mips::TEQ_MMR6: + case Mips::TGE_MMR6: + case Mips::TGEU_MMR6: + case Mips::TLT_MMR6: + case Mips::TLTU_MMR6: + case Mips::TNE_MMR6: case Mips::SB16_MM: Opnd = Inst.getOperand(2); if (!Opnd.isImm()) Index: lib/Target/Mips/MicroMips32r6InstrFormats.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrFormats.td +++ lib/Target/Mips/MicroMips32r6InstrFormats.td @@ -94,3 +94,19 @@ let Inst{20-16} = funct; let Inst{15-0} = imm; } + +class TRAP_MMR6_ENC funct> : MipsR6Inst { + bits<5> rs; + bits<5> rt; + bits<4> code_; + + bits<32> Inst; + + let Inst{31-26} = 0x00; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-12} = code_; + let Inst{11-6} = funct; + let Inst{5-0} = 0x3c; +} + Index: lib/Target/Mips/MicroMips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrInfo.td +++ lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -36,6 +36,12 @@ class PREF_MMR6_ENC : CACHE_PREF_FM_MMR6<0b011000, 0b0010>; class SUB_MMR6_ENC : ARITH_FM_MMR6<"sub", 0x190>; class SUBU_MMR6_ENC : ARITH_FM_MMR6<"subu", 0x1d0>; +class TEQ_MMR6_ENC : TRAP_MMR6_ENC<0b000000>; +class TGE_MMR6_ENC : TRAP_MMR6_ENC<0b001000>; +class TGEU_MMR6_ENC : TRAP_MMR6_ENC<0b010000>; +class TLT_MMR6_ENC : TRAP_MMR6_ENC<0b100000>; +class TLTU_MMR6_ENC : TRAP_MMR6_ENC<0b101000>; +class TNE_MMR6_ENC : TRAP_MMR6_ENC<0b110000>; //===----------------------------------------------------------------------===// // @@ -133,6 +139,24 @@ class ADDIUPC_MMR6_DESC : PCREL_MMR6_DESC_BASE<"addiupc", GPR32Opnd, simm19_lsl2>; class LWPC_MMR6_DESC: PCREL_MMR6_DESC_BASE<"lwpc", GPR32Opnd, simm19_lsl2>; +class TRAP_MMR6_DESC + : MMR6Arch { + dag InOperandList = (ins RO:$rs, RO:$rt, uimm4:$code_); + dag OutOperandList = (outs); + string AsmString = !strconcat(instr_asm, "\t$rs, $rt, $code_"); + list Pattern = []; + Format f = FrmI; + string BaseOpcode = instr_asm; + bit hasSideEffects = 1; +} + +class TEQ_MMR6_DESC : TRAP_MMR6_DESC<"teq", GPR32Opnd>; +class TGE_MMR6_DESC : TRAP_MMR6_DESC<"tge", GPR32Opnd>; +class TGEU_MMR6_DESC : TRAP_MMR6_DESC<"tgeu", GPR32Opnd>; +class TLT_MMR6_DESC : TRAP_MMR6_DESC<"tlt", GPR32Opnd>; +class TLTU_MMR6_DESC : TRAP_MMR6_DESC<"tltu", GPR32Opnd>; +class TNE_MMR6_DESC : TRAP_MMR6_DESC<"tne", GPR32Opnd>; + //===----------------------------------------------------------------------===// // // Instruction Definitions @@ -163,4 +187,10 @@ def PREF_MMR6 : R6MMR6Rel, PREF_MMR6_ENC, PREF_MMR6_DESC, ISA_MICROMIPS32R6; def SUB_MMR6 : StdMMR6Rel, SUB_MMR6_DESC, SUB_MMR6_ENC, ISA_MICROMIPS32R6; def SUBU_MMR6 : StdMMR6Rel, SUBU_MMR6_DESC, SUBU_MMR6_ENC, ISA_MICROMIPS32R6; +def TEQ_MMR6 : StdMMR6Rel, TEQ_MMR6_ENC, TEQ_MMR6_DESC, ISA_MICROMIPS32R6; +def TGE_MMR6 : StdMMR6Rel, TGE_MMR6_ENC, TGE_MMR6_DESC, ISA_MICROMIPS32R6; +def TGEU_MMR6 : StdMMR6Rel, TGEU_MMR6_ENC, TGEU_MMR6_DESC, ISA_MICROMIPS32R6; +def TLT_MMR6 : StdMMR6Rel, TLT_MMR6_ENC, TLT_MMR6_DESC, ISA_MICROMIPS32R6; +def TLTU_MMR6 : StdMMR6Rel, TLTU_MMR6_ENC, TLTU_MMR6_DESC, ISA_MICROMIPS32R6; +def TNE_MMR6 : StdMMR6Rel, TNE_MMR6_ENC, TNE_MMR6_DESC, ISA_MICROMIPS32R6; } Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -610,6 +610,16 @@ def BREAK16_MM : BrkSdbbp16MM<"break16">, BRKSDBBP16_FM_MM<0x28>; def SDBBP16_MM : BrkSdbbp16MM<"sdbbp16">, BRKSDBBP16_FM_MM<0x2C>; +let DecoderNamespace = "MicroMips" in { +/// Trap Instructions +def TEQ_MM : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM_MM<0x0>, ISA_MICROMIPS32R2; +def TGE_MM : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM_MM<0x08>, ISA_MICROMIPS32R2; +def TGEU_MM : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM_MM<0x10>, ISA_MICROMIPS32R2; +def TLT_MM : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM_MM<0x20>, ISA_MICROMIPS32R2; +def TLTU_MM : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM_MM<0x28>, ISA_MICROMIPS32R2; +def TNE_MM : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM_MM<0x30>, ISA_MICROMIPS32R2; +} + class WaitMM : InstSE<(outs), (ins uimm10:$code_), !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmOther, opstr>; @@ -836,13 +846,6 @@ ISA_MIPS32R2; /// Trap Instructions - def TEQ_MM : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM_MM<0x0>; - def TGE_MM : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM_MM<0x08>; - def TGEU_MM : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM_MM<0x10>; - def TLT_MM : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM_MM<0x20>; - def TLTU_MM : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM_MM<0x28>; - def TNE_MM : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM_MM<0x30>; - def TEQI_MM : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM_MM<0x0e>; def TGEI_MM : MMRel, TEQI_FT<"tgei", GPR32Opnd>, TEQI_FM_MM<0x09>; def TGEIU_MM : MMRel, TEQI_FT<"tgeiu", GPR32Opnd>, TEQI_FM_MM<0x0b>; Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -252,6 +252,9 @@ class ISA_MICROMIPS32R6 { list InsnPredicates = [HasMicroMips32r6]; } +class ISA_MICROMIPS32R2 { + list InsnPredicates = [InMicroMips, NotMips32r6]; +} // The portions of MIPS-III that were also added to MIPS32 class INSN_MIPS3_32 { list InsnPredicates = [HasMips3_32]; } @@ -1247,12 +1250,14 @@ def SYNC : MMRel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS32; def SYNCI : MMRel, SYNCI_FT<"synci">, SYNCI_FM, ISA_MIPS32R2; -def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>, ISA_MIPS2; -def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>, ISA_MIPS2; -def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>, ISA_MIPS2; -def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM<0x32>, ISA_MIPS2; -def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM<0x33>, ISA_MIPS2; -def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM<0x36>, ISA_MIPS2; +let AdditionalPredicates = [NotInMicroMips] in { +def TEQ : MMRel, StdMMR6Rel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>, ISA_MIPS2; +def TGE : MMRel, StdMMR6Rel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>, ISA_MIPS2; +def TGEU : MMRel, StdMMR6Rel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>, ISA_MIPS2; +def TLT : MMRel, StdMMR6Rel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM<0x32>, ISA_MIPS2; +def TLTU : MMRel, StdMMR6Rel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM<0x33>, ISA_MIPS2; +def TNE : MMRel, StdMMR6Rel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM<0x36>, ISA_MIPS2; +} def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM<0xc>, ISA_MIPS2_NOT_32R6_64R6; Index: test/MC/Disassembler/Mips/micromips32r6.txt =================================================================== --- test/MC/Disassembler/Mips/micromips32r6.txt +++ test/MC/Disassembler/Mips/micromips32r6.txt @@ -45,3 +45,15 @@ 0x00 0xa4 0x19 0xd0 # CHECK: subu $3, $4, $5 +0x01 0x28 0x00 0x3c # CHECK: teq $8, $9, 0 +0x00 0xe5 0xf0 0x3c # CHECK: teq $5, $7, 15 +0x01 0x47 0x02 0x3c # CHECK: tge $7, $10, 0 +0x02 0x67 0xf2 0x3c # CHECK: tge $7, $19, 15 +0x03 0x96 0x04 0x3c # CHECK: tgeu $22, $gp, 0 +0x01 0xd4 0xf4 0x3c # CHECK: tgeu $20, $14, 15 +0x01 0xaf 0x08 0x3c # CHECK: tlt $15, $13, 0 +0x02 0x62 0xf8 0x3c # CHECK: tlt $2, $19, 15 +0x02 0x0b 0x0a 0x3c # CHECK: tltu $11, $16, 0 +0x03 0xb0 0xfa 0x3c # CHECK: tltu $16, $sp, 15 +0x02 0x26 0x0c 0x3c # CHECK: tne $6, $17, 0 +0x01 0x07 0xfc 0x3c # CHECK: tne $7, $8, 15 Index: test/MC/Mips/micromips-trap-instructions.s =================================================================== --- test/MC/Mips/micromips-trap-instructions.s +++ test/MC/Mips/micromips-trap-instructions.s @@ -36,12 +36,12 @@ # CHECK-EB: tlti $9, 17767 # encoding: [0x41,0x09,0x45,0x67] # CHECK-EB: tltiu $9, 17767 # encoding: [0x41,0x49,0x45,0x67] # CHECK-EB: tnei $9, 17767 # encoding: [0x41,0x89,0x45,0x67] - teq $8, $9, 0 - tge $8, $9, 0 - tgeu $8, $9, 0 - tlt $8, $9, 0 - tltu $8, $9, 0 - tne $8, $9, 0 + teq $8, $9 + tge $8, $9 + tgeu $8, $9 + tlt $8, $9 + tltu $8, $9 + tne $8, $9 teqi $9, 17767 tgei $9, 17767 tgeiu $9, 17767 Index: test/MC/Mips/micromips32r6/invalid.s =================================================================== --- /dev/null +++ test/MC/Mips/micromips32r6/invalid.s @@ -0,0 +1,27 @@ +# RUN: not llvm-mc %s -triple=mips -show-encoding -mcpu=mips32r6 -mattr=micromips 2>%t1 +# RUN: FileCheck %s < %t1 + + teq $34, $9, 5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + teq $8, $35, 6 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + teq $8, $9, 16 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + tge $34, $9, 5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + tge $8, $35, 6 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + tge $8, $9, 16 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + tgeu $34, $9, 5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + tgeu $8, $35, 6 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + tgeu $8, $9, 16 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + tlt $34, $9, 5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + tlt $8, $35, 6 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + tlt $8, $9, 16 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + tltu $34, $9, 5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + tltu $8, $35, 6 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + tltu $8, $9, 16 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + tne $34, $9, 5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + tne $8, $35, 6 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + tne $8, $9, 16 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + teq $8, $9, $2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + tge $8, $9, $2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + tgeu $8, $9, $2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + tlt $8, $9, $2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + tltu $8, $9, $2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + tne $8, $9, $2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/micromips32r6/valid.s =================================================================== --- test/MC/Mips/micromips32r6/valid.s +++ test/MC/Mips/micromips32r6/valid.s @@ -21,4 +21,15 @@ pref 1, 8($5) # CHECK: pref 1, 8($5) # encoding: [0x60,0x25,0x20,0x08] sub $3, $4, $5 # CHECK: sub $3, $4, $5 # encoding: [0x00,0xa4,0x19,0x90] subu $3, $4, $5 # CHECK: subu $3, $4, $5 # encoding: [0x00,0xa4,0x19,0xd0] - + teq $8, $9 # CHECK: teq $8, $9 # encoding: [0x01,0x28,0x00,0x3c] + teq $5, $7, 15 # CHECK: teq $5, $7, 15 # encoding: [0x00,0xe5,0xf0,0x3c] + tge $7, $10 # CHECK: tge $7, $10 # encoding: [0x01,0x47,0x02,0x3c] + tge $7, $19, 15 # CHECK: tge $7, $19, 15 # encoding: [0x02,0x67,0xf2,0x3c] + tgeu $22, $gp # CHECK: tgeu $22, $gp # encoding: [0x03,0x96,0x04,0x3c] + tgeu $20, $14, 15 # CHECK: tgeu $20, $14, 15 # encoding: [0x01,0xd4,0xf4,0x3c] + tlt $15, $13 # CHECK: tlt $15, $13 # encoding: [0x01,0xaf,0x08,0x3c] + tlt $2, $19, 15 # CHECK: tlt $2, $19, 15 # encoding: [0x02,0x62,0xf8,0x3c] + tltu $11, $16 # CHECK: tltu $11, $16 # encoding: [0x02,0x0b,0x0a,0x3c] + tltu $16, $sp, 15 # CHECK: tltu $16, $sp, 15 # encoding: [0x03,0xb0,0xfa,0x3c] + tne $6, $17 # CHECK: tne $6, $17 # encoding: [0x02,0x26,0x0c,0x3c] + tne $7, $8, 15 # CHECK: tne $7, $8, 15 # encoding: [0x01,0x07,0xfc,0x3c]