diff options
author | Akira Hatanaka <ahatanaka@mips.com> | 2013-04-30 23:22:09 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@mips.com> | 2013-04-30 23:22:09 +0000 |
commit | c147c1b994e1187cb471cdb7ee05f5f875eff4e0 (patch) | |
tree | cb8374bc211e2f08f526dd29e1e24c1ca05161db | |
parent | 3484da9479a4daff3efc7febe004e1f4d69b3b4a (diff) | |
download | llvm-c147c1b994e1187cb471cdb7ee05f5f875eff4e0.tar.gz llvm-c147c1b994e1187cb471cdb7ee05f5f875eff4e0.tar.bz2 llvm-c147c1b994e1187cb471cdb7ee05f5f875eff4e0.tar.xz |
[mips] Fix handling of instructions which copy to/from accumulator registers.
Expand copy instructions between two accumulator registers before callee-saved
scan is done. Handle copies between integer GPR and hi/lo registers in
MipsSEInstrInfo::copyPhysReg. Delete pseudo-copy instructions that are not
needed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180827 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/Mips/Mips64InstrInfo.td | 4 | ||||
-rw-r--r-- | lib/Target/Mips/MipsDSPInstrInfo.td | 4 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 4 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.td | 4 | ||||
-rw-r--r-- | lib/Target/Mips/MipsRegisterInfo.td | 6 | ||||
-rw-r--r-- | lib/Target/Mips/MipsSEFrameLowering.cpp | 28 | ||||
-rw-r--r-- | lib/Target/Mips/MipsSEInstrInfo.cpp | 30 | ||||
-rw-r--r-- | test/CodeGen/Mips/spill-copy-acreg.ll | 21 |
8 files changed, 64 insertions, 37 deletions
diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td index 846a8224af..fc533fb03f 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/lib/Target/Mips/Mips64InstrInfo.td @@ -66,14 +66,12 @@ let usesCustomInserter = 1, Predicates = [HasStdEnc], defm ATOMIC_CMP_SWAP_I64 : AtomicCmpSwap64<atomic_cmp_swap_64>; } -/// Pseudo instructions for loading, storing and copying accumulator registers. +/// Pseudo instructions for loading and storing accumulator registers. let isPseudo = 1 in { defm LOAD_AC128 : LoadM<"load_ac128", ACRegs128>; defm STORE_AC128 : StoreM<"store_ac128", ACRegs128>; } -def COPY_AC128 : PseudoSE<(outs ACRegs128:$dst), (ins ACRegs128:$src), []>; - //===----------------------------------------------------------------------===// // Instruction definition //===----------------------------------------------------------------------===// diff --git a/lib/Target/Mips/MipsDSPInstrInfo.td b/lib/Target/Mips/MipsDSPInstrInfo.td index 6719cd54a9..710b40d68e 100644 --- a/lib/Target/Mips/MipsDSPInstrInfo.td +++ b/lib/Target/Mips/MipsDSPInstrInfo.td @@ -1231,14 +1231,12 @@ def PREPEND : PREPEND_ENC, PREPEND_DESC; } // Pseudos. -/// Pseudo instructions for loading, storing and copying accumulator registers. +/// Pseudo instructions for loading and storing accumulator registers. let isPseudo = 1 in { defm LOAD_AC_DSP : LoadM<"load_ac_dsp", ACRegsDSP>; defm STORE_AC_DSP : StoreM<"store_ac_dsp", ACRegsDSP>; } -def COPY_AC_DSP : PseudoSE<(outs ACRegsDSP:$dst), (ins ACRegsDSP:$src), []>; - // Pseudo CMP and PICK instructions. class PseudoCMP<Instruction RealInst> : PseudoDSP<(outs DSPCC:$cmp), (ins DSPRegs:$rs, DSPRegs:$rt), []>, diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 611d48326e..4d76181f92 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -2831,8 +2831,8 @@ getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const return std::make_pair((unsigned)Mips::T9_64, &Mips::CPU64RegsRegClass); case 'l': // register suitable for indirect jump if (VT == MVT::i32) - return std::make_pair((unsigned)Mips::LO, &Mips::HILORegClass); - return std::make_pair((unsigned)Mips::LO64, &Mips::HILO64RegClass); + return std::make_pair((unsigned)Mips::LO, &Mips::LORegsRegClass); + return std::make_pair((unsigned)Mips::LO64, &Mips::LORegs64RegClass); case 'x': // register suitable for indirect jump // Fixme: Not triggering the use of both hi and low // This will generate an error message diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 15e70190fb..86ec72982b 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -837,14 +837,12 @@ let usesCustomInserter = 1 in { defm ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap32<atomic_cmp_swap_32>; } -/// Pseudo instructions for loading, storing and copying accumulator registers. +/// Pseudo instructions for loading and storing accumulator registers. let isPseudo = 1 in { defm LOAD_AC64 : LoadM<"load_ac64", ACRegs>; defm STORE_AC64 : StoreM<"store_ac64", ACRegs>; } -def COPY_AC64 : PseudoSE<(outs ACRegs:$dst), (ins ACRegs:$src), []>; - //===----------------------------------------------------------------------===// // Instruction definition //===----------------------------------------------------------------------===// diff --git a/lib/Target/Mips/MipsRegisterInfo.td b/lib/Target/Mips/MipsRegisterInfo.td index e314e946a0..865d4d7888 100644 --- a/lib/Target/Mips/MipsRegisterInfo.td +++ b/lib/Target/Mips/MipsRegisterInfo.td @@ -341,10 +341,12 @@ def FGR64 : RegisterClass<"Mips", [f64], 64, (sequence "D%u_64", 0, 31)>; def CCR : RegisterClass<"Mips", [i32], 32, (add FCR31,FCC0)>, Unallocatable; // Hi/Lo Registers -def HILO : RegisterClass<"Mips", [i32], 32, (add HI, LO)>, Unallocatable; -def HILO64 : RegisterClass<"Mips", [i64], 64, (add HI64, LO64)>, Unallocatable; +def LORegs : RegisterClass<"Mips", [i32], 32, (add LO)>; +def HIRegs : RegisterClass<"Mips", [i32], 32, (add HI)>; def LORegsDSP : RegisterClass<"Mips", [i32], 32, (add LO, LO1, LO2, LO3)>; def HIRegsDSP : RegisterClass<"Mips", [i32], 32, (add HI, HI1, HI2, HI3)>; +def LORegs64 : RegisterClass<"Mips", [i64], 64, (add LO64)>; +def HIRegs64 : RegisterClass<"Mips", [i64], 64, (add HI64)>; // Hardware registers def HWRegs : RegisterClass<"Mips", [i32], 32, (add HWR29)>, Unallocatable; diff --git a/lib/Target/Mips/MipsSEFrameLowering.cpp b/lib/Target/Mips/MipsSEFrameLowering.cpp index 68ec921888..ce6d933f04 100644 --- a/lib/Target/Mips/MipsSEFrameLowering.cpp +++ b/lib/Target/Mips/MipsSEFrameLowering.cpp @@ -42,7 +42,7 @@ private: bool expandInstr(MachineBasicBlock &MBB, Iter I); void expandLoad(MachineBasicBlock &MBB, Iter I, unsigned RegSize); void expandStore(MachineBasicBlock &MBB, Iter I, unsigned RegSize); - void expandCopy(MachineBasicBlock &MBB, Iter I, unsigned RegSize); + bool expandCopy(MachineBasicBlock &MBB, Iter I); MachineFunction &MF; const MipsSEInstrInfo &TII; @@ -89,12 +89,9 @@ bool ExpandACCPseudo::expandInstr(MachineBasicBlock &MBB, Iter I) { case Mips::STORE_AC128_P8: expandStore(MBB, I, 8); break; - case Mips::COPY_AC64: - case Mips::COPY_AC_DSP: - expandCopy(MBB, I, 4); - break; - case Mips::COPY_AC128: - expandCopy(MBB, I, 8); + case TargetOpcode::COPY: + if (!expandCopy(MBB, I)) + return false; break; default: return false; @@ -152,8 +149,19 @@ void ExpandACCPseudo::expandStore(MachineBasicBlock &MBB, Iter I, TII.storeRegToStack(MBB, I, VR1, true, FI, RC, &RegInfo, RegSize); } -void ExpandACCPseudo::expandCopy(MachineBasicBlock &MBB, Iter I, - unsigned RegSize) { +bool ExpandACCPseudo::expandCopy(MachineBasicBlock &MBB, Iter I) { + unsigned Dst = I->getOperand(0).getReg(), Src = I->getOperand(1).getReg(); + unsigned RegSize; + + if (Mips::ACRegsDSPRegClass.contains(Dst) && + Mips::ACRegsDSPRegClass.contains(Src)) + RegSize = 4; + else if (Mips::ACRegs128RegClass.contains(Dst) && + Mips::ACRegs128RegClass.contains(Src)) + RegSize = 8; + else + return false; + // copy $vr0, src_lo // copy dst_lo, $vr0 // copy $vr1, src_hi @@ -162,7 +170,6 @@ void ExpandACCPseudo::expandCopy(MachineBasicBlock &MBB, Iter I, const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize); unsigned VR0 = MRI.createVirtualRegister(RC); unsigned VR1 = MRI.createVirtualRegister(RC); - unsigned Dst = I->getOperand(0).getReg(), Src = I->getOperand(1).getReg(); unsigned SrcKill = getKillRegState(I->getOperand(1).isKill()); unsigned DstLo = RegInfo.getSubReg(Dst, Mips::sub_lo); unsigned DstHi = RegInfo.getSubReg(Dst, Mips::sub_hi); @@ -176,6 +183,7 @@ void ExpandACCPseudo::expandCopy(MachineBasicBlock &MBB, Iter I, BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR1).addReg(SrcHi, SrcKill); BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstHi) .addReg(VR1, RegState::Kill); + return true; } unsigned MipsSEFrameLowering::ehDataReg(unsigned I) const { diff --git a/lib/Target/Mips/MipsSEInstrInfo.cpp b/lib/Target/Mips/MipsSEInstrInfo.cpp index ca0315ed9f..2e7048d26e 100644 --- a/lib/Target/Mips/MipsSEInstrInfo.cpp +++ b/lib/Target/Mips/MipsSEInstrInfo.cpp @@ -95,20 +95,28 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, Opc = Mips::CFC1; else if (Mips::FGR32RegClass.contains(SrcReg)) Opc = Mips::MFC1; - else if (SrcReg == Mips::HI) + else if (Mips::HIRegsRegClass.contains(SrcReg)) Opc = Mips::MFHI, SrcReg = 0; - else if (SrcReg == Mips::LO) + else if (Mips::LORegsRegClass.contains(SrcReg)) Opc = Mips::MFLO, SrcReg = 0; + else if (Mips::HIRegsDSPRegClass.contains(SrcReg)) + Opc = Mips::MFHI_DSP; + else if (Mips::LORegsDSPRegClass.contains(SrcReg)) + Opc = Mips::MFLO_DSP; } else if (Mips::CPURegsRegClass.contains(SrcReg)) { // Copy from CPU Reg. if (Mips::CCRRegClass.contains(DestReg)) Opc = Mips::CTC1; else if (Mips::FGR32RegClass.contains(DestReg)) Opc = Mips::MTC1; - else if (DestReg == Mips::HI) + else if (Mips::HIRegsRegClass.contains(DestReg)) Opc = Mips::MTHI, DestReg = 0; - else if (DestReg == Mips::LO) + else if (Mips::LORegsRegClass.contains(DestReg)) Opc = Mips::MTLO, DestReg = 0; + else if (Mips::HIRegsDSPRegClass.contains(DestReg)) + Opc = Mips::MTHI_DSP; + else if (Mips::LORegsDSPRegClass.contains(DestReg)) + Opc = Mips::MTLO_DSP; } else if (Mips::FGR32RegClass.contains(DestReg, SrcReg)) Opc = Mips::FMOV_S; @@ -121,27 +129,21 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, else if (Mips::CPU64RegsRegClass.contains(DestReg)) { // Copy to CPU64 Reg. if (Mips::CPU64RegsRegClass.contains(SrcReg)) Opc = Mips::OR64, ZeroReg = Mips::ZERO_64; - else if (SrcReg == Mips::HI64) + else if (Mips::HIRegs64RegClass.contains(SrcReg)) Opc = Mips::MFHI64, SrcReg = 0; - else if (SrcReg == Mips::LO64) + else if (Mips::LORegs64RegClass.contains(SrcReg)) Opc = Mips::MFLO64, SrcReg = 0; else if (Mips::FGR64RegClass.contains(SrcReg)) Opc = Mips::DMFC1; } else if (Mips::CPU64RegsRegClass.contains(SrcReg)) { // Copy from CPU64 Reg. - if (DestReg == Mips::HI64) + if (Mips::HIRegs64RegClass.contains(DestReg)) Opc = Mips::MTHI64, DestReg = 0; - else if (DestReg == Mips::LO64) + else if (Mips::LORegs64RegClass.contains(DestReg)) Opc = Mips::MTLO64, DestReg = 0; else if (Mips::FGR64RegClass.contains(DestReg)) Opc = Mips::DMTC1; } - else if (Mips::ACRegsRegClass.contains(DestReg, SrcReg)) - Opc = Mips::COPY_AC64; - else if (Mips::ACRegsDSPRegClass.contains(DestReg, SrcReg)) - Opc = Mips::COPY_AC_DSP; - else if (Mips::ACRegs128RegClass.contains(DestReg, SrcReg)) - Opc = Mips::COPY_AC128; assert(Opc && "Cannot copy registers"); diff --git a/test/CodeGen/Mips/spill-copy-acreg.ll b/test/CodeGen/Mips/spill-copy-acreg.ll new file mode 100644 index 0000000000..2ca031a104 --- /dev/null +++ b/test/CodeGen/Mips/spill-copy-acreg.ll @@ -0,0 +1,21 @@ +; RUN: llc -march=mipsel -mattr=+dsp < %s + +@g1 = common global i64 0, align 8 +@g2 = common global i64 0, align 8 +@g3 = common global i64 0, align 8 + +define i64 @test_acreg_copy(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { +entry: + %0 = load i64* @g1, align 8 + %1 = tail call i64 @llvm.mips.maddu(i64 %0, i32 %a0, i32 %a1) + %2 = tail call i64 @llvm.mips.maddu(i64 %0, i32 %a2, i32 %a3) + store i64 %1, i64* @g1, align 8 + store i64 %2, i64* @g2, align 8 + tail call void @foo1() + store i64 %2, i64* @g3, align 8 + ret i64 %1 +} + +declare i64 @llvm.mips.maddu(i64, i32, i32) + +declare void @foo1() |