[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

Akira Hatanaka ahatanak at gmail.com
Wed Aug 17 10:25:13 PDT 2011


Encoding of instruction "ext $dst, $src, $pos, $size" looks like this:

field31-26, field25-21, field20-16, field15-11, field10-6, field5-0
31,           $src,          $dst,         $size,       $pos,       0

The FR format binds the operands in the following order,
(rd:field15-11), (rs:field25-21), (rt:field20-16), (shamt:field10-6)

so if I want to use the FR format to define "ext $dst, $src, $pos,
$size", the operands need to be given in the following order:

$size, $src, $dst, $pos

Is it possible to do so? In the format of FR, (dag outs) appears
before (dag ins).

On Tue, Aug 16, 2011 at 8:13 PM, Akira Hatanaka <ahatanak at gmail.com> wrote:
> Okay, I will make the changes tomorrow.
>
> Thank you for your comments.
>
> On Tue, Aug 16, 2011 at 7:29 PM, Bruno Cardoso Lopes
> <bruno.cardoso at gmail.com> wrote:
>> 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