diff options
author | Akira Hatanaka <ahatanaka@mips.com> | 2011-12-05 21:26:34 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@mips.com> | 2011-12-05 21:26:34 +0000 |
commit | d6bc5237d8c961949fbc57dfa1a07f5833262388 (patch) | |
tree | 76df05e6f75e3b5840eb319b569c8ce282cabea1 | |
parent | cee46abc169226ba799c012d9f8c3bec52ccf90d (diff) | |
download | llvm-d6bc5237d8c961949fbc57dfa1a07f5833262388.tar.gz llvm-d6bc5237d8c961949fbc57dfa1a07f5833262388.tar.bz2 llvm-d6bc5237d8c961949fbc57dfa1a07f5833262388.tar.xz |
Add definitions of 64-bit extract and insert instrucions and make
PerformANDCombine and PerformOrCombine aware of them. Test cases are included
too.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145853 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/Mips/Mips64InstrInfo.td | 3 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 26 | ||||
-rw-r--r-- | test/CodeGen/Mips/mips64extins.ll | 55 |
3 files changed, 72 insertions, 12 deletions
diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td index b0fb4fa184..d5676120ba 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/lib/Target/Mips/Mips64InstrInfo.td @@ -206,6 +206,9 @@ let Uses = [SP_64] in def DynAlloc64 : EffectiveAddress<"daddiu\t$rt, $addr", CPU64Regs, mem_ea_64>, Requires<[IsN64]>; +def DEXT : ExtBase<3, "dext", CPU64Regs>; +def DINS : InsBase<7, "dins", CPU64Regs>; + //===----------------------------------------------------------------------===// // Arbitrary patterns that map to one or more instructions //===----------------------------------------------------------------------===// diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 205116918e..272b8c57f2 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -40,11 +40,11 @@ using namespace llvm; // mask (Pos), and return true. // For example, if I is 0x003ff800, (Pos, Size) = (11, 11). static bool IsShiftedMask(uint64_t I, uint64_t &Pos, uint64_t &Size) { - if (!isUInt<32>(I) || !isShiftedMask_32(I)) + if (!isShiftedMask_64(I)) return false; - Size = CountPopulation_32(I); - Pos = CountTrailingZeros_32(I); + Size = CountPopulation_64(I); + Pos = CountTrailingZeros_64(I); return true; } @@ -556,20 +556,20 @@ static SDValue PerformANDCombine(SDNode *N, SelectionDAG& DAG, return SDValue(); SDValue ShiftRight = N->getOperand(0), Mask = N->getOperand(1); - + unsigned ShiftRightOpc = ShiftRight.getOpcode(); + // Op's first operand must be a shift right. - if (ShiftRight.getOpcode() != ISD::SRA && ShiftRight.getOpcode() != ISD::SRL) + if (ShiftRightOpc != ISD::SRA && ShiftRightOpc != ISD::SRL) return SDValue(); // The second operand of the shift must be an immediate. - uint64_t Pos; ConstantSDNode *CN; if (!(CN = dyn_cast<ConstantSDNode>(ShiftRight.getOperand(1)))) return SDValue(); - Pos = CN->getZExtValue(); - + uint64_t Pos = CN->getZExtValue(); uint64_t SMPos, SMSize; + // Op's second operand must be a shifted mask. if (!(CN = dyn_cast<ConstantSDNode>(Mask)) || !IsShiftedMask(CN->getZExtValue(), SMPos, SMSize)) @@ -577,10 +577,11 @@ static SDValue PerformANDCombine(SDNode *N, SelectionDAG& DAG, // Return if the shifted mask does not start at bit 0 or the sum of its size // and Pos exceeds the word's size. - if (SMPos != 0 || Pos + SMSize > 32) + EVT ValTy = N->getValueType(0); + if (SMPos != 0 || Pos + SMSize > ValTy.getSizeInBits()) return SDValue(); - return DAG.getNode(MipsISD::Ext, N->getDebugLoc(), MVT::i32, + return DAG.getNode(MipsISD::Ext, N->getDebugLoc(), ValTy, ShiftRight.getOperand(0), DAG.getConstant(Pos, MVT::i32), DAG.getConstant(SMSize, MVT::i32)); @@ -631,10 +632,11 @@ static SDValue PerformORCombine(SDNode *N, SelectionDAG& DAG, // Return if the shift amount and the first bit position of mask are not the // same. - if (Shamt != SMPos0) + EVT ValTy = N->getValueType(0); + if ((Shamt != SMPos0) || (SMPos0 + SMSize0 > ValTy.getSizeInBits())) return SDValue(); - return DAG.getNode(MipsISD::Ins, N->getDebugLoc(), MVT::i32, + return DAG.getNode(MipsISD::Ins, N->getDebugLoc(), ValTy, Shl.getOperand(0), DAG.getConstant(SMPos0, MVT::i32), DAG.getConstant(SMSize0, MVT::i32), diff --git a/test/CodeGen/Mips/mips64extins.ll b/test/CodeGen/Mips/mips64extins.ll new file mode 100644 index 0000000000..14f92ca869 --- /dev/null +++ b/test/CodeGen/Mips/mips64extins.ll @@ -0,0 +1,55 @@ +; RUN: llc < %s -march=mips64el -mcpu=mips64r2 -mattr=n64 | FileCheck %s + +define i64 @dext(i64 %i) nounwind readnone { +entry: +; CHECK: dext ${{[0-9]+}}, ${{[0-9]+}}, 5, 10 + %shr = lshr i64 %i, 5 + %and = and i64 %shr, 1023 + ret i64 %and +} + +define i64 @dextm(i64 %i) nounwind readnone { +entry: +; CHECK: dext ${{[0-9]+}}, ${{[0-9]+}}, 5, 34 + %shr = lshr i64 %i, 5 + %and = and i64 %shr, 17179869183 + ret i64 %and +} + +define i64 @dextu(i64 %i) nounwind readnone { +entry: +; CHECK: dext ${{[0-9]+}}, ${{[0-9]+}}, 34, 6 + %shr = lshr i64 %i, 34 + %and = and i64 %shr, 63 + ret i64 %and +} + +define i64 @dins(i64 %i, i64 %j) nounwind readnone { +entry: +; CHECK: dins ${{[0-9]+}}, ${{[0-9]+}}, 8, 10 + %shl2 = shl i64 %j, 8 + %and = and i64 %shl2, 261888 + %and3 = and i64 %i, -261889 + %or = or i64 %and3, %and + ret i64 %or +} + +define i64 @dinsm(i64 %i, i64 %j) nounwind readnone { +entry: +; CHECK: dins ${{[0-9]+}}, ${{[0-9]+}}, 10, 33 + %shl4 = shl i64 %j, 10 + %and = and i64 %shl4, 8796093021184 + %and5 = and i64 %i, -8796093021185 + %or = or i64 %and5, %and + ret i64 %or +} + +define i64 @dinsu(i64 %i, i64 %j) nounwind readnone { +entry: +; CHECK: dins ${{[0-9]+}}, ${{[0-9]+}}, 40, 13 + %shl4 = shl i64 %j, 40 + %and = and i64 %shl4, 9006099743113216 + %and5 = and i64 %i, -9006099743113217 + %or = or i64 %and5, %and + ret i64 %or +} |