aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@mips.com>2012-01-25 03:01:35 +0000
committerAkira Hatanaka <ahatanaka@mips.com>2012-01-25 03:01:35 +0000
commit57fa38225cfeded40a38770a2cc52e10a4e7268d (patch)
treecf4f75ebce9c25938d502f29b29d7cade4c080ad /lib/Target
parent1ab525e857463ff0ab702b50a97fb9c7811f0ac7 (diff)
downloadexternal_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')
-rw-r--r--lib/Target/Mips/Mips64InstrInfo.td31
-rw-r--r--lib/Target/Mips/MipsISelDAGToDAG.cpp42
2 files changed, 42 insertions, 31 deletions
diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td
index 56d2b42..1a57756 100644
--- a/lib/Target/Mips/Mips64InstrInfo.td
+++ b/lib/Target/Mips/Mips64InstrInfo.td
@@ -31,19 +31,6 @@ def Subtract32 : SDNodeXForm<imm, [{
// shamt must fit in 6 bits.
def immZExt6 : ImmLeaf<i32, [{return Imm == (Imm & 0x3f);}]>;
-// Is a 32-bit int.
-def immSExt32 : ImmLeaf<i64, [{return isInt<32>(Imm);}]>;
-
-// Transformation Function - get the higher 16 bits.
-def HIGHER : SDNodeXForm<imm, [{
- return getImm(N, (N->getZExtValue() >> 32) & 0xFFFF);
-}]>;
-
-// Transformation Function - get the highest 16 bits.
-def HIGHEST : SDNodeXForm<imm, [{
- return getImm(N, (N->getZExtValue() >> 48) & 0xFFFF);
-}]>;
-
//===----------------------------------------------------------------------===//
// Instructions specific format
//===----------------------------------------------------------------------===//
@@ -213,24 +200,6 @@ def SLL64_64 : FR<0x0, 0x00, (outs CPU64Regs:$rd), (ins CPU64Regs:$rt),
// Arbitrary patterns that map to one or more instructions
//===----------------------------------------------------------------------===//
-// Small immediates
-def : Pat<(i64 immSExt16:$in),
- (DADDiu ZERO_64, imm:$in)>;
-def : Pat<(i64 immZExt16:$in),
- (ORi64 ZERO_64, imm:$in)>;
-def : Pat<(i64 immLow16Zero:$in),
- (LUi64 (HI16 imm:$in))>;
-
-// 32-bit immediates
-def : Pat<(i64 immSExt32:$imm),
- (ORi64 (LUi64 (HI16 imm:$imm)), (LO16 imm:$imm))>;
-
-// Arbitrary immediates
-def : Pat<(i64 imm:$imm),
- (ORi64 (DSLL (ORi64 (DSLL (ORi64 (LUi64 (HIGHEST imm:$imm)),
- (HIGHER imm:$imm)), 16), (HI16 imm:$imm)), 16),
- (LO16 imm:$imm))>;
-
// extended loads
let Predicates = [NotN64] in {
def : Pat<(i64 (extloadi1 addr:$src)), (LB64 addr:$src)>;
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;