diff options
Diffstat (limited to 'contrib/llvm/lib/Target/ARC/ARCExpandPseudos.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/ARC/ARCExpandPseudos.cpp | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/contrib/llvm/lib/Target/ARC/ARCExpandPseudos.cpp b/contrib/llvm/lib/Target/ARC/ARCExpandPseudos.cpp new file mode 100644 index 000000000000..3177735c0529 --- /dev/null +++ b/contrib/llvm/lib/Target/ARC/ARCExpandPseudos.cpp @@ -0,0 +1,103 @@ +//===- ARCExpandPseudosPass - ARC expand pseudo loads -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass expands stores with large offsets into an appropriate sequence. +//===----------------------------------------------------------------------===// + +#include "ARC.h" +#include "ARCInstrInfo.h" +#include "ARCRegisterInfo.h" +#include "ARCSubtarget.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" + +using namespace llvm; + +#define DEBUG_TYPE "arc-expand-pseudos" + +namespace { + +class ARCExpandPseudos : public MachineFunctionPass { +public: + static char ID; + ARCExpandPseudos() : MachineFunctionPass(ID) {} + + bool runOnMachineFunction(MachineFunction &Fn) override; + + StringRef getPassName() const override { return "ARC Expand Pseudos"; } + +private: + void ExpandStore(MachineFunction &, MachineBasicBlock::iterator); + + const ARCInstrInfo *TII; +}; + +char ARCExpandPseudos::ID = 0; + +} // end anonymous namespace + +static unsigned getMappedOp(unsigned PseudoOp) { + switch (PseudoOp) { + case ARC::ST_FAR: + return ARC::ST_rs9; + case ARC::STH_FAR: + return ARC::STH_rs9; + case ARC::STB_FAR: + return ARC::STB_rs9; + default: + llvm_unreachable("Unhandled pseudo op."); + } +} + +void ARCExpandPseudos::ExpandStore(MachineFunction &MF, + MachineBasicBlock::iterator SII) { + MachineInstr &SI = *SII; + unsigned AddrReg = MF.getRegInfo().createVirtualRegister(&ARC::GPR32RegClass); + unsigned AddOpc = + isUInt<6>(SI.getOperand(2).getImm()) ? ARC::ADD_rru6 : ARC::ADD_rrlimm; + BuildMI(*SI.getParent(), SI, SI.getDebugLoc(), TII->get(AddOpc), AddrReg) + .addReg(SI.getOperand(1).getReg()) + .addImm(SI.getOperand(2).getImm()); + BuildMI(*SI.getParent(), SI, SI.getDebugLoc(), + TII->get(getMappedOp(SI.getOpcode()))) + .addReg(SI.getOperand(0).getReg()) + .addReg(AddrReg) + .addImm(0); + SI.eraseFromParent(); +} + +bool ARCExpandPseudos::runOnMachineFunction(MachineFunction &MF) { + const ARCSubtarget *STI = &MF.getSubtarget<ARCSubtarget>(); + TII = STI->getInstrInfo(); + bool ExpandedStore = false; + for (auto &MBB : MF) { + MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); + while (MBBI != E) { + MachineBasicBlock::iterator NMBBI = std::next(MBBI); + switch (MBBI->getOpcode()) { + case ARC::ST_FAR: + case ARC::STH_FAR: + case ARC::STB_FAR: + ExpandStore(MF, MBBI); + ExpandedStore = true; + break; + default: + break; + } + MBBI = NMBBI; + } + } + return ExpandedStore; +} + +FunctionPass *llvm::createARCExpandPseudosPass() { + return new ARCExpandPseudos(); +} |