[llvm-commits] [llvm] r137804 - in /llvm/trunk: lib/Target/Mips/MipsISelLowering.cpp lib/Target/Mips/MipsISelLowering.h lib/Target/Mips/MipsInstrFormats.td lib/Target/Mips/MipsInstrInfo.td test/CodeGen/Mips/extins.ll

Bruno Cardoso Lopes bruno.cardoso at gmail.com
Tue Aug 16 19:29:18 PDT 2011


Hi Akira,

This is more appropriate as a target specific DAGCombine than regular
lowering. Can you please move the logic to do that?
Also, I don't see how ExtIns is different from FR class. Can you
change it to inherit from it instead? This would be better once we
have MC based object code emission, mips is simple enough that we can
emit the binaries easily based only on the basic formats.

Thanks

On Tue, Aug 16, 2011 at 7:05 PM, Akira Hatanaka <ahatanak at gmail.com> wrote:
> Author: ahatanak
> Date: Tue Aug 16 21:05:42 2011
> New Revision: 137804
>
> URL: http://llvm.org/viewvc/llvm-project?rev=137804&view=rev
> Log:
> Add support for ext and ins.
>
> Added:
>    llvm/trunk/test/CodeGen/Mips/extins.ll
> Modified:
>    llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
>    llvm/trunk/lib/Target/Mips/MipsISelLowering.h
>    llvm/trunk/lib/Target/Mips/MipsInstrFormats.td
>    llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
>
> Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=137804&r1=137803&r2=137804&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Tue Aug 16 21:05:42 2011
> @@ -35,6 +35,24 @@
>  #include "llvm/Support/ErrorHandling.h"
>  using namespace llvm;
>
> +namespace {
> +  // If I is a shifted mask, set the size (Size) and the first bit of the
> +  // mask (Pos), and return true.
> +  bool IsShiftedMask(uint64_t I, unsigned SizeInBits, uint64_t &Pos,
> +                     uint64_t &Size) {
> +    assert(SizeInBits == 32 || SizeInBits == 64);
> +    bool Is32Bits = (SizeInBits == 32);
> +
> +    if ((Is32Bits == 32 && !isShiftedMask_32(I)) ||
> +        (!Is32Bits && !isShiftedMask_64(I)))
> +      return false;
> +
> +    Size = Is32Bits ? CountPopulation_32(I) : CountPopulation_64(I);
> +    Pos = Is32Bits ? CountTrailingZeros_32(I) : CountTrailingZeros_64(I);
> +    return true;
> +  }
> +}
> +
>  const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {
>   switch (Opcode) {
>   case MipsISD::JmpLink:           return "MipsISD::JmpLink";
> @@ -62,6 +80,8 @@
>   case MipsISD::WrapperPIC:        return "MipsISD::WrapperPIC";
>   case MipsISD::DynAlloc:          return "MipsISD::DynAlloc";
>   case MipsISD::Sync:              return "MipsISD::Sync";
> +  case MipsISD::Ext:               return "MipsISD::Ext";
> +  case MipsISD::Ins:               return "MipsISD::Ins";
>   default:                         return NULL;
>   }
>  }
> @@ -111,6 +131,8 @@
>   setOperationAction(ISD::BRCOND,             MVT::Other, Custom);
>   setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32,   Custom);
>   setOperationAction(ISD::VASTART,            MVT::Other, Custom);
> +  setOperationAction(ISD::AND,                MVT::i32,   Custom);
> +  setOperationAction(ISD::OR,                 MVT::i32,   Custom);
>
>   setOperationAction(ISD::SDIV, MVT::i32, Expand);
>   setOperationAction(ISD::SREM, MVT::i32, Expand);
> @@ -539,6 +561,8 @@
>     case ISD::FRAMEADDR:          return LowerFRAMEADDR(Op, DAG);
>     case ISD::MEMBARRIER:         return LowerMEMBARRIER(Op, DAG);
>     case ISD::ATOMIC_FENCE:       return LowerATOMIC_FENCE(Op, DAG);
> +    case ISD::AND:                return LowerAND(Op, DAG);
> +    case ISD::OR:                 return LowerOR(Op, DAG);
>   }
>   return SDValue();
>  }
> @@ -1556,6 +1580,98 @@
>                      DAG.getConstant(SType, MVT::i32));
>  }
>
> +SDValue MipsTargetLowering::LowerAND(SDValue Op, SelectionDAG& DAG) const {
> +  // Pattern match EXT.
> +  //  $dst = and ((sra or srl) $src , pos), (2**size - 1)
> +  //  => ext $dst, $src, size, pos
> +  if (!Subtarget->isMips32r2())
> +    return Op;
> +
> +  SDValue ShiftRight = Op.getOperand(0), Mask = Op.getOperand(1);
> +
> +  // Op's first operand must be a shift right.
> +  if (ShiftRight.getOpcode() != ISD::SRA && ShiftRight.getOpcode() != ISD::SRL)
> +    return Op;
> +
> +  // The second operand of the shift must be an immediate.
> +  uint64_t Pos;
> +  ConstantSDNode *CN;
> +  if (!(CN = dyn_cast<ConstantSDNode>(ShiftRight.getOperand(1))))
> +    return Op;
> +
> +  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(), 32, SMPos, SMSize))
> +    return Op;
> +
> +  // 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)
> +    return Op;
> +
> +  return DAG.getNode(MipsISD::Ext, Op.getDebugLoc(), MVT::i32,
> +                     ShiftRight.getOperand(0),
> +                     DAG.getConstant(SMSize, MVT::i32),
> +                     DAG.getConstant(Pos, MVT::i32));
> +}
> +
> +SDValue MipsTargetLowering::LowerOR(SDValue Op, SelectionDAG& DAG) const {
> +  // Pattern match INS.
> +  //  $dst = or (and $src1 , mask0), (and (shl $src, pos), mask1),
> +  //  where mask1 = (2**size - 1) << pos, mask0 = ~mask1
> +  //  => ins $dst, $src, size, pos
> +  if (!Subtarget->isMips32r2())
> +    return Op;
> +
> +  SDValue And0 = Op.getOperand(0), And1 = Op.getOperand(1);
> +  uint64_t SMPos0, SMSize0, SMPos1, SMSize1;
> +  ConstantSDNode *CN;
> +
> +  // See if Op's first operand matches (and $src1 , mask0).
> +  if (And0.getOpcode() != ISD::AND)
> +    return Op;
> +
> +  if (!(CN = dyn_cast<ConstantSDNode>(And0.getOperand(1))) ||
> +      !IsShiftedMask(~CN->getZExtValue(), 32, SMPos0, SMSize0))
> +    return Op;
> +
> +  // See if Op's second operand matches (and (shl $src, pos), mask1).
> +  if (And1.getOpcode() != ISD::AND)
> +    return Op;
> +
> +  if (!(CN = dyn_cast<ConstantSDNode>(And1.getOperand(1))) ||
> +      !IsShiftedMask(CN->getZExtValue(), CN->getValueSizeInBits(0), SMPos1,
> +                     SMSize1))
> +    return Op;
> +
> +  // The shift masks must have the same position and size.
> +  if (SMPos0 != SMPos1 || SMSize0 != SMSize1)
> +    return Op;
> +
> +  SDValue Shl = And1.getOperand(0);
> +  if (Shl.getOpcode() != ISD::SHL)
> +    return Op;
> +
> +  if (!(CN = dyn_cast<ConstantSDNode>(Shl.getOperand(1))))
> +    return Op;
> +
> +  unsigned Shamt = CN->getZExtValue();
> +
> +  // Return if the shift amount and the first bit position of mask are not the
> +  // same.
> +  if (Shamt != SMPos0)
> +    return Op;
> +
> +  return DAG.getNode(MipsISD::Ins, Op.getDebugLoc(), MVT::i32,
> +                     Shl.getOperand(0),
> +                     DAG.getConstant(SMSize0, MVT::i32),
> +                     DAG.getConstant(SMPos0, MVT::i32),
> +                     And0.getOperand(0));
> +}
> +
>  //===----------------------------------------------------------------------===//
>  //                      Calling Convention Implementation
>  //===----------------------------------------------------------------------===//
>
> Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.h?rev=137804&r1=137803&r2=137804&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/MipsISelLowering.h (original)
> +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.h Tue Aug 16 21:05:42 2011
> @@ -83,7 +83,10 @@
>
>       DynAlloc,
>
> -      Sync
> +      Sync,
> +
> +      Ext,
> +      Ins
>     };
>   }
>
> @@ -134,6 +137,8 @@
>     SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
>     SDValue LowerMEMBARRIER(SDValue Op, SelectionDAG& DAG) const;
>     SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
> +    SDValue LowerAND(SDValue Op, SelectionDAG& DAG) const;
> +    SDValue LowerOR(SDValue Op, SelectionDAG& DAG) const;
>
>     virtual SDValue
>       LowerFormalArguments(SDValue Chain,
>
> Modified: llvm/trunk/lib/Target/Mips/MipsInstrFormats.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrFormats.td?rev=137804&r1=137803&r2=137804&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/MipsInstrFormats.td (original)
> +++ llvm/trunk/lib/Target/Mips/MipsInstrFormats.td Tue Aug 16 21:05:42 2011
> @@ -102,6 +102,28 @@
>   let Inst{25-0} = addr;
>  }
>
> +// Ext and Ins
> +class ExtIns<bits<6> _funct, string instr_asm, dag Outs, dag Ins,
> +             list<dag> pattern, InstrItinClass itin>:
> +  MipsInst<Outs, Ins, !strconcat(instr_asm, "\t$dst, $src, $pos, $size"),
> +           pattern, itin>
> +{
> +  bits<5>  rt;
> +  bits<5>  rs;
> +  bits<5>  sz;
> +  bits<5>  pos;
> +  bits<6>  funct;
> +
> +  let opcode = 0x1f;
> +  let funct  = _funct;
> +
> +  let Inst{25-21} = rs;
> +  let Inst{20-16} = rt;
> +  let Inst{15-11} = sz;
> +  let Inst{10-6}  = pos;
> +  let Inst{5-0}   = funct;
> +}
> +
>  //===----------------------------------------------------------------------===//
>  //
>  //  FLOATING POINT INSTRUCTION FORMATS
>
> Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.td?rev=137804&r1=137803&r2=137804&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td (original)
> +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Tue Aug 16 21:05:42 2011
> @@ -43,6 +43,12 @@
>                                                SDTCisVT<1, iPTR>]>;
>  def SDT_Sync             : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
>
> +def SDT_Ext : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisSameAs<0, 1>,
> +                                   SDTCisInt<2>, SDTCisSameAs<2, 3>]>;
> +def SDT_Ins : SDTypeProfile<1, 4, [SDTCisVT<0, i32>, SDTCisSameAs<0, 1>,
> +                                   SDTCisInt<2>, SDTCisSameAs<2, 3>,
> +                                   SDTCisSameAs<0, 4>]>;
> +
>  // Call
>  def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink,
>                          [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
> @@ -109,6 +115,9 @@
>
>  def MipsSync : SDNode<"MipsISD::Sync", SDT_Sync, [SDNPHasChain]>;
>
> +def MipsExt :  SDNode<"MipsISD::Ext", SDT_Ext>;
> +def MipsIns :  SDNode<"MipsISD::Ins", SDT_Ins>;
> +
>  //===----------------------------------------------------------------------===//
>  // Mips Instruction Predicate Definitions.
>  //===----------------------------------------------------------------------===//
> @@ -661,6 +670,23 @@
>
>  def RDHWR : ReadHardware;
>
> +let Predicates = [IsMips32r2] in {
> +  def Ext : ExtIns<0b000000, "ext", (outs CPURegs:$dst),
> +                   (ins CPURegs:$src, uimm16:$size, uimm16:$pos),
> +                   [(set CPURegs:$dst,
> +                     (MipsExt CPURegs:$src, immZExt5:$size, immZExt5:$pos))],
> +                   NoItinerary>;
> +  let Constraints = "$src1 = $dst" in
> +  def Ins : ExtIns<0b000100, "ins",
> +                   (outs CPURegs:$dst),
> +                   (ins CPURegs:$src, uimm16:$size, uimm16:$pos,
> +                    CPURegs:$src1),
> +                   [(set CPURegs:$dst,
> +                     (MipsIns CPURegs:$src, immZExt5:$size, immZExt5:$pos,
> +                      CPURegs:$src1))],
> +                   NoItinerary>;
> +}
> +
>  //===----------------------------------------------------------------------===//
>  //  Arbitrary patterns that map to one or more instructions
>  //===----------------------------------------------------------------------===//
>
> Added: llvm/trunk/test/CodeGen/Mips/extins.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/extins.ll?rev=137804&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/Mips/extins.ll (added)
> +++ llvm/trunk/test/CodeGen/Mips/extins.ll Tue Aug 16 21:05:42 2011
> @@ -0,0 +1,21 @@
> +; RUN: llc -march=mips -mcpu=4ke < %s | FileCheck %s
> +
> +define i32 @ext0_5_9(i32 %s, i32 %pos, i32 %sz) nounwind readnone {
> +entry:
> +; CHECK: ext ${{[0-9]+}}, $4, 5, 9
> +  %shr = lshr i32 %s, 5
> +  %and = and i32 %shr, 511
> +  ret i32 %and
> +}
> +
> +define void @ins2_5_9(i32 %s, i32* nocapture %d) nounwind {
> +entry:
> +; CHECK: ins ${{[0-9]+}}, $4, 5, 9
> +  %and = shl i32 %s, 5
> +  %shl = and i32 %and, 16352
> +  %tmp3 = load i32* %d, align 4
> +  %and5 = and i32 %tmp3, -16353
> +  %or = or i32 %and5, %shl
> +  store i32 %or, i32* %d, align 4
> +  ret void
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>



-- 
Bruno Cardoso Lopes
http://www.brunocardoso.cc




More information about the llvm-commits mailing list