From 01f7089bca51744226306e09db4954e3df02b3be Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Thu, 27 Sep 2012 02:15:57 +0000 Subject: [PATCH] MIPS DSP: Branch on Greater Than or Equal To Value 32 in DSPControl Pos Field instruction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164751 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsDSPInstrFormats.td | 10 ++++ lib/Target/Mips/MipsDSPInstrInfo.td | 25 ++++++++++ lib/Target/Mips/MipsISelLowering.cpp | 66 ++++++++++++++++++++++++++ lib/Target/Mips/MipsISelLowering.h | 2 + test/CodeGen/Mips/dsp-r1.ll | 10 ++++ 5 files changed, 113 insertions(+) diff --git a/lib/Target/Mips/MipsDSPInstrFormats.td b/lib/Target/Mips/MipsDSPInstrFormats.td index 2a0bc2eaaef..c22bbdc2084 100644 --- a/lib/Target/Mips/MipsDSPInstrFormats.td +++ b/lib/Target/Mips/MipsDSPInstrFormats.td @@ -103,3 +103,13 @@ class SHILO_R2_FMT op> : DSPInst { let Inst{10-6} = op; let Inst{5-0} = 0b111000; } + +class BPOSGE32_FMT op> : DSPInst { + bits<16> offset; + + let Opcode = REGIMM_OPCODE.V; + + let Inst{25-21} = 0; + let Inst{20-16} = op; + let Inst{15-0} = offset; +} diff --git a/lib/Target/Mips/MipsDSPInstrInfo.td b/lib/Target/Mips/MipsDSPInstrInfo.td index 34475fd704a..6fb1339e944 100644 --- a/lib/Target/Mips/MipsDSPInstrInfo.td +++ b/lib/Target/Mips/MipsDSPInstrInfo.td @@ -103,6 +103,7 @@ class MADD_DSP_ENC : MULT_FMT<0b011100, 0b000000>; class MADDU_DSP_ENC : MULT_FMT<0b011100, 0b000001>; class MSUB_DSP_ENC : MULT_FMT<0b011100, 0b000100>; class MSUBU_DSP_ENC : MULT_FMT<0b011100, 0b000101>; +class BPOSGE32_ENC : BPOSGE32_FMT<0b11100>; class EXTP_ENC : EXTR_W_TY1_FMT<0b00010>; class EXTPV_ENC : EXTR_W_TY1_FMT<0b00011>; @@ -216,6 +217,23 @@ class MULT_DESC_BASE { string AsmString = !strconcat(instr_asm, "\t$ac, $rs, $rt"); } +class BPOSGE32_PSEUDO_DESC_BASE : + MipsPseudo<(outs CPURegs:$dst), (ins), "", [(set CPURegs:$dst, (OpNode))]> { + list Uses = [DSPCtrl]; + bit usesCustomInserter = 1; +} + +class BPOSGE32_DESC_BASE { + dag OutOperandList = (outs); + dag InOperandList = (ins brtarget:$offset); + string AsmString = !strconcat(instr_asm, "\t$offset"); + InstrItinClass Itinerary = itin; + list Uses = [DSPCtrl]; + bit isBranch = 1; + bit isTerminator = 1; + bit hasDelaySlot = 1; +} + //===----------------------------------------------------------------------===// // MIPS DSP Rev 1 //===----------------------------------------------------------------------===// @@ -260,6 +278,9 @@ class MSUB_DSP_DESC : MULT_DESC_BASE<"msub">; class MSUBU_DSP_DESC : MULT_DESC_BASE<"msubu">; +// Misc +class BPOSGE32_DESC : BPOSGE32_DESC_BASE<"bposge32", NoItinerary>; + // Extr class EXTP_DESC : EXTR_W_TY1_R1_DESC_BASE<"extp", MipsEXTP, NoItinerary>; @@ -320,6 +341,9 @@ class DPSQX_SA_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpsqx_sa.w.ph">; class MULSA_W_PH_DESC : DPA_W_PH_DESC_BASE<"mulsa.w.ph">; +// Pseudos. +def BPOSGE32_PSEUDO : BPOSGE32_PSEUDO_DESC_BASE; + // Instruction defs. // MIPS DSP Rev 1 def MULSAQ_S_W_PH : MULSAQ_S_W_PH_ENC, MULSAQ_S_W_PH_DESC; @@ -341,6 +365,7 @@ 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 BPOSGE32 : BPOSGE32_ENC, BPOSGE32_DESC; def EXTP : EXTP_ENC, EXTP_DESC; def EXTPV : EXTPV_ENC, EXTPV_DESC; def EXTPDP : EXTPDP_ENC, EXTPDP_DESC; diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 0ddfde2669c..d8097032caf 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -978,6 +978,70 @@ static MachineBasicBlock* ExpandCondMov(MachineInstr *MI, MachineBasicBlock *BB, return BB; } */ + +MachineBasicBlock * +MipsTargetLowering::EmitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{ + // $bb: + // bposge32_pseudo $vr0 + // => + // $bb: + // bposge32 $tbb + // $fbb: + // li $vr2, 0 + // b $sink + // $tbb: + // li $vr1, 1 + // $sink: + // $vr0 = phi($vr2, $fbb, $vr1, $tbb) + + MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + const TargetRegisterClass *RC = &Mips::CPURegsRegClass; + DebugLoc DL = MI->getDebugLoc(); + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB)); + MachineFunction *F = BB->getParent(); + MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB); + F->insert(It, FBB); + F->insert(It, TBB); + F->insert(It, Sink); + + // Transfer the remainder of BB and its successor edges to Sink. + Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)), + BB->end()); + Sink->transferSuccessorsAndUpdatePHIs(BB); + + // Add successors. + BB->addSuccessor(FBB); + BB->addSuccessor(TBB); + FBB->addSuccessor(Sink); + TBB->addSuccessor(Sink); + + // Insert the real bposge32 instruction to $BB. + BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB); + + // Fill $FBB. + unsigned VR2 = RegInfo.createVirtualRegister(RC); + BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2) + .addReg(Mips::ZERO).addImm(0); + BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink); + + // Fill $TBB. + unsigned VR1 = RegInfo.createVirtualRegister(RC); + BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1) + .addReg(Mips::ZERO).addImm(1); + + // Insert phi function to $Sink. + BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI), + MI->getOperand(0).getReg()) + .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB); + + MI->eraseFromParent(); // The pseudo instruction is gone now. + return Sink; +} + MachineBasicBlock * MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB) const { @@ -1086,6 +1150,8 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, case Mips::ATOMIC_CMP_SWAP_I64: case Mips::ATOMIC_CMP_SWAP_I64_P8: return EmitAtomicCmpSwap(MI, BB, 8); + case Mips::BPOSGE32_PSEUDO: + return EmitBPOSGE32(MI, BB); } } diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index d66c37940f4..b4cc16c1ca2 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -262,6 +262,8 @@ namespace llvm { virtual unsigned getJumpTableEncoding() const; + MachineBasicBlock *EmitBPOSGE32(MachineInstr *MI, + MachineBasicBlock *BB) const; MachineBasicBlock *EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, unsigned Size, unsigned BinOpcode, bool Nand = false) const; MachineBasicBlock *EmitAtomicBinaryPartword(MachineInstr *MI, diff --git a/test/CodeGen/Mips/dsp-r1.ll b/test/CodeGen/Mips/dsp-r1.ll index 0b2ac1a7ad2..d2838724276 100644 --- a/test/CodeGen/Mips/dsp-r1.ll +++ b/test/CodeGen/Mips/dsp-r1.ll @@ -288,6 +288,16 @@ entry: declare i64 @llvm.mips.mthlip(i64, i32) nounwind +define i32 @test__builtin_mips_bposge321(i32 %i0) nounwind readonly { +entry: +; CHECK: bposge32 + + %0 = tail call i32 @llvm.mips.bposge32() + ret i32 %0 +} + +declare i32 @llvm.mips.bposge32() nounwind readonly + define i64 @test__builtin_mips_madd1(i32 %i0, i32, i64 %a0, i32 %a1, i32 %a2) nounwind readnone { entry: ; CHECK: madd -- 2.34.1