From: Akira Hatanaka Date: Wed, 25 Jan 2012 03:01:35 +0000 (+0000) Subject: Lower 64-bit immediates using MipsAnalyzeImmediate that has just been added. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=57fa38225cfeded40a38770a2cc52e10a4e7268d;p=oota-llvm.git 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 --- diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td index 56d2b42f642..1a577569dfd 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/lib/Target/Mips/Mips64InstrInfo.td @@ -31,19 +31,6 @@ def Subtract32 : SDNodeXForm; -// Is a 32-bit int. -def immSExt32 : ImmLeaf(Imm);}]>; - -// Transformation Function - get the higher 16 bits. -def HIGHER : SDNodeXFormgetZExtValue() >> 32) & 0xFFFF); -}]>; - -// Transformation Function - get the highest 16 bits. -def HIGHEST : SDNodeXFormgetZExtValue() >> 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 0194ed58912..bdb7ca48f52 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(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; diff --git a/test/CodeGen/Mips/mips64imm.ll b/test/CodeGen/Mips/mips64imm.ll index 8cec536c259..1fc8636c480 100644 --- a/test/CodeGen/Mips/mips64imm.ll +++ b/test/CodeGen/Mips/mips64imm.ll @@ -12,7 +12,7 @@ define i64 @foo3() nounwind readnone { entry: ; CHECK: foo3 ; CHECK: lui $[[R0:[0-9]+]], 4660 -; CHECK: ori ${{[0-9]+}}, $[[R0]], 22136 +; CHECK: daddiu ${{[0-9]+}}, $[[R0]], 22136 ret i64 305419896 } @@ -33,11 +33,20 @@ entry: define i64 @foo9() nounwind readnone { entry: ; CHECK: foo9 -; CHECK: lui $[[R0:[0-9]+]], 4660 -; CHECK: ori $[[R1:[0-9]+]], $[[R0]], 22136 -; CHECK: dsll $[[R2:[0-9]+]], $[[R1]], 16 -; CHECK: ori $[[R3:[0-9]+]], $[[R2]], 36882 -; CHECK: dsll $[[R4:[0-9]+]], $[[R3]], 16 -; CHECK: ori ${{[0-9]+}}, $[[R4]], 13398 +; CHECK: lui $[[R0:[0-9]+]], 583 +; CHECK: daddiu $[[R1:[0-9]+]], $[[R0]], -30001 +; CHECK: dsll $[[R2:[0-9]+]], $[[R1]], 18 +; CHECK: daddiu $[[R3:[0-9]+]], $[[R2]], 18441 +; CHECK: dsll $[[R4:[0-9]+]], $[[R3]], 17 +; CHECK: daddiu ${{[0-9]+}}, $[[R4]], 13398 ret i64 1311768467284833366 } + +define i64 @foo10() nounwind readnone { +entry: +; CHECK: foo10 +; CHECK: lui $[[R0:[0-9]+]], 34661 +; CHECK: daddiu ${{[0-9]+}}, $[[R0]], 17185 + ret i64 -8690466096928522240 +} +