diff options
author | Akira Hatanaka <ahatanaka@mips.com> | 2012-01-25 03:01:35 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@mips.com> | 2012-01-25 03:01:35 +0000 |
commit | 57fa38225cfeded40a38770a2cc52e10a4e7268d (patch) | |
tree | cf4f75ebce9c25938d502f29b29d7cade4c080ad /lib/Target/Mips/MipsISelDAGToDAG.cpp | |
parent | 1ab525e857463ff0ab702b50a97fb9c7811f0ac7 (diff) | |
download | external_llvm-57fa38225cfeded40a38770a2cc52e10a4e7268d.zip external_llvm-57fa38225cfeded40a38770a2cc52e10a4e7268d.tar.gz external_llvm-57fa38225cfeded40a38770a2cc52e10a4e7268d.tar.bz2 |
Lower 64-bit immediates using MipsAnalyzeImmediate that has just been added.
Add a test case to show fewer instructions are needed to load an immediate
with the new way of loading immediates.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148908 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Mips/MipsISelDAGToDAG.cpp')
-rw-r--r-- | lib/Target/Mips/MipsISelDAGToDAG.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp index 0194ed5..bdb7ca4 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -13,6 +13,7 @@ #define DEBUG_TYPE "mips-isel" #include "Mips.h" +#include "MipsAnalyzeImmediate.h" #include "MipsMachineFunction.h" #include "MipsRegisterInfo.h" #include "MipsSubtarget.h" @@ -317,6 +318,47 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) { break; } + case ISD::Constant: { + const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Node); + unsigned Size = CN->getValueSizeInBits(0); + + if (Size == 32) + break; + + MipsAnalyzeImmediate AnalyzeImm; + int64_t Imm = CN->getSExtValue(); + + const MipsAnalyzeImmediate::InstSeq &Seq = + AnalyzeImm.Analyze(Imm, Size, false); + + MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin(); + DebugLoc DL = CN->getDebugLoc(); + SDNode *RegOpnd; + SDValue ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd), + MVT::i64); + + // The first instruction can be a LUi which is different from other + // instructions (ADDiu, ORI and SLL) in that it does not have a register + // operand. + if (Inst->Opc == Mips::LUi64) + RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, ImmOpnd); + else + RegOpnd = + CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, + CurDAG->getRegister(Mips::ZERO_64, MVT::i64), + ImmOpnd); + + // The remaining instructions in the sequence are handled here. + for (++Inst; Inst != Seq.end(); ++Inst) { + ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd), + MVT::i64); + RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, + SDValue(RegOpnd, 0), ImmOpnd); + } + + return RegOpnd; + } + case MipsISD::ThreadPointer: { EVT PtrVT = TLI.getPointerTy(); unsigned RdhwrOpc, SrcReg, DestReg; |