summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@mips.com>2013-04-30 23:22:09 +0000
committerAkira Hatanaka <ahatanaka@mips.com>2013-04-30 23:22:09 +0000
commitc147c1b994e1187cb471cdb7ee05f5f875eff4e0 (patch)
treecb8374bc211e2f08f526dd29e1e24c1ca05161db
parent3484da9479a4daff3efc7febe004e1f4d69b3b4a (diff)
downloadllvm-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.td4
-rw-r--r--lib/Target/Mips/MipsDSPInstrInfo.td4
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp4
-rw-r--r--lib/Target/Mips/MipsInstrInfo.td4
-rw-r--r--lib/Target/Mips/MipsRegisterInfo.td6
-rw-r--r--lib/Target/Mips/MipsSEFrameLowering.cpp28
-rw-r--r--lib/Target/Mips/MipsSEInstrInfo.cpp30
-rw-r--r--test/CodeGen/Mips/spill-copy-acreg.ll21
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()