From baf31088f1472f48ea5ae81f0b93636cc44ca444 Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Sat, 8 Aug 2009 13:35:48 +0000 Subject: [PATCH] Use VLDM / VSTM to spill/reload 128-bit Neon registers git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78468 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 17 +++++++++++++---- lib/Target/ARM/ARMISelDAGToDAG.cpp | 8 ++++++++ lib/Target/ARM/ARMInstrFormats.td | 4 ++++ lib/Target/ARM/ARMInstrInfo.td | 2 +- lib/Target/ARM/ARMInstrNEON.td | 9 ++++----- 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index ae6f916f42b..c179d8334df 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -655,11 +655,15 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTD)) .addReg(SrcReg, getKillRegState(isKill)) .addFrameIndex(FI).addImm(0)); - } else { - assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); + } else if (RC == ARM::SPRRegisterClass) { AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTS)) .addReg(SrcReg, getKillRegState(isKill)) .addFrameIndex(FI).addImm(0)); + } else { + assert(RC == ARM::QPRRegisterClass && "Unknown regclass!"); + // FIXME: Neon instructions should support predicates + BuildMI(MBB, I, DL, get(ARM::VSTRQ)).addReg(SrcReg, getKillRegState(isKill)) + .addFrameIndex(FI).addImm(0); } } @@ -676,10 +680,13 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, } else if (RC == ARM::DPRRegisterClass || RC == ARM::DPR_VFP2RegisterClass) { AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDD), DestReg) .addFrameIndex(FI).addImm(0)); - } else { - assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); + } else if (RC == ARM::SPRRegisterClass) { AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDS), DestReg) .addFrameIndex(FI).addImm(0)); + } else { + assert(RC == ARM::QPRRegisterClass && "Unknown regclass!"); + // FIXME: Neon instructions should support predicates + BuildMI(MBB, I, DL, get(ARM::VLDRQ), DestReg).addFrameIndex(FI).addImm(0); } } @@ -928,6 +935,8 @@ int llvm::rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx, NumBits = 8; break; } + case ARMII::AddrMode4: + break; case ARMII::AddrMode5: { ImmIdx = FrameRegIdx+1; InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm()); diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index 8e73a43b2d9..3304900c9f2 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -78,6 +78,8 @@ public: SDValue &Offset, SDValue &Opc); bool SelectAddrMode3Offset(SDValue Op, SDValue N, SDValue &Offset, SDValue &Opc); + bool SelectAddrMode4(SDValue Op, SDValue N, SDValue &Addr, + SDValue &Mode); bool SelectAddrMode5(SDValue Op, SDValue N, SDValue &Base, SDValue &Offset); bool SelectAddrMode6(SDValue Op, SDValue N, SDValue &Addr, SDValue &Update, @@ -383,6 +385,12 @@ bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDValue Op, SDValue N, return true; } +bool ARMDAGToDAGISel::SelectAddrMode4(SDValue Op, SDValue N, + SDValue &Addr, SDValue &Mode) { + Addr = N; + Mode = CurDAG->getTargetConstant(0, MVT::i32); + return true; +} bool ARMDAGToDAGISel::SelectAddrMode5(SDValue Op, SDValue N, SDValue &Base, SDValue &Offset) { diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index fb84d523fa8..5bc7212881c 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -1199,6 +1199,10 @@ class NI pattern> : NeonI { } +class NI4 pattern> + : NeonI { +} + class NLdSt pattern> : NeonI { diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 68dac9f4951..599ea1a801f 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -298,7 +298,7 @@ def am3offset : Operand, // addrmode4 := reg, // def addrmode4 : Operand, - ComplexPattern { + ComplexPattern { let PrintMethod = "printAddrMode4Operand"; let MIOperandInfo = (ops GPR, i32imm); } diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index afa42d57ec2..36cd094ee83 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -138,10 +138,10 @@ def VLDMS : NI<(outs), */ // Use vldmia to load a Q register as a D register pair. -def VLDRQ : NI<(outs QPR:$dst), (ins GPR:$addr), +def VLDRQ : NI4<(outs QPR:$dst), (ins addrmode4:$addr), NoItinerary, "vldmia $addr, ${dst:dregpair}", - [(set QPR:$dst, (v2f64 (load GPR:$addr)))]> { + [(set QPR:$dst, (v2f64 (load addrmode4:$addr)))]> { let Inst{27-25} = 0b110; let Inst{24} = 0; // P bit let Inst{23} = 1; // U bit @@ -150,10 +150,10 @@ def VLDRQ : NI<(outs QPR:$dst), (ins GPR:$addr), } // Use vstmia to store a Q register as a D register pair. -def VSTRQ : NI<(outs), (ins QPR:$src, GPR:$addr), +def VSTRQ : NI4<(outs), (ins QPR:$src, addrmode4:$addr), NoItinerary, "vstmia $addr, ${src:dregpair}", - [(store (v2f64 QPR:$src), GPR:$addr)]> { + [(store (v2f64 QPR:$src), addrmode4:$addr)]> { let Inst{27-25} = 0b110; let Inst{24} = 0; // P bit let Inst{23} = 1; // U bit @@ -161,7 +161,6 @@ def VSTRQ : NI<(outs), (ins QPR:$src, GPR:$addr), let Inst{11-9} = 0b101; } - // VLD1 : Vector Load (multiple single elements) class VLD1D : NLdSt<(outs DPR:$dst), (ins addrmode6:$addr), -- 2.34.1