Index: /home/seurer/llvm/llvm-oneoff/lib/Target/PowerPC/PPCFastISel.cpp =================================================================== --- /home/seurer/llvm/llvm-oneoff/lib/Target/PowerPC/PPCFastISel.cpp +++ /home/seurer/llvm/llvm-oneoff/lib/Target/PowerPC/PPCFastISel.cpp @@ -139,6 +139,10 @@ private: bool isTypeLegal(Type *Ty, MVT &VT); bool isLoadTypeLegal(Type *Ty, MVT &VT); + bool isVSXRegister(unsigned Register) const { + return ((Register != 0) && + (MRI.getRegClass(Register)->getID() == PPC::VSFRCRegClassID)); + } bool PPCEmitCmp(const Value *Src1Value, const Value *Src2Value, bool isZExt, unsigned DestReg); bool PPCEmitLoad(MVT VT, unsigned &ResultReg, Address &Addr, @@ -445,6 +449,7 @@ &PPC::GPRC_and_GPRC_NOR0RegClass))))); bool Is32BitInt = UseRC->hasSuperClassEq(&PPC::GPRCRegClass); + bool IsVSX = isVSXRegister(ResultReg); switch (VT.SimpleTy) { default: // e.g., vector types not handled @@ -482,6 +487,12 @@ // the indexed form. Also handle stack pointers with special needs. unsigned IndexReg = 0; PPCSimplifyAddress(Addr, VT, UseOffset, IndexReg); + // If this is a potential VSX load with an offset of 0 a VSX indexed load can be used + if (IsVSX && (Opc == PPC::LFD) && + (Addr.BaseType != Address::FrameIndexBase) && UseOffset && (Addr.Offset == 0)) { + UseOffset = false; + assert(Addr.Base.Reg == 0 && "a non-zero base register was unexpectedly encountered"); + } if (ResultReg == 0) ResultReg = createResultReg(UseRC); @@ -489,6 +500,8 @@ // in range, as otherwise PPCSimplifyAddress would have converted it // into a RegBase. if (Addr.BaseType == Address::FrameIndexBase) { + // VSX only provides an indexed load + if (IsVSX && Opc==PPC::LFD) return false; MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand( @@ -501,6 +514,8 @@ // Base reg with offset in range. } else if (UseOffset) { + // VSX only provides an indexed load + if (IsVSX && Opc==PPC::LFD) return false; BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg) .addImm(Addr.Offset).addReg(Addr.Base.Reg); @@ -524,7 +539,7 @@ case PPC::LWA_32: Opc = PPC::LWAX_32; break; case PPC::LD: Opc = PPC::LDX; break; case PPC::LFS: Opc = PPC::LFSX; break; - case PPC::LFD: Opc = PPC::LFDX; break; + case PPC::LFD: Opc = IsVSX ? PPC::LXSDX : PPC::LFDX; break; } BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg) .addReg(Addr.Base.Reg).addReg(IndexReg); @@ -571,6 +586,7 @@ const TargetRegisterClass *RC = MRI.getRegClass(SrcReg); bool Is32BitInt = RC->hasSuperClassEq(&PPC::GPRCRegClass); + bool IsVSX = isVSXRegister(SrcReg); switch (VT.SimpleTy) { default: // e.g., vector types not handled @@ -601,11 +617,20 @@ // the indexed form. Also handle stack pointers with special needs. unsigned IndexReg = 0; PPCSimplifyAddress(Addr, VT, UseOffset, IndexReg); + // If this is a potential VSX store with an offset of 0 a VSX indexed store can be used + if (IsVSX && (Opc == PPC::STFD) && + (Addr.BaseType != Address::FrameIndexBase) && UseOffset && (Addr.Offset == 0)) { + UseOffset = false; + assert(Addr.Base.Reg == 0 && "a non-zero base register was unexpectedly encountered"); + } // Note: If we still have a frame index here, we know the offset is // in range, as otherwise PPCSimplifyAddress would have converted it // into a RegBase. if (Addr.BaseType == Address::FrameIndexBase) { + // VSX only provides an indexed store + if (IsVSX && Opc==PPC::STFD) return false; + MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand( MachinePointerInfo::getFixedStack(Addr.Base.FI, Addr.Offset), @@ -619,12 +644,15 @@ .addMemOperand(MMO); // Base reg with offset in range. - } else if (UseOffset) + } else if (UseOffset) { + // VSX only provides an indexed store + if (IsVSX && Opc==PPC::STFD) return false; + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc)) .addReg(SrcReg).addImm(Addr.Offset).addReg(Addr.Base.Reg); // Indexed form. - else { + } else { // Get the RR opcode corresponding to the RI one. FIXME: It would be // preferable to use the ImmToIdxMap from PPCRegisterInfo.cpp, but it // is hard to get at. @@ -638,7 +666,7 @@ case PPC::STW8: Opc = PPC::STWX8; break; case PPC::STD: Opc = PPC::STDX; break; case PPC::STFS: Opc = PPC::STFSX; break; - case PPC::STFD: Opc = PPC::STFDX; break; + case PPC::STFD: Opc = IsVSX ? PPC::STXSDX : PPC::STFDX; break; } BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc)) .addReg(SrcReg).addReg(Addr.Base.Reg).addReg(IndexReg);