From c962c4936e83556490ff31af646180462e279dd7 Mon Sep 17 00:00:00 2001 From: Hrvoje Varga Date: Thu, 9 Jun 2016 12:57:23 +0000 Subject: [PATCH] [mips][microMIPS] Implement BOVC, BNVC, EXT, INS and JALRC instructions Differential Revision: http://reviews.llvm.org/D11798 llvm-svn: 272259 --- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 1 + .../Mips/Disassembler/MipsDisassembler.cpp | 72 ++++++++++++++++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 30 ++++++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.h | 7 ++ .../Target/Mips/MicroMips32r6InstrFormats.td | 43 +++++++++++ .../lib/Target/Mips/MicroMips32r6InstrInfo.td | 75 ++++++++++++++++++- llvm/lib/Target/Mips/MicroMipsInstrInfo.td | 3 +- llvm/lib/Target/Mips/Mips32r6InstrInfo.td | 10 ++- llvm/lib/Target/Mips/MipsInstrInfo.td | 13 ++-- .../Disassembler/Mips/micromips32r6/valid.txt | 6 ++ llvm/test/MC/Mips/micromips32r6/invalid.s | 2 + llvm/test/MC/Mips/micromips32r6/valid.s | 8 ++ 12 files changed, 257 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 94f09a95d36a..d2e84c527599 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -3722,6 +3722,7 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { // and registers Rd and Base for microMIPS lwp instruction case Mips::JALR_HB: case Mips::JALRC_HB_MMR6: + case Mips::JALRC_MMR6: if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) return Match_RequiresDifferentSrcAndDst; return Match_Success; diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index ad247c3e9cb1..f5fc090417dd 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -432,11 +432,21 @@ static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, const void *Decoder); +template +static DecodeStatus +DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, + const void *Decoder); + template static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, const void *Decoder); +template +static DecodeStatus +DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, + const void *Decoder); + template static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, @@ -603,6 +613,37 @@ static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn, return MCDisassembler::Success; } +template +static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, + uint64_t Address, + const void *Decoder) { + InsnType Rt = fieldFromInstruction(insn, 21, 5); + InsnType Rs = fieldFromInstruction(insn, 16, 5); + InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2; + + if (Rs >= Rt) { + MI.setOpcode(Mips::BOVC_MMR6); + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, + Rt))); + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, + Rs))); + } else if (Rs != 0 && Rs < Rt) { + MI.setOpcode(Mips::BEQC_MMR6); + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, + Rs))); + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, + Rt))); + } else { + MI.setOpcode(Mips::BEQZALC_MMR6); + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, + Rt))); + } + + MI.addOperand(MCOperand::createImm(Imm)); + + return MCDisassembler::Success; +} + template static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, @@ -642,6 +683,37 @@ static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, return MCDisassembler::Success; } +template +static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, + uint64_t Address, + const void *Decoder) { + InsnType Rt = fieldFromInstruction(insn, 21, 5); + InsnType Rs = fieldFromInstruction(insn, 16, 5); + InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2; + + if (Rs >= Rt) { + MI.setOpcode(Mips::BNVC_MMR6); + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, + Rt))); + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, + Rs))); + } else if (Rs != 0 && Rs < Rt) { + MI.setOpcode(Mips::BNEC_MMR6); + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, + Rs))); + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, + Rt))); + } else { + MI.setOpcode(Mips::BNEZALC_MMR6); + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, + Rt))); + } + + MI.addOperand(MCOperand::createImm(Imm)); + + return MCDisassembler::Success; +} + template static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index fce4efdc8de8..136fef12ee04 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -124,6 +124,10 @@ void MipsMCCodeEmitter::LowerCompactBranch(MCInst& Inst) const { } else if (Inst.getOpcode() == Mips::BNVC || Inst.getOpcode() == Mips::BOVC) { if (Reg0 >= Reg1) return; + } else if (Inst.getOpcode() == Mips::BNVC_MMR6 || + Inst.getOpcode() == Mips::BOVC_MMR6) { + if (Reg1 >= Reg0) + return; } else llvm_unreachable("Cannot rewrite unknown branch!"); @@ -191,7 +195,9 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS, case Mips::BEQC: case Mips::BNEC: case Mips::BOVC: + case Mips::BOVC_MMR6: case Mips::BNVC: + case Mips::BNVC_MMR6: LowerCompactBranch(TmpInst); } @@ -286,6 +292,30 @@ getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo, return 0; } +/// getBranchTargetOpValueMMR6 - Return binary encoding of the branch +/// target operand. If the machine operand requires relocation, +/// record the relocation and return zero. +unsigned MipsMCCodeEmitter:: +getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + + const MCOperand &MO = MI.getOperand(OpNo); + + // If the destination is an immediate, divide by 2. + if (MO.isImm()) + return MO.getImm() >> 1; + + assert(MO.isExpr() && + "getBranchTargetOpValueMMR6 expects only expressions or immediates"); + + const MCExpr *FixupExpression = MCBinaryExpr::createAdd( + MO.getExpr(), MCConstantExpr::create(-2, Ctx), Ctx); + Fixups.push_back(MCFixup::create(0, FixupExpression, + MCFixupKind(Mips::fixup_Mips_PC16))); + return 0; +} + /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch /// target operand. If the machine operand requires relocation, /// record the relocation and return zero. diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index 01daaa252965..6bc9a1b1c287 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -109,6 +109,13 @@ public: SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + // getBranchTargetOpValueMMR6 - Return binary encoding of the branch + // target operand. If the machine operand requires relocation, + // record the relocation and return zero. + unsigned getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + // getBranchTarget7OpValue - Return binary encoding of the microMIPS branch // target operand. If the machine operand requires relocation, // record the relocation and return zero. diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td b/llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td index d3044e196131..c229fe68ddc9 100644 --- a/llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td +++ b/llvm/lib/Target/Mips/MicroMips32r6InstrFormats.td @@ -71,6 +71,32 @@ class POOL16C_JALRC_FM_MM16R6 op> { let Inst{4-0} = op; } +class POP35_BOVC_FM_MMR6 : MipsR6Inst, MMR6Arch { + bits<5> rt; + bits<5> rs; + bits<16> offset; + + bits<32> Inst; + + let Inst{31-26} = 0b011101; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-0} = offset; +} + +class POP37_BNVC_FM_MMR6 : MipsR6Inst, MMR6Arch { + bits<5> rt; + bits<5> rs; + bits<16> offset; + + bits<32> Inst; + + let Inst{31-26} = 0b011111; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-0} = offset; +} + class POOL16C_JRCADDIUSP_FM_MM16R6 op> { bits<5> imm; @@ -508,6 +534,23 @@ class POOL32A_JALRC_FM_MMR6 funct> let Inst{5-0} = 0b111100; } +class POOL32A_EXT_INS_FM_MMR6 funct> + : MMR6Arch, MipsR6Inst { + bits<5> rt; + bits<5> rs; + bits<5> size; + bits<5> pos; + + bits<32> Inst; + + let Inst{31-26} = 0; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-11} = size; + let Inst{10-6} = pos; + let Inst{5-0} = funct; +} + class POOL32A_ERET_FM_MMR6 funct> : MMR6Arch { bits<32> Inst; diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td index 5ac2812fc658..b92d678a7b94 100644 --- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -25,6 +25,13 @@ def brtarget26_mm : Operand { let ParserMatchClass = MipsJumpTargetAsmOperand; } +def brtargetr6 : Operand { + let EncoderMethod = "getBranchTargetOpValueMMR6"; + let OperandType = "OPERAND_PCREL"; + let DecoderMethod = "DecodeBranchTargetMM"; + let ParserMatchClass = MipsJumpTargetAsmOperand; +} + //===----------------------------------------------------------------------===// // // Instruction Encodings @@ -190,7 +197,11 @@ class SELNEZ_S_MMR6_ENC : POOL32F_SEL_FM_MMR6<"selnez.s", 0, 0b001111000>; class SELNEZ_D_MMR6_ENC : POOL32F_SEL_FM_MMR6<"selnez.d", 1, 0b001111000>; class CLASS_S_MMR6_ENC : POOL32F_CLASS_FM_MMR6<"class.s", 0, 0b001100000>; class CLASS_D_MMR6_ENC : POOL32F_CLASS_FM_MMR6<"class.d", 1, 0b001100000>; - +class EXT_MMR6_ENC : POOL32A_EXT_INS_FM_MMR6<"ext", 0b101100>; +class INS_MMR6_ENC : POOL32A_EXT_INS_FM_MMR6<"ins", 0b001100>; +class JALRC_MMR6_ENC : POOL32A_JALRC_FM_MMR6<"jalrc", 0b0000111100>; +class BOVC_MMR6_ENC : POP35_BOVC_FM_MMR6<"bovc">; +class BNVC_MMR6_ENC : POP37_BNVC_FM_MMR6<"bnvc">; class ADDU16_MMR6_ENC : POOL16A_ADDU16_FM_MMR6; class AND16_MMR6_ENC : POOL16C_AND16_FM_MMR6; class ANDI16_MMR6_ENC : ANDI_FM_MM16<0b001011>, MicroMipsR6Inst16; @@ -1193,6 +1204,53 @@ class BRANCH_COP2_MMR6_DESC_BASE : BRANCH_DESC_BASE { class BC2EQZC_MMR6_DESC : BRANCH_COP2_MMR6_DESC_BASE<"bc2eqzc">; class BC2NEZC_MMR6_DESC : BRANCH_COP2_MMR6_DESC_BASE<"bc2nezc">; +class EXT_MMR6_DESC { + dag OutOperandList = (outs GPR32Opnd:$rt); + dag InOperandList = (ins GPR32Opnd:$rs, uimm5:$pos, uimm5_plus1:$size); + string AsmString = !strconcat("ext", "\t$rt, $rs, $pos, $size"); + list Pattern = [(set GPR32Opnd:$rt, (MipsExt GPR32Opnd:$rs, imm:$pos, + imm:$size))]; + InstrItinClass Itinerary = II_EXT; + Format Form = FrmR; + string BaseOpcode = "ext"; +} + +class INS_MMR6_DESC { + dag OutOperandList = (outs GPR32Opnd:$rt); + dag InOperandList = (ins GPR32Opnd:$rs, uimm5:$pos, uimm5_inssize_plus1:$size, + GPR32Opnd:$src); + string AsmString = !strconcat("ins", "\t$rt, $rs, $pos, $size"); + list Pattern = [(set GPR32Opnd:$rt, (MipsIns GPR32Opnd:$rs, imm:$pos, + imm:$size, GPR32Opnd:$src))]; + InstrItinClass Itinerary = II_INS; + Format Form = FrmR; + string BaseOpcode = "ins"; + string Constraints = "$src = $rt"; +} + +class JALRC_MMR6_DESC { + dag OutOperandList = (outs GPR32Opnd:$rt); + dag InOperandList = (ins GPR32Opnd:$rs); + string AsmString = !strconcat("jalrc", "\t$rt, $rs"); + list Pattern = []; + InstrItinClass Itinerary = II_JALRC; + bit isCall = 1; + bit hasDelaySlot = 0; + list Defs = [RA]; +} + +class BOVC_BNVC_MMR6_DESC_BASE + : BRANCH_DESC_BASE { + dag InOperandList = (ins GPROpnd:$rt, GPROpnd:$rs, opnd:$offset); + dag OutOperandList = (outs); + string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $offset"); + list Defs = [AT]; +} + +class BOVC_MMR6_DESC : BOVC_BNVC_MMR6_DESC_BASE<"bovc", brtargetr6, GPR32Opnd>; +class BNVC_MMR6_DESC : BOVC_BNVC_MMR6_DESC_BASE<"bnvc", brtargetr6, GPR32Opnd>; + //===----------------------------------------------------------------------===// // // Instruction Definitions @@ -1464,6 +1522,9 @@ def XOR16_MMR6 : StdMMR6Rel, XOR16_MMR6_DESC, XOR16_MMR6_ENC, ISA_MICROMIPS32R6; def JALRC_HB_MMR6 : R6MMR6Rel, JALRC_HB_MMR6_ENC, JALRC_HB_MMR6_DESC, ISA_MICROMIPS32R6; +def EXT_MMR6 : StdMMR6Rel, EXT_MMR6_ENC, EXT_MMR6_DESC, ISA_MICROMIPS32R6; +def INS_MMR6 : StdMMR6Rel, INS_MMR6_ENC, INS_MMR6_DESC, ISA_MICROMIPS32R6; +def JALRC_MMR6 : R6MMR6Rel, JALRC_MMR6_ENC, JALRC_MMR6_DESC, ISA_MICROMIPS32R6; def RECIP_S_MMR6 : StdMMR6Rel, RECIP_S_MMR6_ENC, RECIP_S_MMR6_DESC, ISA_MICROMIPS32R6; def RECIP_D_MMR6 : StdMMR6Rel, RECIP_D_MMR6_ENC, RECIP_D_MMR6_DESC, ISA_MICROMIPS32R6; @@ -1508,12 +1569,18 @@ def BC2NEZC_MMR6 : R6MMR6Rel, MipsR6Inst, BC2NEZC_MMR6_ENC, BC2NEZC_MMR6_DESC, ISA_MICROMIPS32R6; } +def BOVC_MMR6 : R6MMR6Rel, BOVC_MMR6_ENC, BOVC_MMR6_DESC, ISA_MICROMIPS32R6, + MMDecodeDisambiguatedBy<"POP35GroupBranchMMR6">; +def BNVC_MMR6 : R6MMR6Rel, BNVC_MMR6_ENC, BNVC_MMR6_DESC, ISA_MICROMIPS32R6, + MMDecodeDisambiguatedBy<"POP37GroupBranchMMR6">; def BGEC_MMR6 : R6MMR6Rel, BGEC_MMR6_ENC, BGEC_MMR6_DESC, ISA_MICROMIPS32R6; def BGEUC_MMR6 : R6MMR6Rel, BGEUC_MMR6_ENC, BGEUC_MMR6_DESC, ISA_MICROMIPS32R6; def BLTC_MMR6 : R6MMR6Rel, BLTC_MMR6_ENC, BLTC_MMR6_DESC, ISA_MICROMIPS32R6; def BLTUC_MMR6 : R6MMR6Rel, BLTUC_MMR6_ENC, BLTUC_MMR6_DESC, ISA_MICROMIPS32R6; -def BEQC_MMR6 : R6MMR6Rel, BEQC_MMR6_ENC, BEQC_MMR6_DESC, ISA_MICROMIPS32R6; -def BNEC_MMR6 : R6MMR6Rel, BNEC_MMR6_ENC, BNEC_MMR6_DESC, ISA_MICROMIPS32R6; +def BEQC_MMR6 : R6MMR6Rel, BEQC_MMR6_ENC, BEQC_MMR6_DESC, ISA_MICROMIPS32R6, + DecodeDisambiguates<"POP35GroupBranchMMR6">; +def BNEC_MMR6 : R6MMR6Rel, BNEC_MMR6_ENC, BNEC_MMR6_DESC, ISA_MICROMIPS32R6, + DecodeDisambiguates<"POP37GroupBranchMMR6">; def BGEZALC_MMR6 : R6MMR6Rel, BGEZALC_MMR6_ENC, BGEZALC_MMR6_DESC, ISA_MICROMIPS32R6; def BGTZALC_MMR6 : R6MMR6Rel, BGTZALC_MMR6_ENC, BGTZALC_MMR6_DESC, @@ -1557,6 +1624,8 @@ def : MipsInstAlias<"jalrc.hb $rs", (JALRC_HB_MMR6 RA, GPR32Opnd:$rs), 1>, ISA_MICROMIPS32R6; def : MipsInstAlias<"dvp", (DVP_MMR6 ZERO), 0>, ISA_MICROMIPS32R6; def : MipsInstAlias<"evp", (EVP_MMR6 ZERO), 0>, ISA_MICROMIPS32R6; +def : MipsInstAlias<"jalrc $rs", (JALRC_MMR6 RA, GPR32Opnd:$rs), 1>, + ISA_MICROMIPS32R6; //===----------------------------------------------------------------------===// // diff --git a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td index f0b84f131dce..edc160e64299 100644 --- a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td @@ -887,7 +887,8 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { def JAL_MM : MMRel, JumpLink<"jal", calltarget_mm>, J_FM_MM<0x3d>; def JALX_MM : MMRel, JumpLink<"jalx", calltarget>, J_FM_MM<0x3c>; } - def JR_MM : MMRel, IndirectBranch<"jr", GPR32Opnd>, JR_FM_MM<0x3c>; + def JR_MM : MMRel, IndirectBranch<"jr", GPR32Opnd>, JR_FM_MM<0x3c>, + ISA_MICROMIPS32_NOT_MIPS32R6; def JALR_MM : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM_MM<0x03c>; /// Jump Instructions - Short Delay Slot diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td index 714d18d12ec5..7c3b88498942 100644 --- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td @@ -772,8 +772,10 @@ def BLTZC : BLTZC_ENC, BLTZC_DESC, ISA_MIPS32R6; def BNEC : R6MMR6Rel, BNEC_ENC, BNEC_DESC, ISA_MIPS32R6; def BNEZALC : R6MMR6Rel, BNEZALC_ENC, BNEZALC_DESC, ISA_MIPS32R6; def BNEZC : R6MMR6Rel, BNEZC_ENC, BNEZC_DESC, ISA_MIPS32R6; -def BNVC : BNVC_ENC, BNVC_DESC, ISA_MIPS32R6; -def BOVC : BOVC_ENC, BOVC_DESC, ISA_MIPS32R6; +let AdditionalPredicates = [NotInMicroMips] in { + def BNVC : R6MMR6Rel, BNVC_ENC, BNVC_DESC, ISA_MIPS32R6; + def BOVC : R6MMR6Rel, BOVC_ENC, BOVC_DESC, ISA_MIPS32R6; +} def CACHE_R6 : R6MMR6Rel, CACHE_ENC, CACHE_DESC, ISA_MIPS32R6; let AdditionalPredicates = [NotInMicroMips] in { def CLASS_D : CLASS_D_ENC, CLASS_D_DESC, ISA_MIPS32R6, HARDFLOAT; @@ -854,12 +856,14 @@ def SWC2_R6 : SWC2_R6_ENC, SWC2_R6_DESC, 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; +} def : MipsInstAlias<"jrc $rs", (JIC GPR32Opnd:$rs, 0), 1>, ISA_MIPS32R6, GPR_32; +let AdditionalPredicates = [NotInMicroMips] in { def : MipsInstAlias<"jalrc $rs", (JIALC GPR32Opnd:$rs, 0), 1>, ISA_MIPS32R6, GPR_32; +} //===----------------------------------------------------------------------===// // // Patterns and Pseudo Instructions diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index 6be1edb4ce2e..4acfa6b3d1f4 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -2006,13 +2006,14 @@ let AdditionalPredicates = [NotInMicroMips] in { def PseudoUDIV : MultDivPseudo, ISA_MIPS1_NOT_32R6_64R6; def RDHWR : MMRel, ReadHardware, RDHWR_FM; + // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction + def EXT : MMRel, StdMMR6Rel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1, + immZExt5, immZExt5Plus1, MipsExt>, + EXT_FM<0>; + def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5, + uimm5_inssize_plus1, MipsIns>, + EXT_FM<4>; } -// TODO: Add '0 < pos+size <= 32' constraint check to ext instruction -def EXT : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1, immZExt5, - immZExt5Plus1, MipsExt>, EXT_FM<0>; -def INS : MMRel, InsBase<"ins", GPR32Opnd, uimm5, uimm5_inssize_plus1, MipsIns>, - EXT_FM<4>; - /// Move Control Registers From/To CPU Registers let AdditionalPredicates = [NotInMicroMips] in { def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd>, MFC3OP_FM<0x10, 4>, diff --git a/llvm/test/MC/Disassembler/Mips/micromips32r6/valid.txt b/llvm/test/MC/Disassembler/Mips/micromips32r6/valid.txt index fb14af63b5d3..557d96b361c1 100644 --- a/llvm/test/MC/Disassembler/Mips/micromips32r6/valid.txt +++ b/llvm/test/MC/Disassembler/Mips/micromips32r6/valid.txt @@ -319,3 +319,9 @@ 0x41 0x3f 0x00 0x02 # CHECK: bc1nezc $f31, 4 0x41 0x5f 0x00 0x04 # CHECK: bc2eqzc $31, 8 0x41 0x7f 0x00 0x04 # CHECK: bc2nezc $31, 8 +0x01 0x26 0x30 0xec # CHECK: ext $9, $6, 3, 7 +0x01 0x26 0x48 0xcc # CHECK: ins $9, $6, 3, 7 +0x00 0x85 0x0f 0x3c # CHECK: jalrc $4, $5 +0x03 0xe5 0x0f 0x3c # CHECK: jalrc $5 +0x74 0x44 0x00 0x0c # CHECK: bovc $2, $4, 24 +0x7c 0x44 0x00 0x0c # CHECK: bnvc $2, $4, 24 diff --git a/llvm/test/MC/Mips/micromips32r6/invalid.s b/llvm/test/MC/Mips/micromips32r6/invalid.s index fc42b3fd4ec6..ad966cb0bc1e 100644 --- a/llvm/test/MC/Mips/micromips32r6/invalid.s +++ b/llvm/test/MC/Mips/micromips32r6/invalid.s @@ -234,3 +234,5 @@ bc2nezc $31, -65537 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: branch target out of range bc2nezc $31, 65535 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: branch to misaligned address bc2nezc $31, 65536 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: branch target out of range + jalrc $31 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: source and destination must be different + jalrc $31, $31 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: source and destination must be different diff --git a/llvm/test/MC/Mips/micromips32r6/valid.s b/llvm/test/MC/Mips/micromips32r6/valid.s index a20671299a30..c69a754cf718 100644 --- a/llvm/test/MC/Mips/micromips32r6/valid.s +++ b/llvm/test/MC/Mips/micromips32r6/valid.s @@ -339,3 +339,11 @@ bc1nezc $f31, 4 # CHECK: bc1nezc $f31, 4 # encoding: [0x41,0x3f,0x00,0x02] bc2eqzc $31, 8 # CHECK: bc2eqzc $31, 8 # encoding: [0x41,0x5f,0x00,0x04] bc2nezc $31, 8 # CHECK: bc2nezc $31, 8 # encoding: [0x41,0x7f,0x00,0x04] + ins $9, $6, 3, 7 # CHECK: ins $9, $6, 3, 7 # encoding: [0x01,0x26,0x48,0xcc] + jalrc $4, $5 # CHECK: jalrc $4, $5 # encoding: [0x00,0x85,0x0f,0x3c] + jalrc $5 # CHECK: jalrc $5 # encoding: [0x03,0xe5,0x0f,0x3c] + ext $9, $6, 3, 7 # CHECK: ext $9, $6, 3, 7 # encoding: [0x01,0x26,0x30,0xec] + bovc $2, $4, 24 # CHECK: bovc $2, $4, 24 # encoding: [0x74,0x44,0x00,0x0c] + bovc $4, $2, 24 # CHECK: bovc $4, $2, 24 # encoding: [0x74,0x44,0x00,0x0c] + bnvc $2, $4, 24 # CHECK: bnvc $2, $4, 24 # encoding: [0x7c,0x44,0x00,0x0c] + bnvc $4, $2, 24 # CHECK: bnvc $4, $2, 24 # encoding: [0x7c,0x44,0x00,0x0c]