diff options
author | Jack Carter <jack.carter@imgtec.com> | 2013-08-13 20:19:16 +0000 |
---|---|---|
committer | Jack Carter <jack.carter@imgtec.com> | 2013-08-13 20:19:16 +0000 |
commit | da0860f78e6e43aca3333a7815b2f9bc0f8dfac0 (patch) | |
tree | 9422b762ea978f84ac29d51a4af1e92be2a612b0 /lib/Target/Mips/MipsSEISelDAGToDAG.cpp | |
parent | 13e26da155d245e0d1e55fb8dc9f586426112fc2 (diff) | |
download | llvm-da0860f78e6e43aca3333a7815b2f9bc0f8dfac0.tar.gz llvm-da0860f78e6e43aca3333a7815b2f9bc0f8dfac0.tar.bz2 llvm-da0860f78e6e43aca3333a7815b2f9bc0f8dfac0.tar.xz |
[Mips] Support for unaligned load/store microMips instructions
This includes instructions lwl, lwr, swl and swr.
Patch by Zoran Jovnovic
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188312 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Mips/MipsSEISelDAGToDAG.cpp')
-rw-r--r-- | lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index 37fbc3d95a..203196e626 100644 --- a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -314,6 +314,37 @@ bool MipsSEDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base, selectAddrDefault(Addr, Base, Offset); } +/// Used on microMIPS Load/Store unaligned instructions (12-bit offset) +bool MipsSEDAGToDAGISel::selectAddrRegImm12(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + EVT ValTy = Addr.getValueType(); + + // Addresses of the form FI+const or FI|const + if (CurDAG->isBaseWithConstantOffset(Addr)) { + ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)); + if (isInt<12>(CN->getSExtValue())) { + + // If the first operand is a FI, get the TargetFI Node + if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode> + (Addr.getOperand(0))) + Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); + else + Base = Addr.getOperand(0); + + Offset = CurDAG->getTargetConstant(CN->getZExtValue(), ValTy); + return true; + } + } + + return false; +} + +bool MipsSEDAGToDAGISel::selectIntAddrMM(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + return selectAddrRegImm12(Addr, Base, Offset) || + selectAddrDefault(Addr, Base, Offset); +} + std::pair<bool, SDNode*> MipsSEDAGToDAGISel::selectNode(SDNode *Node) { unsigned Opcode = Node->getOpcode(); SDLoc DL(Node); |