[llvm-commits] [llvm] r135693 - in /llvm/trunk: lib/Target/ARM/ARMBaseInstrInfo.cpp lib/Target/ARM/ARMExpandPseudoInsts.cpp lib/Target/ARM/ARMISelDAGToDAG.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp utils/TableGen/EDEmitter.cpp

Jim Grosbach grosbach at apple.com
Thu Jul 21 12:08:16 PDT 2011


Hi Owen,

Why do both of the new patterns still need two regs and an immediate as MIOperands? It seems that so_reg_reg should be reg+reg+shifttype and so_reg_imm should be reg+imm.

-Jim

On Jul 21, 2011, at 11:54 AM, Owen Anderson wrote:

> Author: resistor
> Date: Thu Jul 21 13:54:16 2011
> New Revision: 135693
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=135693&view=rev
> Log:
> Split up the ARM so_reg ComplexPattern into so_reg_reg and so_reg_imm, allowing us to distinguish the encodings that use shifted registers from those that use shifted immediates.  This is necessary to allow the fixed-length decoder to distinguish things like BICS vs LDRH.
> 
> Modified:
>    llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp
>    llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp
>    llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
>    llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
>    llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
>    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
>    llvm/trunk/utils/TableGen/EDEmitter.cpp
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=135693&r1=135692&r2=135693&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Thu Jul 21 13:54:16 2011
> @@ -172,7 +172,7 @@
>       ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm);
>       unsigned SOOpc = ARM_AM::getSORegOpc(ShOpc, Amt);
>       UpdateMI = BuildMI(MF, MI->getDebugLoc(),
> -                         get(isSub ? ARM::SUBrs : ARM::ADDrs), WBReg)
> +                         get(isSub ? ARM::SUBrsi : ARM::ADDrsi), WBReg)
>         .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc)
>         .addImm(Pred).addReg(0).addReg(0);
>     } else
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp?rev=135693&r1=135692&r2=135693&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp Thu Jul 21 13:54:16 2011
> @@ -741,7 +741,8 @@
>       MI.eraseFromParent();
>       return true;
>     }
> -    case ARM::MOVCCs: {
> +    case ARM::MOVCCsi:
> +    case ARM::MOVCCsr: {
>       BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVs),
>               (MI.getOperand(1).getReg()))
>         .addReg(MI.getOperand(2).getReg(),
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=135693&r1=135692&r2=135693&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Thu Jul 21 13:54:16 2011
> @@ -90,13 +90,20 @@
>   bool hasNoVMLxHazardUse(SDNode *N) const;
>   bool isShifterOpProfitable(const SDValue &Shift,
>                              ARM_AM::ShiftOpc ShOpcVal, unsigned ShAmt);
> -  bool SelectShifterOperandReg(SDValue N, SDValue &A,
> +  bool SelectRegShifterOperand(SDValue N, SDValue &A,
> +                               SDValue &B, SDValue &C,
> +                               bool CheckProfitability = true);
> +  bool SelectImmShifterOperand(SDValue N, SDValue &A,
>                                SDValue &B, SDValue &C,
>                                bool CheckProfitability = true);
>   bool SelectShiftShifterOperandReg(SDValue N, SDValue &A,
>                                     SDValue &B, SDValue &C) {
>     // Don't apply the profitability check
> -    return SelectShifterOperandReg(N, A, B, C, false);
> +    if (SelectImmShifterOperand(N, A, B, C, false))
> +      return true;
> +    else if (SelectRegShifterOperand(N, A, B, C, false))
> +      return true;
> +    return false;
>   }
> 
>   bool SelectAddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm);
> @@ -365,7 +372,7 @@
>   return ShOpcVal == ARM_AM::lsl && ShAmt == 2;
> }
> 
> -bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue N,
> +bool ARMDAGToDAGISel::SelectImmShifterOperand(SDValue N,
>                                               SDValue &BaseReg,
>                                               SDValue &ShReg,
>                                               SDValue &Opc,
> @@ -381,19 +388,43 @@
> 
>   BaseReg = N.getOperand(0);
>   unsigned ShImmVal = 0;
> -  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
> -    ShReg = CurDAG->getRegister(0, MVT::i32);
> -    ShImmVal = RHS->getZExtValue() & 31;
> -  } else {
> -    ShReg = N.getOperand(1);
> -    if (CheckProfitability && !isShifterOpProfitable(N, ShOpcVal, ShImmVal))
> -      return false;
> -  }
> +  ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1));
> +  if (!RHS) return false;
> +  ShReg = CurDAG->getRegister(0, MVT::i32);
> +  ShImmVal = RHS->getZExtValue() & 31;
>   Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal),
>                                   MVT::i32);
>   return true;
> }
> 
> +bool ARMDAGToDAGISel::SelectRegShifterOperand(SDValue N,
> +                                              SDValue &BaseReg,
> +                                              SDValue &ShReg,
> +                                              SDValue &Opc,
> +                                              bool CheckProfitability) {
> +  if (DisableShifterOp)
> +    return false;
> +
> +  ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode());
> +
> +  // Don't match base register only case. That is matched to a separate
> +  // lower complexity pattern with explicit register operand.
> +  if (ShOpcVal == ARM_AM::no_shift) return false;
> +
> +  BaseReg = N.getOperand(0);
> +  unsigned ShImmVal = 0;
> +  ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1));
> +  if (RHS) return false;
> +
> +  ShReg = N.getOperand(1);
> +  if (CheckProfitability && !isShifterOpProfitable(N, ShOpcVal, ShImmVal))
> +    return false;
> +  Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal),
> +                                  MVT::i32);
> +  return true;
> +}
> +
> +
> bool ARMDAGToDAGISel::SelectAddrModeImm12(SDValue N,
>                                           SDValue &Base,
>                                           SDValue &OffImm) {
> @@ -2036,10 +2067,16 @@
>   SDValue CPTmp0;
>   SDValue CPTmp1;
>   SDValue CPTmp2;
> -  if (SelectShifterOperandReg(TrueVal, CPTmp0, CPTmp1, CPTmp2)) {
> +  if (SelectImmShifterOperand(TrueVal, CPTmp0, CPTmp1, CPTmp2)) {
> +    SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
> +    SDValue Ops[] = { FalseVal, CPTmp0, CPTmp1, CPTmp2, CC, CCR, InFlag };
> +    return CurDAG->SelectNodeTo(N, ARM::MOVCCsi, MVT::i32, Ops, 7);
> +  }
> +
> +  if (SelectRegShifterOperand(TrueVal, CPTmp0, CPTmp1, CPTmp2)) {
>     SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
>     SDValue Ops[] = { FalseVal, CPTmp0, CPTmp1, CPTmp2, CC, CCR, InFlag };
> -    return CurDAG->SelectNodeTo(N, ARM::MOVCCs, MVT::i32, Ops, 7);
> +    return CurDAG->SelectNodeTo(N, ARM::MOVCCsr, MVT::i32, Ops, 7);
>   }
>   return 0;
> }
> @@ -2309,7 +2346,7 @@
>           return CurDAG->SelectNodeTo(N, ARM::t2ADDrs, MVT::i32, Ops, 6);
>         } else {
>           SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 };
> -          return CurDAG->SelectNodeTo(N, ARM::ADDrs, MVT::i32, Ops, 7);
> +          return CurDAG->SelectNodeTo(N, ARM::ADDrsi, MVT::i32, Ops, 7);
>         }
>       }
>       if (isPowerOf2_32(RHSV+1)) {  // 2^n-1?
> @@ -2325,7 +2362,7 @@
>           return CurDAG->SelectNodeTo(N, ARM::t2RSBrs, MVT::i32, Ops, 6);
>         } else {
>           SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 };
> -          return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 7);
> +          return CurDAG->SelectNodeTo(N, ARM::RSBrsi, MVT::i32, Ops, 7);
>         }
>       }
>     }
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=135693&r1=135692&r2=135693&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Thu Jul 21 13:54:16 2011
> @@ -5224,15 +5224,19 @@
> static AddSubFlagsOpcodePair AddSubFlagsOpcodeMap[] = {
>   {ARM::ADCSri, ARM::ADCri},
>   {ARM::ADCSrr, ARM::ADCrr},
> -  {ARM::ADCSrs, ARM::ADCrs},
> +  {ARM::ADCSrsi, ARM::ADCrsi},
> +  {ARM::ADCSrsr, ARM::ADCrsr},
>   {ARM::SBCSri, ARM::SBCri},
>   {ARM::SBCSrr, ARM::SBCrr},
> -  {ARM::SBCSrs, ARM::SBCrs},
> +  {ARM::SBCSrsi, ARM::SBCrsi},
> +  {ARM::SBCSrsr, ARM::SBCrsr},
>   {ARM::RSBSri, ARM::RSBri},
>   {ARM::RSBSrr, ARM::RSBrr},
> -  {ARM::RSBSrs, ARM::RSBrs},
> +  {ARM::RSBSrsi, ARM::RSBrsi},
> +  {ARM::RSBSrsr, ARM::RSBrsr},
>   {ARM::RSCSri, ARM::RSCri},
> -  {ARM::RSCSrs, ARM::RSCrs},
> +  {ARM::RSCSrsi, ARM::RSCrsi},
> +  {ARM::RSCSrsr, ARM::RSCrsr},
>   {ARM::t2ADCSri, ARM::t2ADCri},
>   {ARM::t2ADCSrr, ARM::t2ADCrr},
>   {ARM::t2ADCSrs, ARM::t2ADCrs},
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=135693&r1=135692&r2=135693&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
> +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Jul 21 13:54:16 2011
> @@ -423,15 +423,29 @@
>   let Name = "ShiftedReg";
> }
> 
> -// shifter_operand operands: so_reg and so_imm.
> -def so_reg : Operand<i32>,    // reg reg imm
> -             ComplexPattern<i32, 3, "SelectShifterOperandReg",
> -                            [shl,srl,sra,rotr]> {
> +def ShiftedImmAsmOperand : AsmOperandClass {
> +  let Name = "ShiftedImm";
> +}
> +
> +// shifter_operand operands: so_reg_reg, so_reg_imm, and so_imm.
> +def so_reg_reg : Operand<i32>,  // reg reg imm
> +                 ComplexPattern<i32, 3, "SelectRegShifterOperand",
> +                                [shl, srl, sra, rotr]> {
>   let EncoderMethod = "getSORegOpValue";
>   let PrintMethod = "printSORegOperand";
>   let ParserMatchClass = ShiftedRegAsmOperand;
>   let MIOperandInfo = (ops GPR, GPR, shift_imm);
> }
> +
> +def so_reg_imm : Operand<i32>, // reg imm
> +                 ComplexPattern<i32, 3, "SelectImmShifterOperand",
> +                                [shl, srl, sra, rotr]> {
> +  let EncoderMethod = "getSORegOpValue";
> +  let PrintMethod = "printSORegOperand";
> +  let ParserMatchClass = ShiftedImmAsmOperand;
> +  let MIOperandInfo = (ops GPR, GPR, shift_imm);
> +}
> +

> // FIXME: Does this need to be distinct from so_reg?
> def shift_so_reg : Operand<i32>,    // reg reg imm
>                    ComplexPattern<i32, 3, "SelectShiftShifterOperandReg",
> @@ -755,16 +769,37 @@
>     let Inst{11-4} = 0b00000000;
>     let Inst{3-0} = Rm;
>   }
> -  def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
> +
> +  def rsi : AsI1<opcod, (outs GPR:$Rd),
> +               (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegFrm,
> +               iis, opc, "\t$Rd, $Rn, $shift",
> +               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_imm:$shift))]> {
> +    bits<4> Rd;
> +    bits<4> Rn;
> +    bits<12> shift;
> +    let Inst{25} = 0;
> +    let Inst{19-16} = Rn;
> +    let Inst{15-12} = Rd;
> +    let Inst{11-5} = shift{11-5};
> +    let Inst{4} = 0;
> +    let Inst{3-0} = shift{3-0};
> +  }
> +
> +  def rsr : AsI1<opcod, (outs GPR:$Rd),
> +               (ins GPR:$Rn, so_reg_reg:$shift), DPSoRegFrm,
>                iis, opc, "\t$Rd, $Rn, $shift",
> -               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
> +               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_reg:$shift))]> {
>     bits<4> Rd;
>     bits<4> Rn;
>     bits<12> shift;
>     let Inst{25} = 0;
>     let Inst{19-16} = Rn;
>     let Inst{15-12} = Rd;
> -    let Inst{11-0} = shift;
> +    let Inst{11-8} = shift{11-8};
> +    let Inst{7} = 0;
> +    let Inst{6-5} = shift{6-5};
> +    let Inst{4} = 1;
> +    let Inst{3-0} = shift{3-0};
>   }
> 
>   // Assembly aliases for optional destination operand when it's the same
> @@ -780,10 +815,16 @@
>                                                     cc_out:$s)>,
>      Requires<[IsARM]>;
>   def : InstAlias<!strconcat(opc, "${s}${p} $Rdn, $shift"),
> -     (!cast<Instruction>(!strconcat(baseOpc, "rs")) GPR:$Rdn, GPR:$Rdn,
> -                                                    so_reg:$shift, pred:$p,
> +     (!cast<Instruction>(!strconcat(baseOpc, "rsi")) GPR:$Rdn, GPR:$Rdn,
> +                                                    so_reg_imm:$shift, pred:$p,
>                                                     cc_out:$s)>,
>      Requires<[IsARM]>;
> +  def : InstAlias<!strconcat(opc, "${s}${p} $Rdn, $shift"),
> +     (!cast<Instruction>(!strconcat(baseOpc, "rsr")) GPR:$Rdn, GPR:$Rdn,
> +                                                    so_reg_reg:$shift, pred:$p,
> +                                                    cc_out:$s)>,
> +     Requires<[IsARM]>;
> +
> }
> 
> /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
> @@ -818,9 +859,10 @@
>     let Inst{11-4} = 0b00000000;
>     let Inst{3-0} = Rm;
>   }
> -  def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
> +  def rsi : AI1<opcod, (outs GPR:$Rd),
> +               (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegFrm,
>                iis, opc, "\t$Rd, $Rn, $shift",
> -               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
> +               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_imm:$shift))]> {
>     bits<4> Rd;
>     bits<4> Rn;
>     bits<12> shift;
> @@ -828,7 +870,27 @@
>     let Inst{20} = 1;
>     let Inst{19-16} = Rn;
>     let Inst{15-12} = Rd;
> -    let Inst{11-0} = shift;
> +    let Inst{11-5} = shift{11-5};
> +    let Inst{4} = 0;
> +    let Inst{3-0} = shift{3-0};
> +  }
> +
> +    def rsr : AI1<opcod, (outs GPR:$Rd),
> +               (ins GPR:$Rn, so_reg_reg:$shift), DPSoRegFrm,
> +               iis, opc, "\t$Rd, $Rn, $shift",
> +               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_reg:$shift))]> {
> +    bits<4> Rd;
> +    bits<4> Rn;
> +    bits<12> shift;
> +    let Inst{25} = 0;
> +    let Inst{20} = 1;
> +    let Inst{19-16} = Rn;
> +    let Inst{15-12} = Rd;
> +    let Inst{11-8} = shift{11-8};
> +    let Inst{7} = 0;
> +    let Inst{6-5} = shift{6-5};
> +    let Inst{4} = 1;
> +    let Inst{3-0} = shift{3-0};
>   }
> }
> }
> @@ -864,17 +926,37 @@
>     let Inst{11-4} = 0b00000000;
>     let Inst{3-0} = Rm;
>   }
> -  def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis,
> +  def rsi : AI1<opcod, (outs),
> +               (ins GPR:$Rn, so_reg_imm:$shift), DPSoRegFrm, iis,
> +               opc, "\t$Rn, $shift",
> +               [(opnode GPR:$Rn, so_reg_imm:$shift)]> {
> +    bits<4> Rn;
> +    bits<12> shift;
> +    let Inst{25} = 0;
> +    let Inst{20} = 1;
> +    let Inst{19-16} = Rn;
> +    let Inst{15-12} = 0b0000;
> +    let Inst{11-5} = shift{11-5};
> +    let Inst{4} = 0;
> +    let Inst{3-0} = shift{3-0};
> +  }
> +  def rsr : AI1<opcod, (outs),
> +               (ins GPR:$Rn, so_reg_reg:$shift), DPSoRegFrm, iis,
>                opc, "\t$Rn, $shift",
> -               [(opnode GPR:$Rn, so_reg:$shift)]> {
> +               [(opnode GPR:$Rn, so_reg_reg:$shift)]> {
>     bits<4> Rn;
>     bits<12> shift;
>     let Inst{25} = 0;
>     let Inst{20} = 1;
>     let Inst{19-16} = Rn;
>     let Inst{15-12} = 0b0000;
> -    let Inst{11-0} = shift;
> +    let Inst{11-8} = shift{11-8};
> +    let Inst{7} = 0;
> +    let Inst{6-5} = shift{6-5};
> +    let Inst{4} = 1;
> +    let Inst{3-0} = shift{3-0};
>   }
> +
> }
> }
> 
> @@ -1009,17 +1091,37 @@
>     let Inst{15-12} = Rd;
>     let Inst{19-16} = Rn;
>   }
> -  def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
> +  def rsi : AsI1<opcod, (outs GPR:$Rd),
> +                (ins GPR:$Rn, so_reg_imm:$shift),
>                 DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
> -               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>,
> +               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_imm:$shift))]>,
>                Requires<[IsARM]> {
>     bits<4> Rd;
>     bits<4> Rn;
>     bits<12> shift;
>     let Inst{25} = 0;
> -    let Inst{11-0} = shift;
> +    let Inst{19-16} = Rn;
>     let Inst{15-12} = Rd;
> +    let Inst{11-5} = shift{11-5};
> +    let Inst{4} = 0;
> +    let Inst{3-0} = shift{3-0};
> +  }
> +  def rsr : AsI1<opcod, (outs GPR:$Rd),
> +                (ins GPR:$Rn, so_reg_reg:$shift),
> +                DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift",
> +               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_reg:$shift))]>,
> +               Requires<[IsARM]> {
> +    bits<4> Rd;
> +    bits<4> Rn;
> +    bits<12> shift;
> +    let Inst{25} = 0;
>     let Inst{19-16} = Rn;
> +    let Inst{15-12} = Rd;
> +    let Inst{11-8} = shift{11-8};
> +    let Inst{7} = 0;
> +    let Inst{6-5} = shift{6-5};
> +    let Inst{4} = 1;
> +    let Inst{3-0} = shift{3-0};
>   }
>   }
>   // Assembly aliases for optional destination operand when it's the same
> @@ -1035,8 +1137,13 @@
>                                                     cc_out:$s)>,
>      Requires<[IsARM]>;
>   def : InstAlias<!strconcat(opc, "${s}${p} $Rdn, $shift"),
> -     (!cast<Instruction>(!strconcat(baseOpc, "rs")) GPR:$Rdn, GPR:$Rdn,
> -                                                    so_reg:$shift, pred:$p,
> +     (!cast<Instruction>(!strconcat(baseOpc, "rsi")) GPR:$Rdn, GPR:$Rdn,
> +                                                    so_reg_imm:$shift, pred:$p,
> +                                                    cc_out:$s)>,
> +     Requires<[IsARM]>;
> +  def : InstAlias<!strconcat(opc, "${s}${p} $Rdn, $shift"),
> +     (!cast<Instruction>(!strconcat(baseOpc, "rsr")) GPR:$Rdn, GPR:$Rdn,
> +                                                    so_reg_reg:$shift, pred:$p,
>                                                     cc_out:$s)>,
>      Requires<[IsARM]>;
> }
> @@ -1053,9 +1160,12 @@
>                [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> {
>     let isCommutable = Commutable;
>   }
> -  def rs : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
> +  def rsi : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_reg_imm:$shift),
>                4, IIC_iALUsr,
> -               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>;
> +               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_imm:$shift))]>;
> +  def rsr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_reg_reg:$shift),
> +               4, IIC_iALUsr,
> +               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_reg:$shift))]>;
> }
> }
> 
> @@ -2338,16 +2448,34 @@
>   let Inst{19-16} = Rn;
> }
> 
> -def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
> +def RSBrsi : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_imm:$shift),
>                  DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
> -                 [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> {
> +                 [(set GPR:$Rd, (sub so_reg_imm:$shift, GPR:$Rn))]> {
>   bits<4> Rd;
>   bits<4> Rn;
>   bits<12> shift;
>   let Inst{25} = 0;
> -  let Inst{11-0} = shift;
> +  let Inst{19-16} = Rn;
>   let Inst{15-12} = Rd;
> +  let Inst{11-5} = shift{11-5};
> +  let Inst{4} = 0;
> +  let Inst{3-0} = shift{3-0};
> +}
> +
> +def RSBrsr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_reg:$shift),
> +                 DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift",
> +                 [(set GPR:$Rd, (sub so_reg_reg:$shift, GPR:$Rn))]> {
> +  bits<4> Rd;
> +  bits<4> Rn;
> +  bits<12> shift;
> +  let Inst{25} = 0;
>   let Inst{19-16} = Rn;
> +  let Inst{15-12} = Rd;
> +  let Inst{11-8} = shift{11-8};
> +  let Inst{7} = 0;
> +  let Inst{6-5} = shift{6-5};
> +  let Inst{4} = 1;
> +  let Inst{3-0} = shift{3-0};
> }
> 
> // RSB with 's' bit set.
> @@ -2359,9 +2487,12 @@
> def RSBSrr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
>                  4, IIC_iALUr,
>                  [/* For disassembly only; pattern left blank */]>;
> -def RSBSrs : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
> +def RSBSrsi : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_reg_imm:$shift),
>                  4, IIC_iALUsr,
> -                 [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]>;
> +                 [(set GPR:$Rd, (subc so_reg_imm:$shift, GPR:$Rn))]>;
> +def RSBSrsr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_reg_reg:$shift),
> +                 4, IIC_iALUsr,
> +                 [(set GPR:$Rd, (subc so_reg_reg:$shift, GPR:$Rn))]>;
> }
> 
> let Uses = [CPSR] in {
> @@ -2391,28 +2522,50 @@
>   let Inst{15-12} = Rd;
>   let Inst{19-16} = Rn;
> }
> -def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
> +def RSCrsi : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_imm:$shift),
>                  DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
> -                 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>,
> +                 [(set GPR:$Rd, (sube_dead_carry so_reg_imm:$shift, GPR:$Rn))]>,
>                  Requires<[IsARM]> {
>   bits<4> Rd;
>   bits<4> Rn;
>   bits<12> shift;
>   let Inst{25} = 0;
> -  let Inst{11-0} = shift;
> +  let Inst{19-16} = Rn;
>   let Inst{15-12} = Rd;
> +  let Inst{11-5} = shift{11-5};
> +  let Inst{4} = 0;
> +  let Inst{3-0} = shift{3-0};
> +}
> +def RSCrsr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg_reg:$shift),
> +                 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift",
> +                 [(set GPR:$Rd, (sube_dead_carry so_reg_reg:$shift, GPR:$Rn))]>,
> +                 Requires<[IsARM]> {
> +  bits<4> Rd;
> +  bits<4> Rn;
> +  bits<12> shift;
> +  let Inst{25} = 0;
>   let Inst{19-16} = Rn;
> +  let Inst{15-12} = Rd;
> +  let Inst{11-8} = shift{11-8};
> +  let Inst{7} = 0;
> +  let Inst{6-5} = shift{6-5};
> +  let Inst{4} = 1;
> +  let Inst{3-0} = shift{3-0};
> }
> }
> 
> +
> // NOTE: CPSR def omitted because it will be handled by the custom inserter.
> let usesCustomInserter = 1, Uses = [CPSR] in {
> def RSCSri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm),
>                   4, IIC_iALUi,
>                   [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>;
> -def RSCSrs : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift),
> +def RSCSrsi : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_reg_imm:$shift),
> +                  4, IIC_iALUsr,
> +                [(set GPR:$Rd, (sube_dead_carry so_reg_imm:$shift, GPR:$Rn))]>;
> +def RSCSrsr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_reg_reg:$shift),
>                   4, IIC_iALUsr,
> -                  [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>;
> +                [(set GPR:$Rd, (sube_dead_carry so_reg_reg:$shift, GPR:$Rn))]>;
> }
> 
> // (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
> @@ -2684,15 +2837,31 @@
>   let Inst{15-12} = Rd;
>   let Inst{3-0} = Rm;
> }
> -def  MVNs  : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm,
> +def  MVNsi  : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_imm:$shift), DPSoRegFrm,
>                   IIC_iMVNsr, "mvn", "\t$Rd, $shift",
> -                  [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP {
> +                  [(set GPR:$Rd, (not so_reg_imm:$shift))]>, UnaryDP {
>   bits<4> Rd;
>   bits<12> shift;
>   let Inst{25} = 0;
>   let Inst{19-16} = 0b0000;
>   let Inst{15-12} = Rd;
> -  let Inst{11-0} = shift;
> +  let Inst{11-5} = shift{11-5};
> +  let Inst{4} = 0;
> +  let Inst{3-0} = shift{3-0};
> +}
> +def  MVNsr  : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_reg:$shift), DPSoRegFrm,
> +                  IIC_iMVNsr, "mvn", "\t$Rd, $shift",
> +                  [(set GPR:$Rd, (not so_reg_reg:$shift))]>, UnaryDP {
> +  bits<4> Rd;
> +  bits<12> shift;
> +  let Inst{25} = 0;
> +  let Inst{19-16} = 0b0000;
> +  let Inst{15-12} = Rd;
> +  let Inst{11-8} = shift{11-8};
> +  let Inst{7} = 0;
> +  let Inst{6-5} = shift{6-5};
> +  let Inst{4} = 1;
> +  let Inst{3-0} = shift{3-0};
> }
> let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
> def  MVNi  : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm,
> @@ -3156,8 +3325,10 @@
>              (CMPri   GPR:$src, so_imm:$imm)>;
> def : ARMPat<(ARMcmpZ GPR:$src, GPR:$rhs),
>              (CMPrr   GPR:$src, GPR:$rhs)>;
> -def : ARMPat<(ARMcmpZ GPR:$src, so_reg:$rhs),
> -             (CMPrs   GPR:$src, so_reg:$rhs)>;
> +def : ARMPat<(ARMcmpZ GPR:$src, so_reg_imm:$rhs),
> +             (CMPrsi   GPR:$src, so_reg_imm:$rhs)>;
> +def : ARMPat<(ARMcmpZ GPR:$src, so_reg_reg:$rhs),
> +             (CMPrsr   GPR:$src, so_reg_reg:$rhs)>;
> 
> // FIXME: We have to be careful when using the CMN instruction and comparison
> // with 0. One would expect these two pieces of code should give identical
> @@ -3243,11 +3414,17 @@
>                            4, IIC_iCMOVr,
>   [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
>       RegConstraint<"$false = $Rd">;
> -def MOVCCs : ARMPseudoInst<(outs GPR:$Rd),
> -                           (ins GPR:$false, so_reg:$shift, pred:$p),
> +def MOVCCsi : ARMPseudoInst<(outs GPR:$Rd),
> +                           (ins GPR:$false, so_reg_imm:$shift, pred:$p),
>                            4, IIC_iCMOVsr,
> -  [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg:$shift, imm:$cc, CCR:$ccr))*/]>,
> +  [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg_imm:$shift, imm:$cc, CCR:$ccr))*/]>,
>       RegConstraint<"$false = $Rd">;
> +def MOVCCsr : ARMPseudoInst<(outs GPR:$Rd),
> +                           (ins GPR:$false, so_reg_reg:$shift, pred:$p),
> +                           4, IIC_iCMOVsr,
> +  [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg_reg:$shift, imm:$cc, CCR:$ccr))*/]>,
> +      RegConstraint<"$false = $Rd">;
> +
> 
> let isMoveImm = 1 in
> def MOVCCi16 : ARMPseudoInst<(outs GPR:$Rd),
> 
> Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=135693&r1=135692&r2=135693&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Thu Jul 21 13:54:16 2011
> @@ -172,6 +172,7 @@
>     DPRRegisterList,
>     SPRRegisterList,
>     ShiftedRegister,
> +    ShiftedImmediate,
>     Shifter,
>     Token
>   } Kind;
> @@ -241,6 +242,11 @@
>       unsigned ShiftReg;
>       unsigned ShiftImm;
>     } ShiftedReg;
> +    struct {
> +      ARM_AM::ShiftOpc ShiftTy;
> +      unsigned SrcReg;
> +      unsigned ShiftImm;
> +    } ShiftedImm;
>   };
> 
>   ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
> @@ -290,6 +296,9 @@
>     case ShiftedRegister:
>       ShiftedReg = o.ShiftedReg;
>       break;
> +    case ShiftedImmediate:
> +      ShiftedImm = o.ShiftedImm;
> +      break;
>     }
>   }
> 
> @@ -468,6 +477,7 @@
>   bool isMemory() const { return Kind == Memory; }
>   bool isShifter() const { return Kind == Shifter; }
>   bool isShiftedReg() const { return Kind == ShiftedRegister; }
> +  bool isShiftedImm() const { return Kind == ShiftedImmediate; }
>   bool isMemMode2() const {
>     if (getMemAddrMode() != ARMII::AddrMode2)
>       return false;
> @@ -601,15 +611,25 @@
>   void addShiftedRegOperands(MCInst &Inst, unsigned N) const {
>     assert(N == 3 && "Invalid number of operands!");
>     assert(isShiftedReg() && "addShiftedRegOperands() on non ShiftedReg!");
> -    assert((ShiftedReg.ShiftReg == 0 ||
> -            ARM_AM::getSORegOffset(ShiftedReg.ShiftImm) == 0) &&
> -           "Invalid shifted register operand!");
>     Inst.addOperand(MCOperand::CreateReg(ShiftedReg.SrcReg));
>     Inst.addOperand(MCOperand::CreateReg(ShiftedReg.ShiftReg));
>     Inst.addOperand(MCOperand::CreateImm(
>       ARM_AM::getSORegOpc(ShiftedReg.ShiftTy, ShiftedReg.ShiftImm)));
>   }
> 
> +  void addShiftedImmOperands(MCInst &Inst, unsigned N) const {
> +    assert(N == 3 && "Invalid number of operands!");
> +    assert(isShiftedImm() && "addShiftedImmOperands() on non ShiftedImm!");
> +    Inst.addOperand(MCOperand::CreateReg(ShiftedImm.SrcReg));
> +    if (ShiftedImm.ShiftTy == ARM_AM::rrx)
> +      Inst.addOperand(MCOperand::CreateReg(ShiftedImm.SrcReg));
> +    else
> +      Inst.addOperand(MCOperand::CreateReg(0));
> +    Inst.addOperand(MCOperand::CreateImm(
> +      ARM_AM::getSORegOpc(ShiftedImm.ShiftTy, ShiftedImm.ShiftImm)));
> +  }
> +
> +
>   void addShifterOperands(MCInst &Inst, unsigned N) const {
>     assert(N == 1 && "Invalid number of operands!");
>     Inst.addOperand(MCOperand::CreateImm(
> @@ -885,6 +905,19 @@
>     return Op;
>   }
> 
> +  static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
> +                                            unsigned SrcReg,
> +                                            unsigned ShiftImm,
> +                                            SMLoc S, SMLoc E) {
> +    ARMOperand *Op = new ARMOperand(ShiftedImmediate);
> +    Op->ShiftedImm.ShiftTy = ShTy;
> +    Op->ShiftedImm.SrcReg = SrcReg;
> +    Op->ShiftedImm.ShiftImm = ShiftImm;
> +    Op->StartLoc = S;
> +    Op->EndLoc = E;
> +    return Op;
> +  }
> +
>   static ARMOperand *CreateShifter(ARM_AM::ShiftOpc ShTy,
>                                    SMLoc S, SMLoc E) {
>     ARMOperand *Op = new ARMOperand(Shifter);
> @@ -1052,13 +1085,20 @@
>     OS << "<shifter " << ARM_AM::getShiftOpcStr(Shift.ShiftTy) << ">";
>     break;
>   case ShiftedRegister:
> -    OS << "<so_reg"
> +    OS << "<so_reg_reg "
>        << ShiftedReg.SrcReg
>        << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(ShiftedReg.ShiftImm))
>        << ", " << ShiftedReg.ShiftReg << ", "
>        << ARM_AM::getSORegOffset(ShiftedReg.ShiftImm)
>        << ">";
>     break;
> +  case ShiftedImmediate:
> +    OS << "<so_reg_imm "
> +       << ShiftedImm.SrcReg
> +       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(ShiftedImm.ShiftImm))
> +       << ", " << ARM_AM::getSORegOffset(ShiftedImm.ShiftImm)
> +       << ">";
> +    break;
>   case RegisterList:
>   case DPRRegisterList:
>   case SPRRegisterList: {
> @@ -1201,9 +1241,13 @@
>     }
>   }
> 
> -  Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
> +  if (ShiftReg && ShiftTy != ARM_AM::rrx)
> +    Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
>                                                        ShiftReg, Imm,
>                                                S, Parser.getTok().getLoc()));
> +  else
> +    Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
> +                                               S, Parser.getTok().getLoc()));
> 
>   return 0;
> }
> 
> Modified: llvm/trunk/utils/TableGen/EDEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/EDEmitter.cpp?rev=135693&r1=135692&r2=135693&view=diff
> ==============================================================================
> --- llvm/trunk/utils/TableGen/EDEmitter.cpp (original)
> +++ llvm/trunk/utils/TableGen/EDEmitter.cpp Thu Jul 21 13:54:16 2011
> @@ -623,7 +623,8 @@
> 
>   MISC("t_bltarget", "kOperandTypeARMBranchTarget");              // ?
>   MISC("t_blxtarget", "kOperandTypeARMBranchTarget");             // ?
> -  MISC("so_reg", "kOperandTypeARMSoReg");                         // R, R, I
> +  MISC("so_reg_imm", "kOperandTypeARMSoReg");                         // R, R, I
> +  MISC("so_reg_reg", "kOperandTypeARMSoReg");                         // R, R, I
>   MISC("shift_so_reg", "kOperandTypeARMSoReg");                   // R, R, I
>   MISC("t2_so_reg", "kOperandTypeThumb2SoReg");                   // R, I
>   MISC("so_imm", "kOperandTypeARMSoImm");                         // I
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list