From 13ab020ea08826f1b87db6ec3da63889a12e3d9d Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Tue, 10 Jul 2007 18:08:01 +0000 Subject: [PATCH] Remove clobbersPred. Add an OptionalDefOperand to instructions which have the 's' bit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@38501 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelDAGToDAG.cpp | 26 +-- lib/Target/ARM/ARMInstrInfo.cpp | 34 +++- lib/Target/ARM/ARMInstrInfo.h | 3 + lib/Target/ARM/ARMInstrInfo.td | 210 +++++++++++------------ lib/Target/ARM/ARMInstrThumb.td | 1 - lib/Target/ARM/ARMInstrVFP.td | 1 - lib/Target/ARM/ARMLoadStoreOptimizer.cpp | 2 +- lib/Target/ARM/ARMRegisterInfo.cpp | 14 +- 8 files changed, 154 insertions(+), 137 deletions(-) diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index da07d203f00..933651d8b15 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -586,8 +586,9 @@ SDNode *ARMDAGToDAGISel::Select(SDOperand Op) { CurDAG->getTargetConstant(0, MVT::i32)); else { SDOperand Ops[] = { TFI, CurDAG->getTargetConstant(0, MVT::i32), - getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) }; - return CurDAG->SelectNodeTo(N, ARM::ADDri, MVT::i32, Ops, 4); + getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), + CurDAG->getRegister(0, MVT::i32) }; + return CurDAG->SelectNodeTo(N, ARM::ADDri, MVT::i32, Ops, 5); } } case ISD::ADD: { @@ -619,10 +620,9 @@ SDNode *ARMDAGToDAGISel::Select(SDOperand Op) { unsigned ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, Log2_32(RHSV-1)); SDOperand Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32), CurDAG->getTargetConstant(ShImm, MVT::i32), - getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) - - }; - return CurDAG->SelectNodeTo(N, ARM::ADDrs, MVT::i32, Ops, 6); + getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), + CurDAG->getRegister(0, MVT::i32) }; + return CurDAG->SelectNodeTo(N, ARM::ADDrs, MVT::i32, Ops, 7); } if (isPowerOf2_32(RHSV+1)) { // 2^n-1? SDOperand V = Op.getOperand(0); @@ -631,8 +631,8 @@ SDNode *ARMDAGToDAGISel::Select(SDOperand Op) { SDOperand Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32), CurDAG->getTargetConstant(ShImm, MVT::i32), getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), - }; - return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 6); + CurDAG->getRegister(0, MVT::i32) }; + return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 7); } } break; @@ -645,15 +645,17 @@ SDNode *ARMDAGToDAGISel::Select(SDOperand Op) { AddToISelQueue(Op.getOperand(0)); AddToISelQueue(Op.getOperand(1)); SDOperand Ops[] = { Op.getOperand(0), Op.getOperand(1), - getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) }; - return CurDAG->getTargetNode(ARM::UMULL, MVT::i32, MVT::i32, Ops, 4); + getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), + CurDAG->getRegister(0, MVT::i32) }; + return CurDAG->getTargetNode(ARM::UMULL, MVT::i32, MVT::i32, Ops, 5); } case ARMISD::MULHILOS: { AddToISelQueue(Op.getOperand(0)); AddToISelQueue(Op.getOperand(1)); SDOperand Ops[] = { Op.getOperand(0), Op.getOperand(1), - getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) }; - return CurDAG->getTargetNode(ARM::SMULL, MVT::i32, MVT::i32, Ops, 4); + getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), + CurDAG->getRegister(0, MVT::i32) }; + return CurDAG->getTargetNode(ARM::SMULL, MVT::i32, MVT::i32, Ops, 5); } case ISD::LOAD: { LoadSDNode *LD = cast(Op); diff --git a/lib/Target/ARM/ARMInstrInfo.cpp b/lib/Target/ARM/ARMInstrInfo.cpp index 70e4d50163f..f4b4dbe2e3a 100644 --- a/lib/Target/ARM/ARMInstrInfo.cpp +++ b/lib/Target/ARM/ARMInstrInfo.cpp @@ -214,15 +214,18 @@ ARMInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, // add more than 1 instruction. Abandon! return NULL; UpdateMI = BuildMI(get(isSub ? ARM::SUBri : ARM::ADDri), WBReg) - .addReg(BaseReg).addImm(SOImmVal).addImm(Pred); + .addReg(BaseReg).addImm(SOImmVal) + .addImm(Pred).addReg(0).addReg(0); } else if (Amt != 0) { ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm); unsigned SOOpc = ARM_AM::getSORegOpc(ShOpc, Amt); UpdateMI = BuildMI(get(isSub ? ARM::SUBrs : ARM::ADDrs), WBReg) - .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc).addImm(Pred); + .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc) + .addImm(Pred).addReg(0).addReg(0); } else UpdateMI = BuildMI(get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg) - .addReg(BaseReg).addReg(OffReg).addImm(Pred); + .addReg(BaseReg).addReg(OffReg) + .addImm(Pred).addReg(0).addReg(0); break; } case ARMII::AddrMode3 : { @@ -231,10 +234,12 @@ ARMInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, if (OffReg == 0) // Immediate is 8-bits. It's guaranteed to fit in a so_imm operand. UpdateMI = BuildMI(get(isSub ? ARM::SUBri : ARM::ADDri), WBReg) - .addReg(BaseReg).addImm(Amt).addImm(Pred); + .addReg(BaseReg).addImm(Amt) + .addImm(Pred).addReg(0).addReg(0); else UpdateMI = BuildMI(get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg) - .addReg(BaseReg).addReg(OffReg).addImm(Pred); + .addReg(BaseReg).addReg(OffReg) + .addImm(Pred).addReg(0).addReg(0); break; } } @@ -495,6 +500,25 @@ ARMInstrInfo::SubsumesPredicate(const std::vector &Pred1, } } +bool ARMInstrInfo::DefinesPredicate(MachineInstr *MI, + std::vector &Pred) const { + const TargetInstrDescriptor *TID = MI->getInstrDescriptor(); + if (!TID->ImplicitDefs && (TID->Flags & M_HAS_OPTIONAL_DEF) == 0) + return false; + + bool Found = false; + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + if (MO.isReg() && MO.getReg() == ARM::CPSR) { + Pred.push_back(MO); + Found = true; + } + } + + return Found; +} + + /// FIXME: Works around a gcc miscompilation with -fstrict-aliasing static unsigned getNumJTEntries(const std::vector &JT, unsigned JTI) DISABLE_INLINE; diff --git a/lib/Target/ARM/ARMInstrInfo.h b/lib/Target/ARM/ARMInstrInfo.h index 5b406cb8168..2c158b8a245 100644 --- a/lib/Target/ARM/ARMInstrInfo.h +++ b/lib/Target/ARM/ARMInstrInfo.h @@ -113,6 +113,9 @@ public: virtual bool SubsumesPredicate(const std::vector &Pred1, const std::vector &Pred1) const; + + virtual bool DefinesPredicate(MachineInstr *MI, + std::vector &Pred) const; }; // Utility routines diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 97cc15d3fec..adc203b6e9c 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -380,10 +380,25 @@ class I Predicates = [IsARM]; } +// Same as I except it can optionally modify CPSR. +class sI pattern> + // FIXME: Set all opcodes to 0 for now. + : InstARM<0, am, sz, im, cstr> { + let OperandList = !con(oprnds, (ops pred:$p, cc_out:$s)); + let AsmString = !strconcat(opc, !strconcat("${p}${s}", asm)); + let Pattern = pattern; + list Predicates = [IsARM]; +} + class AI pattern> : I; +class AsI pattern> + : sI; class AI1 pattern> : I; +class AsI1 pattern> + : sI; class AI2 pattern> : I; class AI3 pattern> @@ -412,21 +427,21 @@ class UnOpFrag : PatFrag<(ops node:$Src), res>; /// AI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a /// binop that produces a value. -multiclass AI1_bin_irs { - def ri : AI1<(ops GPR:$dst, GPR:$a, so_imm:$b), +multiclass AsI1_bin_irs { + def ri : AsI1<(ops GPR:$dst, GPR:$a, so_imm:$b), opc, " $dst, $a, $b", [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>; - def rr : AI1<(ops GPR:$dst, GPR:$a, GPR:$b), + def rr : AsI1<(ops GPR:$dst, GPR:$a, GPR:$b), opc, " $dst, $a, $b", [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>; - def rs : AI1<(ops GPR:$dst, GPR:$a, so_reg:$b), + def rs : AsI1<(ops GPR:$dst, GPR:$a, so_reg:$b), opc, " $dst, $a, $b", [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>; } -/// AI1_bin_s_irs - Similar to AI1_bin_irs except it sets the 's' bit so the +/// ASI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the /// instruction modifies the CSPR register. -multiclass AI1_bin_s_irs { +multiclass ASI1_bin_s_irs { def ri : AI1<(ops GPR:$dst, GPR:$a, so_imm:$b), opc, "s $dst, $a, $b", [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>, Imp<[], [CPSR]>; @@ -439,7 +454,7 @@ multiclass AI1_bin_s_irs { } /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test -/// patterns. Similar to AI1_bin_irs except the instruction does not produce +/// patterns. Similar to AsI1_bin_irs except the instruction does not produce /// a explicit result, only implicitly set CPSR. multiclass AI1_cmp_irs { def ri : AI1<(ops GPR:$a, so_imm:$b), @@ -453,30 +468,6 @@ multiclass AI1_cmp_irs { [(opnode GPR:$a, so_reg:$b)]>, Imp<[], [CPSR]>; } -/// AI1_bin_is - Defines a set of (op r, {so_imm|so_reg}) patterns for a binop. -multiclass AI1_bin_is { - def ri : AI1<(ops GPR:$dst, GPR:$a, so_imm:$b), - opc, " $dst, $a, $b", - [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>; - def rs : AI1<(ops GPR:$dst, GPR:$a, so_reg:$b), - opc, " $dst, $a, $b", - [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>; -} - -/// AI1_unary_irs - Defines a set of (op {so_imm|r|so_reg}) patterns for unary -/// ops. -multiclass AI1_unary_irs { - def i : AI1<(ops GPR:$dst, so_imm:$a), - opc, " $dst, $a", - [(set GPR:$dst, (opnode so_imm:$a))]>; - def r : AI1<(ops GPR:$dst, GPR:$a), - opc, " $dst, $a", - [(set GPR:$dst, (opnode GPR:$a))]>; - def s : AI1<(ops GPR:$dst, so_reg:$a), - opc, " $dst, $a", - [(set GPR:$dst, (opnode so_reg:$a))]>; -} - /// AI_unary_rrot - A unary operation with two forms: one whose operand is a /// register and one whose operand is a register rotated by 8/16/24. multiclass AI_unary_rrot { @@ -536,17 +527,17 @@ class JTI1 pattern> class JTI2 pattern> : XI; -/// AXI1_bin_c_irs - Same as AI1_bin_irs but without the predicate operand and -/// setting carry bit. -multiclass AXI1_bin_c_irs { - def ri : AXI1<(ops GPR:$dst, GPR:$a, so_imm:$b), - !strconcat(opc, " $dst, $a, $b"), +/// AsXI1_bin_c_irs - Same as AsI1_bin_irs but without the predicate operand and +/// setting carry bit. But it can optionally set CPSR. +multiclass AsXI1_bin_c_irs { + def ri : AXI1<(ops GPR:$dst, GPR:$a, so_imm:$b, cc_out:$s), + !strconcat(opc, "${s} $dst, $a, $b"), [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>, Imp<[CPSR], []>; - def rr : AXI1<(ops GPR:$dst, GPR:$a, GPR:$b), - !strconcat(opc, " $dst, $a, $b"), + def rr : AXI1<(ops GPR:$dst, GPR:$a, GPR:$b, cc_out:$s), + !strconcat(opc, "${s} $dst, $a, $b"), [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>, Imp<[CPSR], []>; - def rs : AXI1<(ops GPR:$dst, GPR:$a, so_reg:$b), - !strconcat(opc, " $dst, $a, $b"), + def rs : AXI1<(ops GPR:$dst, GPR:$a, so_reg:$b, cc_out:$s), + !strconcat(opc, "${s} $dst, $a, $b"), [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>, Imp<[CPSR], []>; } @@ -649,7 +640,7 @@ let isLoad = 1, isReturn = 1, isTerminator = 1 in "ldm${p}${addr:submode} $addr, $dst1", []>; -let isCall = 1, noResults = 1, clobbersPred = 1, +let isCall = 1, noResults = 1, Defs = [R0, R1, R2, R3, R12, LR, D0, D1, D2, D3, D4, D5, D6, D7, CPSR] in { def BL : AXI<(ops i32imm:$func, variable_ops), @@ -697,7 +688,7 @@ let isBranch = 1, isTerminator = 1, noResults = 1 in { // FIXME: should be able to write a pattern for ARMBrcond, but can't use // a two-value operand where a dag node expects two operands. :( def Bcc : AI<(ops brtarget:$dst), "b", " $dst", - [/*(ARMbrcond bb:$dst, imm:$cc, CCR:$ccr)*/]>; + [/*(ARMbrcond bb:$dst, imm:$cc, CCR:$ccr)*/]>; } //===----------------------------------------------------------------------===// @@ -840,29 +831,28 @@ def STM : AXI4<(ops addrmode4:$addr, pred:$p, reglist:$src1, variable_ops), // Move Instructions. // -def MOVr : AI1<(ops GPR:$dst, GPR:$src), - "mov", " $dst, $src", []>; -def MOVs : AI1<(ops GPR:$dst, so_reg:$src), - "mov", " $dst, $src", [(set GPR:$dst, so_reg:$src)]>; +def MOVr : AsI1<(ops GPR:$dst, GPR:$src), + "mov", " $dst, $src", []>; +def MOVs : AsI1<(ops GPR:$dst, so_reg:$src), + "mov", " $dst, $src", [(set GPR:$dst, so_reg:$src)]>; let isReMaterializable = 1 in -def MOVi : AI1<(ops GPR:$dst, so_imm:$src), - "mov", " $dst, $src", [(set GPR:$dst, so_imm:$src)]>; +def MOVi : AsI1<(ops GPR:$dst, so_imm:$src), + "mov", " $dst, $src", [(set GPR:$dst, so_imm:$src)]>; + +def MOVrx : AsI1<(ops GPR:$dst, GPR:$src), + "mov", " $dst, $src, rrx", + [(set GPR:$dst, (ARMrrx GPR:$src))]>; // These aren't really mov instructions, but we have to define them this way // due to flag operands. -let clobbersPred = 1 in { def MOVsrl_flag : AI1<(ops GPR:$dst, GPR:$src), "mov", "s $dst, $src, lsr #1", [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, Imp<[], [CPSR]>; def MOVsra_flag : AI1<(ops GPR:$dst, GPR:$src), "mov", "s $dst, $src, asr #1", [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, Imp<[], [CPSR]>; -} -def MOVrx : AI1<(ops GPR:$dst, GPR:$src), - "mov", " $dst, $src, rrx", - [(set GPR:$dst, (ARMrrx GPR:$src))]>; //===----------------------------------------------------------------------===// // Extend Instructions. @@ -907,38 +897,40 @@ defm UXTAH : AI_bin_rrot<"uxtah", // Arithmetic Instructions. // -defm ADD : AI1_bin_irs<"add", BinOpFrag<(add node:$LHS, node:$RHS)>>; -defm SUB : AI1_bin_irs<"sub", BinOpFrag<(sub node:$LHS, node:$RHS)>>; +defm ADD : AsI1_bin_irs<"add", BinOpFrag<(add node:$LHS, node:$RHS)>>; +defm SUB : AsI1_bin_irs<"sub", BinOpFrag<(sub node:$LHS, node:$RHS)>>; // ADD and SUB with 's' bit set. -let clobbersPred = 1 in { -defm ADDS : AI1_bin_s_irs<"add", BinOpFrag<(addc node:$LHS, node:$RHS)>>; -defm SUBS : AI1_bin_s_irs<"sub", BinOpFrag<(subc node:$LHS, node:$RHS)>>; -} +defm ADDS : ASI1_bin_s_irs<"add", BinOpFrag<(addc node:$LHS, node:$RHS)>>; +defm SUBS : ASI1_bin_s_irs<"sub", BinOpFrag<(subc node:$LHS, node:$RHS)>>; // FIXME: Do not allow ADC / SBC to be predicated for now. -defm ADC : AXI1_bin_c_irs<"adc", BinOpFrag<(adde node:$LHS, node:$RHS)>>; -defm SBC : AXI1_bin_c_irs<"sbc", BinOpFrag<(sube node:$LHS, node:$RHS)>>; +defm ADC : AsXI1_bin_c_irs<"adc", BinOpFrag<(adde node:$LHS, node:$RHS)>>; +defm SBC : AsXI1_bin_c_irs<"sbc", BinOpFrag<(sube node:$LHS, node:$RHS)>>; // These don't define reg/reg forms, because they are handled above. -defm RSB : AI1_bin_is <"rsb", BinOpFrag<(sub node:$RHS, node:$LHS)>>; +def RSBri : AsI1<(ops GPR:$dst, GPR:$a, so_imm:$b), + "rsb", " $dst, $a, $b", + [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]>; + +def RSBrs : AsI1<(ops GPR:$dst, GPR:$a, so_reg:$b), + "rsb", " $dst, $a, $b", + [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]>; // RSB with 's' bit set. -let clobbersPred = 1 in { def RSBSri : AI1<(ops GPR:$dst, GPR:$a, so_imm:$b), "rsb", "s $dst, $a, $b", [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]>, Imp<[], [CPSR]>; def RSBSrs : AI1<(ops GPR:$dst, GPR:$a, so_reg:$b), "rsb", "s $dst, $a, $b", [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]>, Imp<[], [CPSR]>; -} -// FIXME: Do not allow RSC to be predicated for now. -def RSCri : AXI1<(ops GPR:$dst, GPR:$a, so_imm:$b), - "rsc $dst, $a, $b", +// FIXME: Do not allow RSC to be predicated for now. But they can set CPSR. +def RSCri : AXI1<(ops GPR:$dst, GPR:$a, so_imm:$b, cc_out:$s), + "rsc${s} $dst, $a, $b", [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>, Imp<[CPSR], []>; -def RSCrs : AXI1<(ops GPR:$dst, GPR:$a, so_reg:$b), - "rsc $dst, $a, $b", +def RSCrs : AXI1<(ops GPR:$dst, GPR:$a, so_reg:$b, cc_out:$s), + "rsc${s} $dst, $a, $b", [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>, Imp<[CPSR], []>; // (sub X, imm) gets canonicalized to (add X, -imm). Match this form. @@ -961,18 +953,18 @@ def : ARMPat<(add GPR:$src, so_imm_neg:$imm), // Bitwise Instructions. // -defm AND : AI1_bin_irs<"and", BinOpFrag<(and node:$LHS, node:$RHS)>>; -defm ORR : AI1_bin_irs<"orr", BinOpFrag<(or node:$LHS, node:$RHS)>>; -defm EOR : AI1_bin_irs<"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>>; -defm BIC : AI1_bin_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>; +defm AND : AsI1_bin_irs<"and", BinOpFrag<(and node:$LHS, node:$RHS)>>; +defm ORR : AsI1_bin_irs<"orr", BinOpFrag<(or node:$LHS, node:$RHS)>>; +defm EOR : AsI1_bin_irs<"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>>; +defm BIC : AsI1_bin_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>; -def MVNr : AI<(ops GPR:$dst, GPR:$src), - "mvn", " $dst, $src", [(set GPR:$dst, (not GPR:$src))]>; -def MVNs : AI<(ops GPR:$dst, so_reg:$src), - "mvn", " $dst, $src", [(set GPR:$dst, (not so_reg:$src))]>; +def MVNr : AsI<(ops GPR:$dst, GPR:$src), + "mvn", " $dst, $src", [(set GPR:$dst, (not GPR:$src))]>; +def MVNs : AsI<(ops GPR:$dst, so_reg:$src), + "mvn", " $dst, $src", [(set GPR:$dst, (not so_reg:$src))]>; let isReMaterializable = 1 in -def MVNi : AI<(ops GPR:$dst, so_imm:$imm), - "mvn", " $dst, $imm", [(set GPR:$dst, so_imm_not:$imm)]>; +def MVNi : AsI<(ops GPR:$dst, so_imm:$imm), + "mvn", " $dst, $imm", [(set GPR:$dst, so_imm_not:$imm)]>; def : ARMPat<(and GPR:$src, so_imm_not:$imm), (BICri GPR:$src, so_imm_not:$imm)>; @@ -981,46 +973,42 @@ def : ARMPat<(and GPR:$src, so_imm_not:$imm), // Multiply Instructions. // -// AI_orr - Defines a (op r, r) pattern. -class AI_orr - : AI<(ops GPR:$dst, GPR:$a, GPR:$b), - opc, " $dst, $a, $b", - [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>; - -// AI_oorr - Defines a (op (op r, r), r) pattern. -class AI_oorr - : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$c), - opc, " $dst, $a, $b, $c", - [(set GPR:$dst, (opnode1 (opnode2 GPR:$a, GPR:$b), GPR:$c))]>; +def MUL : AsI<(ops GPR:$dst, GPR:$a, GPR:$b), + "mul", " $dst, $a, $b", + [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>; -def MUL : AI_orr<"mul", mul>; -def MLA : AI_oorr<"mla", add, mul>; +def MLA : AsI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$c), + "mla", " $dst, $a, $b, $c", + [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>; // Extra precision multiplies with low / high results -def SMULL : AI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b), - "smull", " $ldst, $hdst, $a, $b", - []>; +def SMULL : AsI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b), + "smull", " $ldst, $hdst, $a, $b", []>; -def UMULL : AI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b), - "umull", " $ldst, $hdst, $a, $b", - []>; +def UMULL : AsI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b), + "umull", " $ldst, $hdst, $a, $b", []>; // Multiply + accumulate -def SMLAL : AI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b), - "smlal", " $ldst, $hdst, $a, $b", - []>; +def SMLAL : AsI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b), + "smlal", " $ldst, $hdst, $a, $b", []>; -def UMLAL : AI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b), - "umlal", " $ldst, $hdst, $a, $b", - []>; +def UMLAL : AsI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b), + "umlal", " $ldst, $hdst, $a, $b", []>; def UMAAL : AI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b), - "umaal", " $ldst, $hdst, $a, $b", - []>, Requires<[IsARM, HasV6]>; + "umaal", " $ldst, $hdst, $a, $b", []>, + Requires<[IsARM, HasV6]>; // Most significant word multiply -def SMMUL : AI_orr<"smmul", mulhs>, Requires<[IsARM, HasV6]>; -def SMMLA : AI_oorr<"smmla", add, mulhs>, Requires<[IsARM, HasV6]>; +def SMMUL : AI<(ops GPR:$dst, GPR:$a, GPR:$b), + "smmul", " $dst, $a, $b", + [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>, + Requires<[IsARM, HasV6]>; + +def SMMLA : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$c), + "smmla", " $dst, $a, $b, $c", + [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>, + Requires<[IsARM, HasV6]>; def SMMLS : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$c), @@ -1164,7 +1152,6 @@ def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), // Comparison Instructions... // -let clobbersPred = 1 in { defm CMP : AI1_cmp_irs<"cmp", BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>; defm CMN : AI1_cmp_irs<"cmn", BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>; @@ -1174,7 +1161,6 @@ defm TEQ : AI1_cmp_irs<"teq", BinOpFrag<(ARMcmpNZ (xor node:$LHS, node:$RHS), 0 defm CMPnz : AI1_cmp_irs<"cmp", BinOpFrag<(ARMcmpNZ node:$LHS, node:$RHS)>>; defm CMNnz : AI1_cmp_irs<"cmn", BinOpFrag<(ARMcmpNZ node:$LHS,(ineg node:$RHS))>>; -} def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm), (CMNri GPR:$src, so_imm_neg:$imm)>; @@ -1223,8 +1209,8 @@ def LEApcrelJT : AXI1<(ops GPR:$dst, i32imm:$label, i32imm:$id, pred:$p), // // __aeabi_read_tp preserves the registers r1-r3. -let isCall = 1, clobbersPred = 1, - Defs = [R0, R12, LR] in { +let isCall = 1, + Defs = [R0, R12, LR, CPSR] in { def TPsoft : AXI<(ops), "bl __aeabi_read_tp", [(set R0, ARMthread_pointer)]>; diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index 25e1872c8a1..27231daf133 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -33,7 +33,6 @@ class ThumbI pattern> // FIXME: Set all opcodes to 0 for now. : InstARM<0, am, sz, IndexModeNone, cstr> { - let clobbersPred = 1; let OperandList = ops; let AsmString = asm; let Pattern = pattern; diff --git a/lib/Target/ARM/ARMInstrVFP.td b/lib/Target/ARM/ARMInstrVFP.td index 9b10d1e687c..4bb9f0462e9 100644 --- a/lib/Target/ARM/ARMInstrVFP.td +++ b/lib/Target/ARM/ARMInstrVFP.td @@ -275,7 +275,6 @@ def FMDRR : ADI<(ops DPR:$dst, GPR:$src1, GPR:$src2), // FMSRR: GPR -> SPR -let clobbersPred = 1 in def FMSTAT : ASI<(ops), "fmstat", "", [(arm_fmstat)]>, Imp<[], [CPSR]>; // FMXR: GPR -> VFP Sstem reg diff --git a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp index 4d773343ab2..7562c5bf24d 100644 --- a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp +++ b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp @@ -158,7 +158,7 @@ static bool mergeOps(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, BuildMI(MBB, MBBI, TII->get(BaseOpc), NewBase) .addReg(Base, false, false, BaseKill).addImm(ImmedOffset) - .addImm(Pred).addReg(PredReg); + .addImm(Pred).addReg(PredReg).addReg(0); Base = NewBase; BaseKill = true; // New base is always killed right its use. } diff --git a/lib/Target/ARM/ARMRegisterInfo.cpp b/lib/Target/ARM/ARMRegisterInfo.cpp index 632530be8ca..05458e59f37 100644 --- a/lib/Target/ARM/ARMRegisterInfo.cpp +++ b/lib/Target/ARM/ARMRegisterInfo.cpp @@ -191,7 +191,7 @@ void ARMRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, BuildMI(MBB, I, TII.get(ARM::tMOVr), DestReg).addReg(SrcReg); else BuildMI(MBB, I, TII.get(ARM::MOVr), DestReg).addReg(SrcReg) - .addImm((int64_t)ARMCC::AL).addReg(0); + .addImm((int64_t)ARMCC::AL).addReg(0).addReg(0); } else if (RC == ARM::SPRRegisterClass) BuildMI(MBB, I, TII.get(ARM::FCPYS), DestReg).addReg(SrcReg) .addImm((int64_t)ARMCC::AL).addReg(0); @@ -258,6 +258,9 @@ MachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr *MI, switch (Opc) { default: break; case ARM::MOVr: { + if (MI->getOperand(4).getReg() == ARM::CPSR) + // If it is updating CPSR, then it cannot be foled. + break; unsigned Pred = MI->getOperand(2).getImmedValue(); unsigned PredReg = MI->getOperand(3).getReg(); if (OpNum == 0) { // move -> store @@ -454,7 +457,7 @@ void emitARMRegPlusImmediate(MachineBasicBlock &MBB, // Build the new ADD / SUB. BuildMI(MBB, MBBI, TII.get(isSub ? ARM::SUBri : ARM::ADDri), DestReg) .addReg(BaseReg, false, false, true).addImm(SOImmVal) - .addImm((unsigned)Pred).addReg(PredReg, false); + .addImm((unsigned)Pred).addReg(PredReg).addReg(0); BaseReg = DestReg; } } @@ -1380,7 +1383,7 @@ void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const { MachineInstrBuilder MIB = BuildMI(MBB, MBBI, TII.get(isThumb ? ARM::tADDrSPi : ARM::ADDri),FramePtr) .addFrameIndex(FramePtrSpillFI).addImm(0); - if (!isThumb) MIB.addImm(ARMCC::AL).addReg(0); + if (!isThumb) MIB.addImm(ARMCC::AL).addReg(0).addReg(0); } if (!isThumb) { @@ -1496,10 +1499,11 @@ void ARMRegisterInfo::emitEpilogue(MachineFunction &MF, hasFP(MF)) if (NumBytes) BuildMI(MBB, MBBI, TII.get(ARM::SUBri), ARM::SP).addReg(FramePtr) - .addImm(NumBytes).addImm((unsigned)ARMCC::AL).addReg(0); + .addImm(NumBytes) + .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0); else BuildMI(MBB, MBBI, TII.get(ARM::MOVr), ARM::SP).addReg(FramePtr) - .addImm((unsigned)ARMCC::AL).addReg(0); + .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0); } else if (NumBytes) { emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, false, TII); } -- 2.34.1