diff options
Diffstat (limited to 'contrib/llvm/lib/Target/BPF/BPFInstrInfo.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/BPF/BPFInstrInfo.cpp | 93 |
1 files changed, 91 insertions, 2 deletions
diff --git a/contrib/llvm/lib/Target/BPF/BPFInstrInfo.cpp b/contrib/llvm/lib/Target/BPF/BPFInstrInfo.cpp index 5351cfa95020..4d47debdaa74 100644 --- a/contrib/llvm/lib/Target/BPF/BPFInstrInfo.cpp +++ b/contrib/llvm/lib/Target/BPF/BPFInstrInfo.cpp @@ -36,10 +36,92 @@ void BPFInstrInfo::copyPhysReg(MachineBasicBlock &MBB, if (BPF::GPRRegClass.contains(DestReg, SrcReg)) BuildMI(MBB, I, DL, get(BPF::MOV_rr), DestReg) .addReg(SrcReg, getKillRegState(KillSrc)); + else if (BPF::GPR32RegClass.contains(DestReg, SrcReg)) + BuildMI(MBB, I, DL, get(BPF::MOV_rr_32), DestReg) + .addReg(SrcReg, getKillRegState(KillSrc)); else llvm_unreachable("Impossible reg-to-reg copy"); } +void BPFInstrInfo::expandMEMCPY(MachineBasicBlock::iterator MI) const { + unsigned DstReg = MI->getOperand(0).getReg(); + unsigned SrcReg = MI->getOperand(1).getReg(); + uint64_t CopyLen = MI->getOperand(2).getImm(); + uint64_t Alignment = MI->getOperand(3).getImm(); + unsigned ScratchReg = MI->getOperand(4).getReg(); + MachineBasicBlock *BB = MI->getParent(); + DebugLoc dl = MI->getDebugLoc(); + unsigned LdOpc, StOpc; + + switch (Alignment) { + case 1: + LdOpc = BPF::LDB; + StOpc = BPF::STB; + break; + case 2: + LdOpc = BPF::LDH; + StOpc = BPF::STH; + break; + case 4: + LdOpc = BPF::LDW; + StOpc = BPF::STW; + break; + case 8: + LdOpc = BPF::LDD; + StOpc = BPF::STD; + break; + default: + llvm_unreachable("unsupported memcpy alignment"); + } + + unsigned IterationNum = CopyLen >> Log2_64(Alignment); + for(unsigned I = 0; I < IterationNum; ++I) { + BuildMI(*BB, MI, dl, get(LdOpc)) + .addReg(ScratchReg, RegState::Define).addReg(SrcReg) + .addImm(I * Alignment); + BuildMI(*BB, MI, dl, get(StOpc)) + .addReg(ScratchReg, RegState::Kill).addReg(DstReg) + .addImm(I * Alignment); + } + + unsigned BytesLeft = CopyLen & (Alignment - 1); + unsigned Offset = IterationNum * Alignment; + bool Hanging4Byte = BytesLeft & 0x4; + bool Hanging2Byte = BytesLeft & 0x2; + bool Hanging1Byte = BytesLeft & 0x1; + if (Hanging4Byte) { + BuildMI(*BB, MI, dl, get(BPF::LDW)) + .addReg(ScratchReg, RegState::Define).addReg(SrcReg).addImm(Offset); + BuildMI(*BB, MI, dl, get(BPF::STW)) + .addReg(ScratchReg, RegState::Kill).addReg(DstReg).addImm(Offset); + Offset += 4; + } + if (Hanging2Byte) { + BuildMI(*BB, MI, dl, get(BPF::LDH)) + .addReg(ScratchReg, RegState::Define).addReg(SrcReg).addImm(Offset); + BuildMI(*BB, MI, dl, get(BPF::STH)) + .addReg(ScratchReg, RegState::Kill).addReg(DstReg).addImm(Offset); + Offset += 2; + } + if (Hanging1Byte) { + BuildMI(*BB, MI, dl, get(BPF::LDB)) + .addReg(ScratchReg, RegState::Define).addReg(SrcReg).addImm(Offset); + BuildMI(*BB, MI, dl, get(BPF::STB)) + .addReg(ScratchReg, RegState::Kill).addReg(DstReg).addImm(Offset); + } + + BB->erase(MI); +} + +bool BPFInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { + if (MI.getOpcode() == BPF::MEMCPY) { + expandMEMCPY(MI); + return true; + } + + return false; +} + void BPFInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned SrcReg, bool IsKill, int FI, @@ -54,6 +136,11 @@ void BPFInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, .addReg(SrcReg, getKillRegState(IsKill)) .addFrameIndex(FI) .addImm(0); + else if (RC == &BPF::GPR32RegClass) + BuildMI(MBB, I, DL, get(BPF::STW32)) + .addReg(SrcReg, getKillRegState(IsKill)) + .addFrameIndex(FI) + .addImm(0); else llvm_unreachable("Can't store this register to stack slot"); } @@ -69,6 +156,8 @@ void BPFInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, if (RC == &BPF::GPRRegClass) BuildMI(MBB, I, DL, get(BPF::LDD), DestReg).addFrameIndex(FI).addImm(0); + else if (RC == &BPF::GPR32RegClass) + BuildMI(MBB, I, DL, get(BPF::LDW32), DestReg).addFrameIndex(FI).addImm(0); else llvm_unreachable("Can't load this register from stack slot"); } @@ -83,7 +172,7 @@ bool BPFInstrInfo::analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock::iterator I = MBB.end(); while (I != MBB.begin()) { --I; - if (I->isDebugValue()) + if (I->isDebugInstr()) continue; // Working from the bottom, when we see a non-terminator @@ -158,7 +247,7 @@ unsigned BPFInstrInfo::removeBranch(MachineBasicBlock &MBB, while (I != MBB.begin()) { --I; - if (I->isDebugValue()) + if (I->isDebugInstr()) continue; if (I->getOpcode() != BPF::JMP) break; |