[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