Index: include/llvm/MC/MCInstrDesc.h =================================================================== --- include/llvm/MC/MCInstrDesc.h +++ include/llvm/MC/MCInstrDesc.h @@ -100,6 +100,7 @@ Pseudo, Return, Call, + Add, Barrier, Terminator, Branch, @@ -197,26 +198,29 @@ /// operands. In this case, the variable operands will be after the normal /// operands but before the implicit definitions and uses (if any are /// present). - bool isVariadic() const { return Flags & (1 << MCID::Variadic); } + bool isVariadic() const { return Flags & (1ULL << MCID::Variadic); } /// \brief Set if this instruction has an optional definition, e.g. /// ARM instructions which can set condition code if 's' bit is set. - bool hasOptionalDef() const { return Flags & (1 << MCID::HasOptionalDef); } + bool hasOptionalDef() const { return Flags & (1ULL << MCID::HasOptionalDef); } /// \brief Return true if this is a pseudo instruction that doesn't /// correspond to a real machine instruction. - bool isPseudo() const { return Flags & (1 << MCID::Pseudo); } + bool isPseudo() const { return Flags & (1ULL << MCID::Pseudo); } /// \brief Return true if the instruction is a return. - bool isReturn() const { return Flags & (1 << MCID::Return); } + bool isReturn() const { return Flags & (1ULL << MCID::Return); } + + /// \brief Return true if the instruction is an add instruction. + bool isAdd() const { return Flags & (1ULL << MCID::Add); } /// \brief Return true if the instruction is a call. - bool isCall() const { return Flags & (1 << MCID::Call); } + bool isCall() const { return Flags & (1ULL << MCID::Call); } /// \brief Returns true if the specified instruction stops control flow /// from executing the instruction immediately following it. Examples include /// unconditional branches and return instructions. - bool isBarrier() const { return Flags & (1 << MCID::Barrier); } + bool isBarrier() const { return Flags & (1ULL << MCID::Barrier); } /// \brief Returns true if this instruction part of the terminator for /// a basic block. Typically this is things like return and branch @@ -224,17 +228,17 @@ /// /// Various passes use this to insert code into the bottom of a basic block, /// but before control flow occurs. - bool isTerminator() const { return Flags & (1 << MCID::Terminator); } + bool isTerminator() const { return Flags & (1ULL << MCID::Terminator); } /// \brief Returns true if this is a conditional, unconditional, or /// indirect branch. Predicates below can be used to discriminate between /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to /// get more information. - bool isBranch() const { return Flags & (1 << MCID::Branch); } + bool isBranch() const { return Flags & (1ULL << MCID::Branch); } /// \brief Return true if this is an indirect branch, such as a /// branch through a register. - bool isIndirectBranch() const { return Flags & (1 << MCID::IndirectBranch); } + bool isIndirectBranch() const { return Flags & (1ULL << MCID::IndirectBranch); } /// \brief Return true if this is a branch which may fall /// through to the next instruction or may transfer control flow to some other @@ -261,29 +265,29 @@ /// that controls execution. It may be set to 'always', or may be set to other /// values. There are various methods in TargetInstrInfo that can be used to /// control and modify the predicate in this instruction. - bool isPredicable() const { return Flags & (1 << MCID::Predicable); } + bool isPredicable() const { return Flags & (1ULL << MCID::Predicable); } /// \brief Return true if this instruction is a comparison. - bool isCompare() const { return Flags & (1 << MCID::Compare); } + bool isCompare() const { return Flags & (1ULL << MCID::Compare); } /// \brief Return true if this instruction is a move immediate /// (including conditional moves) instruction. - bool isMoveImmediate() const { return Flags & (1 << MCID::MoveImm); } + bool isMoveImmediate() const { return Flags & (1ULL << MCID::MoveImm); } /// \brief Return true if this instruction is a bitcast instruction. - bool isBitcast() const { return Flags & (1 << MCID::Bitcast); } + bool isBitcast() const { return Flags & (1ULL << MCID::Bitcast); } /// \brief Return true if this is a select instruction. - bool isSelect() const { return Flags & (1 << MCID::Select); } + bool isSelect() const { return Flags & (1ULL << MCID::Select); } /// \brief Return true if this instruction cannot be safely /// duplicated. For example, if the instruction has a unique labels attached /// to it, duplicating it would cause multiple definition errors. - bool isNotDuplicable() const { return Flags & (1 << MCID::NotDuplicable); } + bool isNotDuplicable() const { return Flags & (1ULL << MCID::NotDuplicable); } /// \brief Returns true if the specified instruction has a delay slot which /// must be filled by the code generator. - bool hasDelaySlot() const { return Flags & (1 << MCID::DelaySlot); } + bool hasDelaySlot() const { return Flags & (1ULL << MCID::DelaySlot); } /// \brief Return true for instructions that can be folded as memory operands /// in other instructions. The most common use for this is instructions that @@ -292,7 +296,7 @@ /// constant-pool loads, such as V_SETALLONES on x86, to allow them to be /// folded when it is beneficial. This should only be set on instructions /// that return a value in their only virtual register definition. - bool canFoldAsLoad() const { return Flags & (1 << MCID::FoldableAsLoad); } + bool canFoldAsLoad() const { return Flags & (1ULL << MCID::FoldableAsLoad); } /// \brief Return true if this instruction behaves /// the same way as the generic REG_SEQUENCE instructions. @@ -304,7 +308,7 @@ /// Note that for the optimizers to be able to take advantage of /// this property, TargetInstrInfo::getRegSequenceLikeInputs has to be /// override accordingly. - bool isRegSequenceLike() const { return Flags & (1 << MCID::RegSequence); } + bool isRegSequenceLike() const { return Flags & (1ULL << MCID::RegSequence); } /// \brief Return true if this instruction behaves /// the same way as the generic EXTRACT_SUBREG instructions. @@ -318,7 +322,7 @@ /// this property, TargetInstrInfo::getExtractSubregLikeInputs has to be /// override accordingly. bool isExtractSubregLike() const { - return Flags & (1 << MCID::ExtractSubreg); + return Flags & (1ULL << MCID::ExtractSubreg); } /// \brief Return true if this instruction behaves @@ -331,14 +335,14 @@ /// Note that for the optimizers to be able to take advantage of /// this property, TargetInstrInfo::getInsertSubregLikeInputs has to be /// override accordingly. - bool isInsertSubregLike() const { return Flags & (1 << MCID::InsertSubreg); } + bool isInsertSubregLike() const { return Flags & (1ULL << MCID::InsertSubreg); } /// \brief Return true if this instruction is convergent. /// /// Convergent instructions may not be made control-dependent on any /// additional values. - bool isConvergent() const { return Flags & (1 << MCID::Convergent); } + bool isConvergent() const { return Flags & (1ULL << MCID::Convergent); } //===--------------------------------------------------------------------===// // Side Effect Analysis @@ -347,13 +351,13 @@ /// \brief Return true if this instruction could possibly read memory. /// Instructions with this flag set are not necessarily simple load /// instructions, they may load a value and modify it, for example. - bool mayLoad() const { return Flags & (1 << MCID::MayLoad); } + bool mayLoad() const { return Flags & (1ULL << MCID::MayLoad); } /// \brief Return true if this instruction could possibly modify memory. /// Instructions with this flag set are not necessarily simple store /// instructions, they may store a modified value based on their operands, or /// may not actually modify anything, for example. - bool mayStore() const { return Flags & (1 << MCID::MayStore); } + bool mayStore() const { return Flags & (1ULL << MCID::MayStore); } /// \brief Return true if this instruction has side /// effects that are not modeled by other flags. This does not return true @@ -368,7 +372,7 @@ /// a control register, flushing a cache, modifying a register invisible to /// LLVM, etc. bool hasUnmodeledSideEffects() const { - return Flags & (1 << MCID::UnmodeledSideEffects); + return Flags & (1ULL << MCID::UnmodeledSideEffects); } //===--------------------------------------------------------------------===// @@ -385,7 +389,7 @@ /// sometimes. In these cases, the call to commuteInstruction will fail. /// Also note that some instructions require non-trivial modification to /// commute them. - bool isCommutable() const { return Flags & (1 << MCID::Commutable); } + bool isCommutable() const { return Flags & (1ULL << MCID::Commutable); } /// \brief Return true if this is a 2-address instruction which can be changed /// into a 3-address instruction if needed. Doing this transformation can be @@ -402,7 +406,7 @@ /// instruction (e.g. shl reg, 4 on x86). /// bool isConvertibleTo3Addr() const { - return Flags & (1 << MCID::ConvertibleTo3Addr); + return Flags & (1ULL << MCID::ConvertibleTo3Addr); } /// \brief Return true if this instruction requires custom insertion support @@ -414,14 +418,14 @@ /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method /// is used to insert this into the MachineBasicBlock. bool usesCustomInsertionHook() const { - return Flags & (1 << MCID::UsesCustomInserter); + return Flags & (1ULL << MCID::UsesCustomInserter); } /// \brief Return true if this instruction requires *adjustment* after /// instruction selection by calling a target hook. For example, this can be /// used to fill in ARM 's' optional operand depending on whether the /// conditional flag register is used. - bool hasPostISelHook() const { return Flags & (1 << MCID::HasPostISelHook); } + bool hasPostISelHook() const { return Flags & (1ULL << MCID::HasPostISelHook); } /// \brief Returns true if this instruction is a candidate for remat. This /// flag is only used in TargetInstrInfo method isTriviallyRematerializable. @@ -430,7 +434,7 @@ /// or isReallyTriviallyReMaterializableGeneric methods are called to verify /// the instruction is really rematable. bool isRematerializable() const { - return Flags & (1 << MCID::Rematerializable); + return Flags & (1ULL << MCID::Rematerializable); } /// \brief Returns true if this instruction has the same cost (or less) than a @@ -442,7 +446,7 @@ /// /// This method could be called by interface TargetInstrInfo::isAsCheapAsAMove /// for different subtargets. - bool isAsCheapAsAMove() const { return Flags & (1 << MCID::CheapAsAMove); } + bool isAsCheapAsAMove() const { return Flags & (1ULL << MCID::CheapAsAMove); } /// \brief Returns true if this instruction source operands have special /// register allocation requirements that are not captured by the operand @@ -451,7 +455,7 @@ /// allocation passes should not attempt to change allocations for sources of /// instructions with this flag. bool hasExtraSrcRegAllocReq() const { - return Flags & (1 << MCID::ExtraSrcRegAllocReq); + return Flags & (1ULL << MCID::ExtraSrcRegAllocReq); } /// \brief Returns true if this instruction def operands have special register @@ -461,7 +465,7 @@ /// allocation passes should not attempt to change allocations for definitions /// of instructions with this flag. bool hasExtraDefRegAllocReq() const { - return Flags & (1 << MCID::ExtraDefRegAllocReq); + return Flags & (1ULL << MCID::ExtraDefRegAllocReq); } /// \brief Return a list of registers that are potentially read by any Index: include/llvm/Target/Target.td =================================================================== --- include/llvm/Target/Target.td +++ include/llvm/Target/Target.td @@ -371,6 +371,7 @@ bit isSelect = 0; // Is this instruction a select instruction? bit isBarrier = 0; // Can control flow fall through this instruction? bit isCall = 0; // Is this instruction a call instruction? + bit isAdd = 0; // Is this instruction an add instruction? bit canFoldAsLoad = 0; // Can this be folded as a simple memory operand? bit mayLoad = ?; // Is it possible for this inst to read memory? bit mayStore = ?; // Is it possible for this inst to write memory? Index: lib/Target/ARM/ARMInstrInfo.td =================================================================== --- lib/Target/ARM/ARMInstrInfo.td +++ lib/Target/ARM/ARMInstrInfo.td @@ -3498,6 +3498,7 @@ // Arithmetic Instructions. // +let isAdd = 1 in defm ADD : AsI1_bin_irs<0b0100, "add", IIC_iALUi, IIC_iALUr, IIC_iALUsr, add, 1>; defm SUB : AsI1_bin_irs<0b0010, "sub", @@ -3513,9 +3514,11 @@ // FIXME: Eliminate ADDS/SUBS pseudo opcodes after adding tablegen // support for an optional CPSR definition that corresponds to the DAG // node's second value. We can then eliminate the implicit def of CPSR. +let isAdd = 1 in defm ADDS : AsI1_bin_s_irs; defm SUBS : AsI1_bin_s_irs; +let isAdd = 1 in defm ADC : AI1_adde_sube_irs<0b0101, "adc", ARMadde, 1>; defm SBC : AI1_adde_sube_irs<0b0110, "sbc", ARMsube>; Index: lib/Target/ARM/ARMInstrThumb.td =================================================================== --- lib/Target/ARM/ARMInstrThumb.td +++ lib/Target/ARM/ARMInstrThumb.td @@ -904,49 +904,51 @@ let Inst{7-0} = imm8; } -// Add with carry register -let isCommutable = 1, Uses = [CPSR] in -def tADC : // A8.6.2 - T1sItDPEncode<0b0101, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm), IIC_iALUr, - "adc", "\t$Rdn, $Rm", - [(set tGPR:$Rdn, (adde tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>; - -// Add immediate -def tADDi3 : // A8.6.4 T1 - T1sIGenEncodeImm<0b01110, (outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3), - IIC_iALUi, - "add", "\t$Rd, $Rm, $imm3", - [(set tGPR:$Rd, (add tGPR:$Rm, imm0_7:$imm3))]>, - Sched<[WriteALU]> { - bits<3> imm3; - let Inst{8-6} = imm3; -} - -def tADDi8 : // A8.6.4 T2 - T1sItGenEncodeImm<{1,1,0,?,?}, (outs tGPR:$Rdn), - (ins tGPR:$Rn, imm0_255:$imm8), IIC_iALUi, - "add", "\t$Rdn, $imm8", - [(set tGPR:$Rdn, (add tGPR:$Rn, imm8_255:$imm8))]>, - Sched<[WriteALU]>; +let isAdd = 1 in { + // Add with carry register + let isCommutable = 1, Uses = [CPSR] in + def tADC : // A8.6.2 + T1sItDPEncode<0b0101, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm), IIC_iALUr, + "adc", "\t$Rdn, $Rm", + [(set tGPR:$Rdn, (adde tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>; + + // Add immediate + def tADDi3 : // A8.6.4 T1 + T1sIGenEncodeImm<0b01110, (outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3), + IIC_iALUi, + "add", "\t$Rd, $Rm, $imm3", + [(set tGPR:$Rd, (add tGPR:$Rm, imm0_7:$imm3))]>, + Sched<[WriteALU]> { + bits<3> imm3; + let Inst{8-6} = imm3; + } -// Add register -let isCommutable = 1 in -def tADDrr : // A8.6.6 T1 - T1sIGenEncode<0b01100, (outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm), - IIC_iALUr, - "add", "\t$Rd, $Rn, $Rm", - [(set tGPR:$Rd, (add tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>; - -let hasSideEffects = 0 in -def tADDhirr : T1pIt<(outs GPR:$Rdn), (ins GPR:$Rn, GPR:$Rm), IIC_iALUr, - "add", "\t$Rdn, $Rm", []>, - T1Special<{0,0,?,?}>, Sched<[WriteALU]> { - // A8.6.6 T2 - bits<4> Rdn; - bits<4> Rm; - let Inst{7} = Rdn{3}; - let Inst{6-3} = Rm; - let Inst{2-0} = Rdn{2-0}; + def tADDi8 : // A8.6.4 T2 + T1sItGenEncodeImm<{1,1,0,?,?}, (outs tGPR:$Rdn), + (ins tGPR:$Rn, imm0_255:$imm8), IIC_iALUi, + "add", "\t$Rdn, $imm8", + [(set tGPR:$Rdn, (add tGPR:$Rn, imm8_255:$imm8))]>, + Sched<[WriteALU]>; + + // Add register + let isCommutable = 1 in + def tADDrr : // A8.6.6 T1 + T1sIGenEncode<0b01100, (outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm), + IIC_iALUr, + "add", "\t$Rd, $Rn, $Rm", + [(set tGPR:$Rd, (add tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>; + + let hasSideEffects = 0 in + def tADDhirr : T1pIt<(outs GPR:$Rdn), (ins GPR:$Rn, GPR:$Rm), IIC_iALUr, + "add", "\t$Rdn, $Rm", []>, + T1Special<{0,0,?,?}>, Sched<[WriteALU]> { + // A8.6.6 T2 + bits<4> Rdn; + bits<4> Rm; + let Inst{7} = Rdn{3}; + let Inst{6-3} = Rm; + let Inst{2-0} = Rdn{2-0}; + } } // AND register Index: lib/Target/ARM/ARMInstrThumb2.td =================================================================== --- lib/Target/ARM/ARMInstrThumb2.td +++ lib/Target/ARM/ARMInstrThumb2.td @@ -2038,6 +2038,7 @@ // Arithmetic Instructions. // +let isAdd = 1 in defm t2ADD : T2I_bin_ii12rs<0b000, "add", add, 1>; defm t2SUB : T2I_bin_ii12rs<0b101, "sub", sub>; Index: lib/Target/Hexagon/HexagonHardwareLoops.cpp =================================================================== --- lib/Target/Hexagon/HexagonHardwareLoops.cpp +++ lib/Target/Hexagon/HexagonHardwareLoops.cpp @@ -411,10 +411,8 @@ unsigned PhiOpReg = Phi->getOperand(i).getReg(); MachineInstr *DI = MRI->getVRegDef(PhiOpReg); - unsigned UpdOpc = DI->getOpcode(); - bool isAdd = (UpdOpc == Hexagon::A2_addi || UpdOpc == Hexagon::A2_addp); - if (isAdd) { + if (DI->getDesc().isAdd()) { // If the register operand to the add is the PHI we're looking at, this // meets the induction pattern. unsigned IndReg = DI->getOperand(1).getReg(); @@ -1592,10 +1590,8 @@ unsigned PhiReg = Phi->getOperand(i).getReg(); MachineInstr *DI = MRI->getVRegDef(PhiReg); - unsigned UpdOpc = DI->getOpcode(); - bool isAdd = (UpdOpc == Hexagon::A2_addi || UpdOpc == Hexagon::A2_addp); - if (isAdd) { + if (DI->getDesc().isAdd()) { // If the register operand to the add/sub is the PHI we are looking // at, this meets the induction pattern. unsigned IndReg = DI->getOperand(1).getReg(); Index: lib/Target/Hexagon/HexagonInstrInfo.td =================================================================== --- lib/Target/Hexagon/HexagonInstrInfo.td +++ lib/Target/Hexagon/HexagonInstrInfo.td @@ -406,7 +406,7 @@ let isExtendable = 1, isExtentSigned = 1, InputType = "imm" in multiclass Addri_base { let CextOpcode = mnemonic, BaseOpcode = mnemonic#_ri in { - let opExtendable = 2, opExtentBits = 16, isPredicable = 1 in + let opExtendable = 2, opExtentBits = 16, isPredicable = 1, isAdd = 1 in def A2_#NAME : T_Addri; let opExtendable = 3, opExtentBits = 8, isPredicated = 1 in { @@ -1292,6 +1292,7 @@ : T_ALU64_rr; +let isAdd = 1 in def A2_addp : T_ALU64_arith<"add", 0b000, 0b111, 0, 0, 1>; def A2_subp : T_ALU64_arith<"sub", 0b001, 0b111, 0, 1, 0>; Index: utils/TableGen/CodeGenInstruction.h =================================================================== --- utils/TableGen/CodeGenInstruction.h +++ utils/TableGen/CodeGenInstruction.h @@ -230,6 +230,7 @@ bool isSelect : 1; bool isBarrier : 1; bool isCall : 1; + bool isAdd : 1; bool canFoldAsLoad : 1; bool mayLoad : 1; bool mayLoad_Unset : 1; Index: utils/TableGen/InstrInfoEmitter.cpp =================================================================== --- utils/TableGen/InstrInfoEmitter.cpp +++ utils/TableGen/InstrInfoEmitter.cpp @@ -482,6 +482,7 @@ if (Inst.isCompare) OS << "|(1ULL<