diff --git a/lib/Target/Hexagon/Hexagon.td b/lib/Target/Hexagon/Hexagon.td index 9b3a64316aa..af1c56b8b14 100644 --- a/lib/Target/Hexagon/Hexagon.td +++ b/lib/Target/Hexagon/Hexagon.td @@ -83,30 +83,6 @@ def getPredOpcode : InstrMapping { let ValueCols = [["true"], ["false"]]; } -//===----------------------------------------------------------------------===// -// Generate mapping table to relate predicate-true instructions with their -// predicate-false forms -// -def getFalsePredOpcode : InstrMapping { - let FilterClass = "PredRel"; - let RowFields = ["BaseOpcode", "PNewValue", "isNVStore", "isBrTaken"]; - let ColFields = ["PredSense"]; - let KeyCol = ["true"]; - let ValueCols = [["false"]]; -} - -//===----------------------------------------------------------------------===// -// Generate mapping table to relate predicate-false instructions with their -// predicate-true forms -// -def getTruePredOpcode : InstrMapping { - let FilterClass = "PredRel"; - let RowFields = ["BaseOpcode", "PNewValue", "isNVStore", "isBrTaken"]; - let ColFields = ["PredSense"]; - let KeyCol = ["false"]; - let ValueCols = [["true"]]; -} - //===----------------------------------------------------------------------===// // Generate mapping table to relate predicated instructions with their .new // format. diff --git a/lib/Target/Hexagon/HexagonInstrInfo.cpp b/lib/Target/Hexagon/HexagonInstrInfo.cpp index 1298045e495..e0beab078f1 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -625,8 +625,110 @@ bool HexagonInstrInfo::isExtended(const MachineInstr *MI) const { return false; } -bool HexagonInstrInfo::isBranch (const MachineInstr *MI) const { - return MI->getDesc().isBranch(); +bool HexagonInstrInfo::isNewValueJump(const MachineInstr *MI) const { + switch (MI->getOpcode()) { + default: return false; + // JMP_EQri + case Hexagon::JMP_EQriPt_nv_V4: + case Hexagon::JMP_EQriPnt_nv_V4: + case Hexagon::JMP_EQriNotPt_nv_V4: + case Hexagon::JMP_EQriNotPnt_nv_V4: + case Hexagon::JMP_EQriPt_ie_nv_V4: + case Hexagon::JMP_EQriPnt_ie_nv_V4: + case Hexagon::JMP_EQriNotPt_ie_nv_V4: + case Hexagon::JMP_EQriNotPnt_ie_nv_V4: + + // JMP_EQri - with -1 + case Hexagon::JMP_EQriPtneg_nv_V4: + case Hexagon::JMP_EQriPntneg_nv_V4: + case Hexagon::JMP_EQriNotPtneg_nv_V4: + case Hexagon::JMP_EQriNotPntneg_nv_V4: + case Hexagon::JMP_EQriPtneg_ie_nv_V4: + case Hexagon::JMP_EQriPntneg_ie_nv_V4: + case Hexagon::JMP_EQriNotPtneg_ie_nv_V4: + case Hexagon::JMP_EQriNotPntneg_ie_nv_V4: + + // JMP_EQrr + case Hexagon::JMP_EQrrPt_nv_V4: + case Hexagon::JMP_EQrrPnt_nv_V4: + case Hexagon::JMP_EQrrNotPt_nv_V4: + case Hexagon::JMP_EQrrNotPnt_nv_V4: + case Hexagon::JMP_EQrrPt_ie_nv_V4: + case Hexagon::JMP_EQrrPnt_ie_nv_V4: + case Hexagon::JMP_EQrrNotPt_ie_nv_V4: + case Hexagon::JMP_EQrrNotPnt_ie_nv_V4: + + // JMP_GTri + case Hexagon::JMP_GTriPt_nv_V4: + case Hexagon::JMP_GTriPnt_nv_V4: + case Hexagon::JMP_GTriNotPt_nv_V4: + case Hexagon::JMP_GTriNotPnt_nv_V4: + case Hexagon::JMP_GTriPt_ie_nv_V4: + case Hexagon::JMP_GTriPnt_ie_nv_V4: + case Hexagon::JMP_GTriNotPt_ie_nv_V4: + case Hexagon::JMP_GTriNotPnt_ie_nv_V4: + + // JMP_GTri - with -1 + case Hexagon::JMP_GTriPtneg_nv_V4: + case Hexagon::JMP_GTriPntneg_nv_V4: + case Hexagon::JMP_GTriNotPtneg_nv_V4: + case Hexagon::JMP_GTriNotPntneg_nv_V4: + case Hexagon::JMP_GTriPtneg_ie_nv_V4: + case Hexagon::JMP_GTriPntneg_ie_nv_V4: + case Hexagon::JMP_GTriNotPtneg_ie_nv_V4: + case Hexagon::JMP_GTriNotPntneg_ie_nv_V4: + + // JMP_GTrr + case Hexagon::JMP_GTrrPt_nv_V4: + case Hexagon::JMP_GTrrPnt_nv_V4: + case Hexagon::JMP_GTrrNotPt_nv_V4: + case Hexagon::JMP_GTrrNotPnt_nv_V4: + case Hexagon::JMP_GTrrPt_ie_nv_V4: + case Hexagon::JMP_GTrrPnt_ie_nv_V4: + case Hexagon::JMP_GTrrNotPt_ie_nv_V4: + case Hexagon::JMP_GTrrNotPnt_ie_nv_V4: + + // JMP_GTrrdn + case Hexagon::JMP_GTrrdnPt_nv_V4: + case Hexagon::JMP_GTrrdnPnt_nv_V4: + case Hexagon::JMP_GTrrdnNotPt_nv_V4: + case Hexagon::JMP_GTrrdnNotPnt_nv_V4: + case Hexagon::JMP_GTrrdnPt_ie_nv_V4: + case Hexagon::JMP_GTrrdnPnt_ie_nv_V4: + case Hexagon::JMP_GTrrdnNotPt_ie_nv_V4: + case Hexagon::JMP_GTrrdnNotPnt_ie_nv_V4: + + // JMP_GTUri + case Hexagon::JMP_GTUriPt_nv_V4: + case Hexagon::JMP_GTUriPnt_nv_V4: + case Hexagon::JMP_GTUriNotPt_nv_V4: + case Hexagon::JMP_GTUriNotPnt_nv_V4: + case Hexagon::JMP_GTUriPt_ie_nv_V4: + case Hexagon::JMP_GTUriPnt_ie_nv_V4: + case Hexagon::JMP_GTUriNotPt_ie_nv_V4: + case Hexagon::JMP_GTUriNotPnt_ie_nv_V4: + + // JMP_GTUrr + case Hexagon::JMP_GTUrrPt_nv_V4: + case Hexagon::JMP_GTUrrPnt_nv_V4: + case Hexagon::JMP_GTUrrNotPt_nv_V4: + case Hexagon::JMP_GTUrrNotPnt_nv_V4: + case Hexagon::JMP_GTUrrPt_ie_nv_V4: + case Hexagon::JMP_GTUrrPnt_ie_nv_V4: + case Hexagon::JMP_GTUrrNotPt_ie_nv_V4: + case Hexagon::JMP_GTUrrNotPnt_ie_nv_V4: + + // JMP_GTUrrdn + case Hexagon::JMP_GTUrrdnPt_nv_V4: + case Hexagon::JMP_GTUrrdnPnt_nv_V4: + case Hexagon::JMP_GTUrrdnNotPt_nv_V4: + case Hexagon::JMP_GTUrrdnNotPnt_nv_V4: + case Hexagon::JMP_GTUrrdnPt_ie_nv_V4: + case Hexagon::JMP_GTUrrdnPnt_ie_nv_V4: + case Hexagon::JMP_GTUrrdnNotPt_ie_nv_V4: + case Hexagon::JMP_GTUrrdnNotPnt_ie_nv_V4: + return true; + } } bool HexagonInstrInfo::isNewValueStore(const MachineInstr *MI) const { @@ -930,12 +1032,6 @@ bool HexagonInstrInfo::isPredicable(MachineInstr *MI) const { // cNotPt ---> cNotPt_nv // cPt ---> cPt_nv unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const { - int InvPredOpcode; - InvPredOpcode = isPredicatedTrue(Opc) ? Hexagon::getFalsePredOpcode(Opc) - : Hexagon::getTruePredOpcode(Opc); - if (InvPredOpcode >= 0) // Valid instruction with the inverted predicate. - return InvPredOpcode; - switch(Opc) { default: llvm_unreachable("Unexpected predicated instruction"); case Hexagon::TFR_cPt: @@ -1268,6 +1364,117 @@ unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const { return Hexagon::DEALLOC_RET_cNotPt_V4; case Hexagon::DEALLOC_RET_cNotPt_V4: return Hexagon::DEALLOC_RET_cPt_V4; + + // New Value Jump. + // JMPEQ_ri - with -1. + case Hexagon::JMP_EQriPtneg_nv_V4: + return Hexagon::JMP_EQriNotPtneg_nv_V4; + case Hexagon::JMP_EQriNotPtneg_nv_V4: + return Hexagon::JMP_EQriPtneg_nv_V4; + + case Hexagon::JMP_EQriPntneg_nv_V4: + return Hexagon::JMP_EQriNotPntneg_nv_V4; + case Hexagon::JMP_EQriNotPntneg_nv_V4: + return Hexagon::JMP_EQriPntneg_nv_V4; + + // JMPEQ_ri. + case Hexagon::JMP_EQriPt_nv_V4: + return Hexagon::JMP_EQriNotPt_nv_V4; + case Hexagon::JMP_EQriNotPt_nv_V4: + return Hexagon::JMP_EQriPt_nv_V4; + + case Hexagon::JMP_EQriPnt_nv_V4: + return Hexagon::JMP_EQriNotPnt_nv_V4; + case Hexagon::JMP_EQriNotPnt_nv_V4: + return Hexagon::JMP_EQriPnt_nv_V4; + + // JMPEQ_rr. + case Hexagon::JMP_EQrrPt_nv_V4: + return Hexagon::JMP_EQrrNotPt_nv_V4; + case Hexagon::JMP_EQrrNotPt_nv_V4: + return Hexagon::JMP_EQrrPt_nv_V4; + + case Hexagon::JMP_EQrrPnt_nv_V4: + return Hexagon::JMP_EQrrNotPnt_nv_V4; + case Hexagon::JMP_EQrrNotPnt_nv_V4: + return Hexagon::JMP_EQrrPnt_nv_V4; + + // JMPGT_ri - with -1. + case Hexagon::JMP_GTriPtneg_nv_V4: + return Hexagon::JMP_GTriNotPtneg_nv_V4; + case Hexagon::JMP_GTriNotPtneg_nv_V4: + return Hexagon::JMP_GTriPtneg_nv_V4; + + case Hexagon::JMP_GTriPntneg_nv_V4: + return Hexagon::JMP_GTriNotPntneg_nv_V4; + case Hexagon::JMP_GTriNotPntneg_nv_V4: + return Hexagon::JMP_GTriPntneg_nv_V4; + + // JMPGT_ri. + case Hexagon::JMP_GTriPt_nv_V4: + return Hexagon::JMP_GTriNotPt_nv_V4; + case Hexagon::JMP_GTriNotPt_nv_V4: + return Hexagon::JMP_GTriPt_nv_V4; + + case Hexagon::JMP_GTriPnt_nv_V4: + return Hexagon::JMP_GTriNotPnt_nv_V4; + case Hexagon::JMP_GTriNotPnt_nv_V4: + return Hexagon::JMP_GTriPnt_nv_V4; + + // JMPGT_rr. + case Hexagon::JMP_GTrrPt_nv_V4: + return Hexagon::JMP_GTrrNotPt_nv_V4; + case Hexagon::JMP_GTrrNotPt_nv_V4: + return Hexagon::JMP_GTrrPt_nv_V4; + + case Hexagon::JMP_GTrrPnt_nv_V4: + return Hexagon::JMP_GTrrNotPnt_nv_V4; + case Hexagon::JMP_GTrrNotPnt_nv_V4: + return Hexagon::JMP_GTrrPnt_nv_V4; + + // JMPGT_rrdn. + case Hexagon::JMP_GTrrdnPt_nv_V4: + return Hexagon::JMP_GTrrdnNotPt_nv_V4; + case Hexagon::JMP_GTrrdnNotPt_nv_V4: + return Hexagon::JMP_GTrrdnPt_nv_V4; + + case Hexagon::JMP_GTrrdnPnt_nv_V4: + return Hexagon::JMP_GTrrdnNotPnt_nv_V4; + case Hexagon::JMP_GTrrdnNotPnt_nv_V4: + return Hexagon::JMP_GTrrdnPnt_nv_V4; + + // JMPGTU_ri. + case Hexagon::JMP_GTUriPt_nv_V4: + return Hexagon::JMP_GTUriNotPt_nv_V4; + case Hexagon::JMP_GTUriNotPt_nv_V4: + return Hexagon::JMP_GTUriPt_nv_V4; + + case Hexagon::JMP_GTUriPnt_nv_V4: + return Hexagon::JMP_GTUriNotPnt_nv_V4; + case Hexagon::JMP_GTUriNotPnt_nv_V4: + return Hexagon::JMP_GTUriPnt_nv_V4; + + // JMPGTU_rr. + case Hexagon::JMP_GTUrrPt_nv_V4: + return Hexagon::JMP_GTUrrNotPt_nv_V4; + case Hexagon::JMP_GTUrrNotPt_nv_V4: + return Hexagon::JMP_GTUrrPt_nv_V4; + + case Hexagon::JMP_GTUrrPnt_nv_V4: + return Hexagon::JMP_GTUrrNotPnt_nv_V4; + case Hexagon::JMP_GTUrrNotPnt_nv_V4: + return Hexagon::JMP_GTUrrPnt_nv_V4; + + // JMPGTU_rrdn. + case Hexagon::JMP_GTUrrdnPt_nv_V4: + return Hexagon::JMP_GTUrrdnNotPt_nv_V4; + case Hexagon::JMP_GTUrrdnNotPt_nv_V4: + return Hexagon::JMP_GTUrrdnPt_nv_V4; + + case Hexagon::JMP_GTUrrdnPnt_nv_V4: + return Hexagon::JMP_GTUrrdnNotPnt_nv_V4; + case Hexagon::JMP_GTUrrdnNotPnt_nv_V4: + return Hexagon::JMP_GTUrrdnPnt_nv_V4; } } @@ -1296,7 +1503,12 @@ getMatchingCondBranchOpcode(int Opc, bool invertPredicate) const { case Hexagon::JMP: return !invertPredicate ? Hexagon::JMP_t : Hexagon::JMP_f; - + case Hexagon::JMP_EQrrPt_nv_V4: + return !invertPredicate ? Hexagon::JMP_EQrrPt_nv_V4 : + Hexagon::JMP_EQrrNotPt_nv_V4; + case Hexagon::JMP_EQriPt_nv_V4: + return !invertPredicate ? Hexagon::JMP_EQriPt_nv_V4 : + Hexagon::JMP_EQriNotPt_nv_V4; case Hexagon::COMBINE_rr: return !invertPredicate ? Hexagon::COMBINE_rr_cPt : Hexagon::COMBINE_rr_cNotPt; @@ -1677,41 +1889,13 @@ isProfitableToIfCvt(MachineBasicBlock &TMBB, return true; } -// Returns true if an instruction is predicated irrespective of the predicate -// sense. For example, all of the following will return true. -// if (p0) R1 = add(R2, R3) -// if (!p0) R1 = add(R2, R3) -// if (p0.new) R1 = add(R2, R3) -// if (!p0.new) R1 = add(R2, R3) + bool HexagonInstrInfo::isPredicated(const MachineInstr *MI) const { const uint64_t F = MI->getDesc().TSFlags; return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask); } -bool HexagonInstrInfo::isPredicated(unsigned Opcode) const { - const uint64_t F = get(Opcode).TSFlags; - - return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask); -} - -bool HexagonInstrInfo::isPredicatedTrue(const MachineInstr *MI) const { - const uint64_t F = MI->getDesc().TSFlags; - - assert(isPredicated(MI)); - return (!((F >> HexagonII::PredicatedFalsePos) & - HexagonII::PredicatedFalseMask)); -} - -bool HexagonInstrInfo::isPredicatedTrue(unsigned Opcode) const { - const uint64_t F = get(Opcode).TSFlags; - - // Make sure that the instruction is predicated. - assert((F>> HexagonII::PredicatedPos) & HexagonII::PredicatedMask); - return (!((F >> HexagonII::PredicatedFalsePos) & - HexagonII::PredicatedFalseMask)); -} - bool HexagonInstrInfo::isPredicatedNew(const MachineInstr *MI) const { const uint64_t F = MI->getDesc().TSFlags; @@ -1719,13 +1903,6 @@ bool HexagonInstrInfo::isPredicatedNew(const MachineInstr *MI) const { return ((F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask); } -bool HexagonInstrInfo::isPredicatedNew(unsigned Opcode) const { - const uint64_t F = get(Opcode).TSFlags; - - assert(isPredicated(Opcode)); - return ((F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask); -} - bool HexagonInstrInfo::DefinesPredicate(MachineInstr *MI, std::vector &Pred) const { @@ -2194,18 +2371,6 @@ isConditionalStore (const MachineInstr* MI) const { } } - -bool HexagonInstrInfo::isNewValueJump(const MachineInstr *MI) const { - if (isNewValue(MI) && isBranch(MI)) - return true; - return false; -} - -bool HexagonInstrInfo::isNewValue(const MachineInstr* MI) const { - const uint64_t F = MI->getDesc().TSFlags; - return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask); -} - // Returns true, if any one of the operands is a dot new // insn, whether it is predicated dot new or register dot new. bool HexagonInstrInfo::isDotNewInst (const MachineInstr* MI) const { diff --git a/lib/Target/Hexagon/HexagonInstrInfo.h b/lib/Target/Hexagon/HexagonInstrInfo.h index b721da4620c..e0bec04e64f 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.h +++ b/lib/Target/Hexagon/HexagonInstrInfo.h @@ -113,7 +113,6 @@ public: unsigned createVR(MachineFunction* MF, MVT VT) const; - virtual bool isBranch(const MachineInstr *MI) const; virtual bool isPredicable(MachineInstr *MI) const; virtual bool PredicateInstruction(MachineInstr *MI, @@ -130,11 +129,7 @@ public: const BranchProbability &Probability) const; virtual bool isPredicated(const MachineInstr *MI) const; - virtual bool isPredicated(unsigned Opcode) const; - virtual bool isPredicatedTrue(const MachineInstr *MI) const; - virtual bool isPredicatedTrue(unsigned Opcode) const; virtual bool isPredicatedNew(const MachineInstr *MI) const; - virtual bool isPredicatedNew(unsigned Opcode) const; virtual bool DefinesPredicate(MachineInstr *MI, std::vector &Pred) const; virtual bool @@ -183,7 +178,6 @@ public: bool isConditionalLoad (const MachineInstr* MI) const; bool isConditionalStore(const MachineInstr* MI) const; bool isNewValueInst(const MachineInstr* MI) const; - bool isNewValue(const MachineInstr* MI) const; bool isDotNewInst(const MachineInstr* MI) const; bool isDeallocRet(const MachineInstr *MI) const; unsigned getInvertedPredicatedOpcode(const int Opc) const; diff --git a/lib/Target/Hexagon/HexagonInstrInfoV4.td b/lib/Target/Hexagon/HexagonInstrInfoV4.td index 933239d5c3a..744efe85ec3 100644 --- a/lib/Target/Hexagon/HexagonInstrInfoV4.td +++ b/lib/Target/Hexagon/HexagonInstrInfoV4.td @@ -967,194 +967,180 @@ defm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel; // NV/J + //===----------------------------------------------------------------------===// -//===----------------------------------------------------------------------===// -// multiclass/template class for the new-value compare jumps with the register -// operands. -//===----------------------------------------------------------------------===// +multiclass NVJ_type_basic_reg { + def _ie_nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1.new, $src2)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; -let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11 in -class NVJrr_template majOp, bit NvOpNum, - bit isNegCond, bit isTaken> - : NVInst_V4<(outs), - (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset), - "if ("#!if(isNegCond, "!","")#mnemonic# - "($src1"#!if(!eq(NvOpNum, 0),".new, ",", ")# - "$src2"#!if(!eq(NvOpNum, 1),".new))","))")#" jump:" - #!if(isTaken, "t","nt")#" $offset", - []>, Requires<[HasV4T]> { - - bits<5> src1; - bits<5> src2; - bits<3> Ns; // New-Value Operand - bits<5> RegOp; // Non New-Value Operand - bits<11> offset; - - let isBrTaken = !if(isTaken, "true", "false"); - let isPredicatedFalse = isNegCond; - - let Ns = !if(!eq(NvOpNum, 0), src1{2-0}, src2{2-0}); - let RegOp = !if(!eq(NvOpNum, 0), src2, src1); - - let IClass = 0b0010; - let Inst{26} = 0b0; - let Inst{25-23} = majOp; - let Inst{22} = isNegCond; - let Inst{18-16} = Ns; - let Inst{13} = isTaken; - let Inst{12-8} = RegOp; - let Inst{21-20} = offset{10-9}; - let Inst{7-1} = offset{8-2}; + def _nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1.new, $src2)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; } +multiclass NVJ_type_basic_2ndDotNew { + def _ie_nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1, $src2.new)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; -multiclass NVJrr_cond majOp, bit NvOpNum, - bit isNegCond> { - // Branch not taken: - def _nt_V4: NVJrr_template; - // Branch taken: - def _t_V4: NVJrr_template; + def _nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1, $src2.new)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; } -// NvOpNum = 0 -> First Operand is a new-value Register -// NvOpNum = 1 -> Second Operand is a new-value Register +multiclass NVJ_type_basic_imm { + def _ie_nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1.new, #$src2)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; -multiclass NVJrr_base majOp, - bit NvOpNum> { - let BaseOpcode = BaseOp#_NVJ in { - defm _t_Jumpnv : NVJrr_cond; // True cond - defm _f_Jumpnv : NVJrr_cond; // False cond - } + def _nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1.new, #$src2)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; } -// if ([!]cmp.eq(Ns.new,Rt)) jump:[n]t #r9:2 -// if ([!]cmp.gt(Ns.new,Rt)) jump:[n]t #r9:2 -// if ([!]cmp.gtu(Ns.new,Rt)) jump:[n]t #r9:2 -// if ([!]cmp.gt(Rt,Ns.new)) jump:[n]t #r9:2 -// if ([!]cmp.gtu(Rt,Ns.new)) jump:[n]t #r9:2 +multiclass NVJ_type_basic_neg { + def _ie_nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, nOneImm:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1.new, #$src2)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; -let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1, - Defs = [PC], neverHasSideEffects = 1, validSubTargets = HasV4SubT in { - defm CMPEQrr : NVJrr_base<"cmp.eq", "CMPEQ", 0b000, 0>, PredRel; - defm CMPGTrr : NVJrr_base<"cmp.gt", "CMPGT", 0b001, 0>, PredRel; - defm CMPGTUrr : NVJrr_base<"cmp.gtu", "CMPGTU", 0b010, 0>, PredRel; - defm CMPLTrr : NVJrr_base<"cmp.gt", "CMPLT", 0b011, 1>, PredRel; - defm CMPLTUrr : NVJrr_base<"cmp.gtu", "CMPLTU", 0b100, 1>, PredRel; + def _nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, nOneImm:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1.new, #$src2)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; +} + +multiclass NVJ_type_basic_tstbit { + def _ie_nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, u1Imm:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1.new, #$src2)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; + + def _nv_V4 : NVInst_V4<(outs), + (ins IntRegs:$src1, u1Imm:$src2, brtarget:$offset), + !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr, + !strconcat("($src1.new, #$src2)) jump:", + !strconcat(TakenStr, " $offset"))))), + []>, + Requires<[HasV4T]>; +} + +// Multiclass for regular dot new of Ist operand register. +multiclass NVJ_type_br_pred_reg { + defm Pt : NVJ_type_basic_reg; + defm Pnt : NVJ_type_basic_reg; +} + +// Multiclass for dot new of 2nd operand register. +multiclass NVJ_type_br_pred_2ndDotNew { + defm Pt : NVJ_type_basic_2ndDotNew; + defm Pnt : NVJ_type_basic_2ndDotNew; +} + +// Multiclass for 2nd operand immediate, including -1. +multiclass NVJ_type_br_pred_imm { + defm Pt : NVJ_type_basic_imm; + defm Pnt : NVJ_type_basic_imm; + defm Ptneg : NVJ_type_basic_neg; + defm Pntneg : NVJ_type_basic_neg; +} + +// Multiclass for 2nd operand immediate, excluding -1. +multiclass NVJ_type_br_pred_imm_only { + defm Pt : NVJ_type_basic_imm; + defm Pnt : NVJ_type_basic_imm; +} + +// Multiclass for tstbit, where 2nd operand is always #0. +multiclass NVJ_type_br_pred_tstbit { + defm Pt : NVJ_type_basic_tstbit; + defm Pnt : NVJ_type_basic_tstbit; +} + +// Multiclass for GT. +multiclass NVJ_type_rr_ri { + defm rrNot : NVJ_type_br_pred_reg<"!", OpcStr>; + defm rr : NVJ_type_br_pred_reg<"", OpcStr>; + defm rrdnNot : NVJ_type_br_pred_2ndDotNew<"!", OpcStr>; + defm rrdn : NVJ_type_br_pred_2ndDotNew<"", OpcStr>; + defm riNot : NVJ_type_br_pred_imm<"!", OpcStr>; + defm ri : NVJ_type_br_pred_imm<"", OpcStr>; +} + +// Multiclass for EQ. +multiclass NVJ_type_rr_ri_no_2ndDotNew { + defm rrNot : NVJ_type_br_pred_reg<"!", OpcStr>; + defm rr : NVJ_type_br_pred_reg<"", OpcStr>; + defm riNot : NVJ_type_br_pred_imm<"!", OpcStr>; + defm ri : NVJ_type_br_pred_imm<"", OpcStr>; +} + +// Multiclass for GTU. +multiclass NVJ_type_rr_ri_no_nOne { + defm rrNot : NVJ_type_br_pred_reg<"!", OpcStr>; + defm rr : NVJ_type_br_pred_reg<"", OpcStr>; + defm rrdnNot : NVJ_type_br_pred_2ndDotNew<"!", OpcStr>; + defm rrdn : NVJ_type_br_pred_2ndDotNew<"", OpcStr>; + defm riNot : NVJ_type_br_pred_imm_only<"!", OpcStr>; + defm ri : NVJ_type_br_pred_imm_only<"", OpcStr>; +} + +// Multiclass for tstbit. +multiclass NVJ_type_r0 { + defm r0Not : NVJ_type_br_pred_tstbit<"!", OpcStr>; + defm r0 : NVJ_type_br_pred_tstbit<"", OpcStr>; + } + +// Base Multiclass for New Value Jump. +multiclass NVJ_type { + defm GT : NVJ_type_rr_ri<"cmp.gt">; + defm EQ : NVJ_type_rr_ri_no_2ndDotNew<"cmp.eq">; + defm GTU : NVJ_type_rr_ri_no_nOne<"cmp.gtu">; + defm TSTBIT : NVJ_type_r0<"tstbit">; +} + +let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC] in { + defm JMP_ : NVJ_type; } //===----------------------------------------------------------------------===// -// multiclass/template class for the new-value compare jumps instruction -// with a register and an unsigned immediate (U5) operand. +// NV/J - //===----------------------------------------------------------------------===// -let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11 in -class NVJri_template majOp, bit isNegCond, - bit isTaken> - : NVInst_V4<(outs), - (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset), - "if ("#!if(isNegCond, "!","")#mnemonic#"($src1.new, #$src2)) jump:" - #!if(isTaken, "t","nt")#" $offset", - []>, Requires<[HasV4T]> { - - let isPredicatedFalse = isNegCond; - let isBrTaken = !if(isTaken, "true", "false"); - - bits<3> src1; - bits<5> src2; - bits<11> offset; - - let IClass = 0b0010; - let Inst{26} = 0b1; - let Inst{25-23} = majOp; - let Inst{22} = isNegCond; - let Inst{18-16} = src1; - let Inst{13} = isTaken; - let Inst{12-8} = src2; - let Inst{21-20} = offset{10-9}; - let Inst{7-1} = offset{8-2}; -} - -multiclass NVJri_cond majOp, bit isNegCond> { - // Branch not taken: - def _nt_V4: NVJri_template; - // Branch taken: - def _t_V4: NVJri_template; -} - -multiclass NVJri_base majOp> { - let BaseOpcode = BaseOp#_NVJri in { - defm _t_Jumpnv : NVJri_cond; // True Cond - defm _f_Jumpnv : NVJri_cond; // False cond - } -} - -// if ([!]cmp.eq(Ns.new,#U5)) jump:[n]t #r9:2 -// if ([!]cmp.gt(Ns.new,#U5)) jump:[n]t #r9:2 -// if ([!]cmp.gtu(Ns.new,#U5)) jump:[n]t #r9:2 - -let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1, - Defs = [PC], neverHasSideEffects = 1, validSubTargets = HasV4SubT in { - defm CMPEQri : NVJri_base<"cmp.eq", "CMPEQ", 0b000>, PredRel; - defm CMPGTri : NVJri_base<"cmp.gt", "CMPGT", 0b001>, PredRel; - defm CMPGTUri : NVJri_base<"cmp.gtu", "CMPGTU", 0b010>, PredRel; -} - -//===----------------------------------------------------------------------===// -// multiclass/template class for the new-value compare jumps instruction -// with a register and an hardcoded 0/-1 immediate value. -//===----------------------------------------------------------------------===// - -let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 11 in -class NVJ_ConstImm_template majOp, string ImmVal, - bit isNegCond, bit isTaken> - : NVInst_V4<(outs), - (ins IntRegs:$src1, brtarget:$offset), - "if ("#!if(isNegCond, "!","")#mnemonic - #"($src1.new, #"#ImmVal#")) jump:" - #!if(isTaken, "t","nt")#" $offset", - []>, Requires<[HasV4T]> { - - let isPredicatedFalse = isNegCond; - let isBrTaken = !if(isTaken, "true", "false"); - - bits<3> src1; - bits<11> offset; - let IClass = 0b0010; - let Inst{26} = 0b1; - let Inst{25-23} = majOp; - let Inst{22} = isNegCond; - let Inst{18-16} = src1; - let Inst{13} = isTaken; - let Inst{21-20} = offset{10-9}; - let Inst{7-1} = offset{8-2}; -} - -multiclass NVJ_ConstImm_cond majOp, string ImmVal, - bit isNegCond> { - // Branch not taken: - def _nt_V4: NVJ_ConstImm_template; - // Branch taken: - def _t_V4: NVJ_ConstImm_template; -} - -multiclass NVJ_ConstImm_base majOp, - string ImmVal> { - let BaseOpcode = BaseOp#_NVJ_ConstImm in { - defm _t_Jumpnv : NVJ_ConstImm_cond; // True cond - defm _f_Jumpnv : NVJ_ConstImm_cond; // False Cond - } -} - -// if ([!]tstbit(Ns.new,#0)) jump:[n]t #r9:2 -// if ([!]cmp.eq(Ns.new,#-1)) jump:[n]t #r9:2 -// if ([!]cmp.gt(Ns.new,#-1)) jump:[n]t #r9:2 - -let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator=1, - Defs = [PC], neverHasSideEffects = 1 in { - defm TSTBIT0 : NVJ_ConstImm_base<"tstbit", "TSTBIT", 0b011, "0">, PredRel; - defm CMPEQn1 : NVJ_ConstImm_base<"cmp.eq", "CMPEQ", 0b100, "-1">, PredRel; - defm CMPGTn1 : NVJ_ConstImm_base<"cmp.gt", "CMPGT", 0b101, "-1">, PredRel; -} - //===----------------------------------------------------------------------===// // XTYPE/ALU + //===----------------------------------------------------------------------===// @@ -3021,10 +3007,9 @@ def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))), // Transfer global address into a register -let isExtended = 1, opExtendable = 1, AddedComplexity=50, isMoveImm = 1, -isAsCheapAsAMove = 1, isReMaterializable = 1, validSubTargets = HasV4SubT in -def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins s16Ext:$src1), - "$dst = #$src1", +let AddedComplexity=50, isMoveImm = 1, isReMaterializable = 1 in +def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$src1), + "$dst = ##$src1", [(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>, Requires<[HasV4T]>; diff --git a/lib/Target/Hexagon/HexagonNewValueJump.cpp b/lib/Target/Hexagon/HexagonNewValueJump.cpp index 05e696865fb..72af87659e1 100644 --- a/lib/Target/Hexagon/HexagonNewValueJump.cpp +++ b/lib/Target/Hexagon/HexagonNewValueJump.cpp @@ -22,31 +22,29 @@ // //===----------------------------------------------------------------------===// #define DEBUG_TYPE "hexagon-nvj" -#include "llvm/PassSupport.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/Debug.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/CodeGen/Passes.h" -#include "llvm/CodeGen/ScheduleDAGInstrs.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/LiveVariables.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/MachineFunctionAnalysis.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetRegisterInfo.h" #include "Hexagon.h" -#include "HexagonTargetMachine.h" -#include "HexagonRegisterInfo.h" -#include "HexagonSubtarget.h" #include "HexagonInstrInfo.h" #include "HexagonMachineFunctionInfo.h" - -#include - +#include "HexagonRegisterInfo.h" +#include "HexagonSubtarget.h" +#include "HexagonTargetMachine.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/CodeGen/LiveVariables.h" +#include "llvm/CodeGen/MachineFunctionAnalysis.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/ScheduleDAGInstrs.h" +#include "llvm/PassSupport.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include using namespace llvm; STATISTIC(NumNVJGenerated, "Number of New Value Jump Instructions created"); @@ -59,11 +57,6 @@ static cl::opt DisableNewValueJumps("disable-nvjump", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Disable New Value Jumps")); -namespace llvm { - void initializeHexagonNewValueJumpPass(PassRegistry&); -} - - namespace { struct HexagonNewValueJump : public MachineFunctionPass { const HexagonInstrInfo *QII; @@ -72,9 +65,7 @@ namespace { public: static char ID; - HexagonNewValueJump() : MachineFunctionPass(ID) { - initializeHexagonNewValueJumpPass(*PassRegistry::getPassRegistry()); - } + HexagonNewValueJump() : MachineFunctionPass(ID) { } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); @@ -97,13 +88,6 @@ namespace { char HexagonNewValueJump::ID = 0; -INITIALIZE_PASS_BEGIN(HexagonNewValueJump, "hexagon-nvj", - "Hexagon NewValueJump", false, false) -INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo) -INITIALIZE_PASS_END(HexagonNewValueJump, "hexagon-nvj", - "Hexagon NewValueJump", false, false) - - // We have identified this II could be feeder to NVJ, // verify that it can be. static bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII, @@ -235,7 +219,7 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII, return false; } - unsigned cmpReg1, cmpOp2 = 0; // cmpOp2 assignment silences compiler warning. + unsigned cmpReg1, cmpOp2; cmpReg1 = MI->getOperand(1).getReg(); if (secondReg) { @@ -301,48 +285,43 @@ static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg, switch (MI->getOpcode()) { case Hexagon::CMPEQrr: - return taken ? Hexagon::CMPEQrr_t_Jumpnv_t_V4 - : Hexagon::CMPEQrr_t_Jumpnv_nt_V4; + return taken ? Hexagon::JMP_EQrrPt_nv_V4 : Hexagon::JMP_EQrrPnt_nv_V4; case Hexagon::CMPEQri: { if (reg >= 0) - return taken ? Hexagon::CMPEQri_t_Jumpnv_t_V4 - : Hexagon::CMPEQri_t_Jumpnv_nt_V4; + return taken ? Hexagon::JMP_EQriPt_nv_V4 : Hexagon::JMP_EQriPnt_nv_V4; else - return taken ? Hexagon::CMPEQn1_t_Jumpnv_t_V4 - : Hexagon::CMPEQn1_t_Jumpnv_nt_V4; + return taken ? Hexagon::JMP_EQriPtneg_nv_V4 + : Hexagon::JMP_EQriPntneg_nv_V4; } case Hexagon::CMPGTrr: { if (secondRegNewified) - return taken ? Hexagon::CMPLTrr_t_Jumpnv_t_V4 - : Hexagon::CMPLTrr_t_Jumpnv_nt_V4; + return taken ? Hexagon::JMP_GTrrdnPt_nv_V4 + : Hexagon::JMP_GTrrdnPnt_nv_V4; else - return taken ? Hexagon::CMPGTrr_t_Jumpnv_t_V4 - : Hexagon::CMPGTrr_t_Jumpnv_nt_V4; + return taken ? Hexagon::JMP_GTrrPt_nv_V4 + : Hexagon::JMP_GTrrPnt_nv_V4; } case Hexagon::CMPGTri: { if (reg >= 0) - return taken ? Hexagon::CMPGTri_t_Jumpnv_t_V4 - : Hexagon::CMPGTri_t_Jumpnv_nt_V4; + return taken ? Hexagon::JMP_GTriPt_nv_V4 : Hexagon::JMP_GTriPnt_nv_V4; else - return taken ? Hexagon::CMPGTn1_t_Jumpnv_t_V4 - : Hexagon::CMPGTn1_t_Jumpnv_nt_V4; + return taken ? Hexagon::JMP_GTriPtneg_nv_V4 + : Hexagon::JMP_GTriPntneg_nv_V4; } case Hexagon::CMPGTUrr: { if (secondRegNewified) - return taken ? Hexagon::CMPLTUrr_t_Jumpnv_t_V4 - : Hexagon::CMPLTUrr_t_Jumpnv_nt_V4; + return taken ? Hexagon::JMP_GTUrrdnPt_nv_V4 + : Hexagon::JMP_GTUrrdnPnt_nv_V4; else - return taken ? Hexagon::CMPGTUrr_t_Jumpnv_t_V4 - : Hexagon::CMPGTUrr_t_Jumpnv_nt_V4; + return taken ? Hexagon::JMP_GTUrrPt_nv_V4 : Hexagon::JMP_GTUrrPnt_nv_V4; } case Hexagon::CMPGTUri: - return taken ? Hexagon::CMPGTUri_t_Jumpnv_t_V4 - : Hexagon::CMPGTUri_t_Jumpnv_nt_V4; + return taken ? Hexagon::JMP_GTUriPt_nv_V4 : Hexagon::JMP_GTUriPnt_nv_V4; default: llvm_unreachable("Could not find matching New Value Jump instruction.");