mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 17:32:19 +00:00
reverting r180953
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180964 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5ed88013e8
commit
d4f8a6b9e9
@ -83,30 +83,6 @@ def getPredOpcode : InstrMapping {
|
|||||||
let ValueCols = [["true"], ["false"]];
|
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
|
// Generate mapping table to relate predicated instructions with their .new
|
||||||
// format.
|
// format.
|
||||||
|
@ -625,8 +625,110 @@ bool HexagonInstrInfo::isExtended(const MachineInstr *MI) const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HexagonInstrInfo::isBranch (const MachineInstr *MI) const {
|
bool HexagonInstrInfo::isNewValueJump(const MachineInstr *MI) const {
|
||||||
return MI->getDesc().isBranch();
|
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 {
|
bool HexagonInstrInfo::isNewValueStore(const MachineInstr *MI) const {
|
||||||
@ -930,12 +1032,6 @@ bool HexagonInstrInfo::isPredicable(MachineInstr *MI) const {
|
|||||||
// cNotPt ---> cNotPt_nv
|
// cNotPt ---> cNotPt_nv
|
||||||
// cPt ---> cPt_nv
|
// cPt ---> cPt_nv
|
||||||
unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const {
|
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) {
|
switch(Opc) {
|
||||||
default: llvm_unreachable("Unexpected predicated instruction");
|
default: llvm_unreachable("Unexpected predicated instruction");
|
||||||
case Hexagon::TFR_cPt:
|
case Hexagon::TFR_cPt:
|
||||||
@ -1268,6 +1364,117 @@ unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const {
|
|||||||
return Hexagon::DEALLOC_RET_cNotPt_V4;
|
return Hexagon::DEALLOC_RET_cNotPt_V4;
|
||||||
case Hexagon::DEALLOC_RET_cNotPt_V4:
|
case Hexagon::DEALLOC_RET_cNotPt_V4:
|
||||||
return Hexagon::DEALLOC_RET_cPt_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:
|
case Hexagon::JMP:
|
||||||
return !invertPredicate ? Hexagon::JMP_t :
|
return !invertPredicate ? Hexagon::JMP_t :
|
||||||
Hexagon::JMP_f;
|
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:
|
case Hexagon::COMBINE_rr:
|
||||||
return !invertPredicate ? Hexagon::COMBINE_rr_cPt :
|
return !invertPredicate ? Hexagon::COMBINE_rr_cPt :
|
||||||
Hexagon::COMBINE_rr_cNotPt;
|
Hexagon::COMBINE_rr_cNotPt;
|
||||||
@ -1677,41 +1889,13 @@ isProfitableToIfCvt(MachineBasicBlock &TMBB,
|
|||||||
return true;
|
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 {
|
bool HexagonInstrInfo::isPredicated(const MachineInstr *MI) const {
|
||||||
const uint64_t F = MI->getDesc().TSFlags;
|
const uint64_t F = MI->getDesc().TSFlags;
|
||||||
|
|
||||||
return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask);
|
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 {
|
bool HexagonInstrInfo::isPredicatedNew(const MachineInstr *MI) const {
|
||||||
const uint64_t F = MI->getDesc().TSFlags;
|
const uint64_t F = MI->getDesc().TSFlags;
|
||||||
|
|
||||||
@ -1719,13 +1903,6 @@ bool HexagonInstrInfo::isPredicatedNew(const MachineInstr *MI) const {
|
|||||||
return ((F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask);
|
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
|
bool
|
||||||
HexagonInstrInfo::DefinesPredicate(MachineInstr *MI,
|
HexagonInstrInfo::DefinesPredicate(MachineInstr *MI,
|
||||||
std::vector<MachineOperand> &Pred) const {
|
std::vector<MachineOperand> &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
|
// Returns true, if any one of the operands is a dot new
|
||||||
// insn, whether it is predicated dot new or register dot new.
|
// insn, whether it is predicated dot new or register dot new.
|
||||||
bool HexagonInstrInfo::isDotNewInst (const MachineInstr* MI) const {
|
bool HexagonInstrInfo::isDotNewInst (const MachineInstr* MI) const {
|
||||||
|
@ -113,7 +113,6 @@ public:
|
|||||||
|
|
||||||
unsigned createVR(MachineFunction* MF, MVT VT) const;
|
unsigned createVR(MachineFunction* MF, MVT VT) const;
|
||||||
|
|
||||||
virtual bool isBranch(const MachineInstr *MI) const;
|
|
||||||
virtual bool isPredicable(MachineInstr *MI) const;
|
virtual bool isPredicable(MachineInstr *MI) const;
|
||||||
virtual bool
|
virtual bool
|
||||||
PredicateInstruction(MachineInstr *MI,
|
PredicateInstruction(MachineInstr *MI,
|
||||||
@ -130,11 +129,7 @@ public:
|
|||||||
const BranchProbability &Probability) const;
|
const BranchProbability &Probability) const;
|
||||||
|
|
||||||
virtual bool isPredicated(const MachineInstr *MI) 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(const MachineInstr *MI) const;
|
||||||
virtual bool isPredicatedNew(unsigned Opcode) const;
|
|
||||||
virtual bool DefinesPredicate(MachineInstr *MI,
|
virtual bool DefinesPredicate(MachineInstr *MI,
|
||||||
std::vector<MachineOperand> &Pred) const;
|
std::vector<MachineOperand> &Pred) const;
|
||||||
virtual bool
|
virtual bool
|
||||||
@ -183,7 +178,6 @@ public:
|
|||||||
bool isConditionalLoad (const MachineInstr* MI) const;
|
bool isConditionalLoad (const MachineInstr* MI) const;
|
||||||
bool isConditionalStore(const MachineInstr* MI) const;
|
bool isConditionalStore(const MachineInstr* MI) const;
|
||||||
bool isNewValueInst(const MachineInstr* MI) const;
|
bool isNewValueInst(const MachineInstr* MI) const;
|
||||||
bool isNewValue(const MachineInstr* MI) const;
|
|
||||||
bool isDotNewInst(const MachineInstr* MI) const;
|
bool isDotNewInst(const MachineInstr* MI) const;
|
||||||
bool isDeallocRet(const MachineInstr *MI) const;
|
bool isDeallocRet(const MachineInstr *MI) const;
|
||||||
unsigned getInvertedPredicatedOpcode(const int Opc) const;
|
unsigned getInvertedPredicatedOpcode(const int Opc) const;
|
||||||
|
@ -967,194 +967,180 @@ defm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel;
|
|||||||
// NV/J +
|
// NV/J +
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
multiclass NVJ_type_basic_reg<string NotStr, string OpcStr, string TakenStr> {
|
||||||
// multiclass/template class for the new-value compare jumps with the register
|
def _ie_nv_V4 : NVInst_V4<(outs),
|
||||||
// operands.
|
(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
|
def _nv_V4 : NVInst_V4<(outs),
|
||||||
class NVJrr_template<string mnemonic, bits<3> majOp, bit NvOpNum,
|
(ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
|
||||||
bit isNegCond, bit isTaken>
|
!strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
|
||||||
: NVInst_V4<(outs),
|
!strconcat("($src1.new, $src2)) jump:",
|
||||||
(ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
|
!strconcat(TakenStr, " $offset"))))),
|
||||||
"if ("#!if(isNegCond, "!","")#mnemonic#
|
[]>,
|
||||||
"($src1"#!if(!eq(NvOpNum, 0),".new, ",", ")#
|
Requires<[HasV4T]>;
|
||||||
"$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};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
multiclass NVJ_type_basic_2ndDotNew<string NotStr, string OpcStr,
|
||||||
|
string TakenStr> {
|
||||||
|
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<string mnemonic, bits<3> majOp, bit NvOpNum,
|
def _nv_V4 : NVInst_V4<(outs),
|
||||||
bit isNegCond> {
|
(ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
|
||||||
// Branch not taken:
|
!strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
|
||||||
def _nt_V4: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 0>;
|
!strconcat("($src1, $src2.new)) jump:",
|
||||||
// Branch taken:
|
!strconcat(TakenStr, " $offset"))))),
|
||||||
def _t_V4: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 1>;
|
[]>,
|
||||||
|
Requires<[HasV4T]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NvOpNum = 0 -> First Operand is a new-value Register
|
multiclass NVJ_type_basic_imm<string NotStr, string OpcStr, string TakenStr> {
|
||||||
// NvOpNum = 1 -> Second Operand is a new-value Register
|
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<string mnemonic, string BaseOp, bits<3> majOp,
|
def _nv_V4 : NVInst_V4<(outs),
|
||||||
bit NvOpNum> {
|
(ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset),
|
||||||
let BaseOpcode = BaseOp#_NVJ in {
|
!strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
|
||||||
defm _t_Jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 0>; // True cond
|
!strconcat("($src1.new, #$src2)) jump:",
|
||||||
defm _f_Jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 1>; // False cond
|
!strconcat(TakenStr, " $offset"))))),
|
||||||
}
|
[]>,
|
||||||
|
Requires<[HasV4T]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if ([!]cmp.eq(Ns.new,Rt)) jump:[n]t #r9:2
|
multiclass NVJ_type_basic_neg<string NotStr, string OpcStr, string TakenStr> {
|
||||||
// if ([!]cmp.gt(Ns.new,Rt)) jump:[n]t #r9:2
|
def _ie_nv_V4 : NVInst_V4<(outs),
|
||||||
// if ([!]cmp.gtu(Ns.new,Rt)) jump:[n]t #r9:2
|
(ins IntRegs:$src1, nOneImm:$src2, brtarget:$offset),
|
||||||
// if ([!]cmp.gt(Rt,Ns.new)) jump:[n]t #r9:2
|
!strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
|
||||||
// if ([!]cmp.gtu(Rt,Ns.new)) jump:[n]t #r9:2
|
!strconcat("($src1.new, #$src2)) jump:",
|
||||||
|
!strconcat(TakenStr, " $offset"))))),
|
||||||
|
[]>,
|
||||||
|
Requires<[HasV4T]>;
|
||||||
|
|
||||||
let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1,
|
def _nv_V4 : NVInst_V4<(outs),
|
||||||
Defs = [PC], neverHasSideEffects = 1, validSubTargets = HasV4SubT in {
|
(ins IntRegs:$src1, nOneImm:$src2, brtarget:$offset),
|
||||||
defm CMPEQrr : NVJrr_base<"cmp.eq", "CMPEQ", 0b000, 0>, PredRel;
|
!strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
|
||||||
defm CMPGTrr : NVJrr_base<"cmp.gt", "CMPGT", 0b001, 0>, PredRel;
|
!strconcat("($src1.new, #$src2)) jump:",
|
||||||
defm CMPGTUrr : NVJrr_base<"cmp.gtu", "CMPGTU", 0b010, 0>, PredRel;
|
!strconcat(TakenStr, " $offset"))))),
|
||||||
defm CMPLTrr : NVJrr_base<"cmp.gt", "CMPLT", 0b011, 1>, PredRel;
|
[]>,
|
||||||
defm CMPLTUrr : NVJrr_base<"cmp.gtu", "CMPLTU", 0b100, 1>, PredRel;
|
Requires<[HasV4T]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
multiclass NVJ_type_basic_tstbit<string NotStr, string OpcStr,
|
||||||
|
string TakenStr> {
|
||||||
|
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<string NotStr, string OpcStr> {
|
||||||
|
defm Pt : NVJ_type_basic_reg<NotStr, OpcStr, "t">;
|
||||||
|
defm Pnt : NVJ_type_basic_reg<NotStr, OpcStr, "nt">;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiclass for dot new of 2nd operand register.
|
||||||
|
multiclass NVJ_type_br_pred_2ndDotNew<string NotStr, string OpcStr> {
|
||||||
|
defm Pt : NVJ_type_basic_2ndDotNew<NotStr, OpcStr, "t">;
|
||||||
|
defm Pnt : NVJ_type_basic_2ndDotNew<NotStr, OpcStr, "nt">;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiclass for 2nd operand immediate, including -1.
|
||||||
|
multiclass NVJ_type_br_pred_imm<string NotStr, string OpcStr> {
|
||||||
|
defm Pt : NVJ_type_basic_imm<NotStr, OpcStr, "t">;
|
||||||
|
defm Pnt : NVJ_type_basic_imm<NotStr, OpcStr, "nt">;
|
||||||
|
defm Ptneg : NVJ_type_basic_neg<NotStr, OpcStr, "t">;
|
||||||
|
defm Pntneg : NVJ_type_basic_neg<NotStr, OpcStr, "nt">;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiclass for 2nd operand immediate, excluding -1.
|
||||||
|
multiclass NVJ_type_br_pred_imm_only<string NotStr, string OpcStr> {
|
||||||
|
defm Pt : NVJ_type_basic_imm<NotStr, OpcStr, "t">;
|
||||||
|
defm Pnt : NVJ_type_basic_imm<NotStr, OpcStr, "nt">;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiclass for tstbit, where 2nd operand is always #0.
|
||||||
|
multiclass NVJ_type_br_pred_tstbit<string NotStr, string OpcStr> {
|
||||||
|
defm Pt : NVJ_type_basic_tstbit<NotStr, OpcStr, "t">;
|
||||||
|
defm Pnt : NVJ_type_basic_tstbit<NotStr, OpcStr, "nt">;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiclass for GT.
|
||||||
|
multiclass NVJ_type_rr_ri<string OpcStr> {
|
||||||
|
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<string OpcStr> {
|
||||||
|
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<string OpcStr> {
|
||||||
|
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<string OpcStr> {
|
||||||
|
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
|
// NV/J -
|
||||||
// with a register and an unsigned immediate (U5) operand.
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11 in
|
|
||||||
class NVJri_template<string mnemonic, bits<3> 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<string mnemonic, bits<3> majOp, bit isNegCond> {
|
|
||||||
// Branch not taken:
|
|
||||||
def _nt_V4: NVJri_template<mnemonic, majOp, isNegCond, 0>;
|
|
||||||
// Branch taken:
|
|
||||||
def _t_V4: NVJri_template<mnemonic, majOp, isNegCond, 1>;
|
|
||||||
}
|
|
||||||
|
|
||||||
multiclass NVJri_base<string mnemonic, string BaseOp, bits<3> majOp> {
|
|
||||||
let BaseOpcode = BaseOp#_NVJri in {
|
|
||||||
defm _t_Jumpnv : NVJri_cond<mnemonic, majOp, 0>; // True Cond
|
|
||||||
defm _f_Jumpnv : NVJri_cond<mnemonic, majOp, 1>; // 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<string mnemonic, bits<3> 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<string mnemonic, bits<3> majOp, string ImmVal,
|
|
||||||
bit isNegCond> {
|
|
||||||
// Branch not taken:
|
|
||||||
def _nt_V4: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 0>;
|
|
||||||
// Branch taken:
|
|
||||||
def _t_V4: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 1>;
|
|
||||||
}
|
|
||||||
|
|
||||||
multiclass NVJ_ConstImm_base<string mnemonic, string BaseOp, bits<3> majOp,
|
|
||||||
string ImmVal> {
|
|
||||||
let BaseOpcode = BaseOp#_NVJ_ConstImm in {
|
|
||||||
defm _t_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 0>; // True cond
|
|
||||||
defm _f_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 1>; // 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 +
|
// XTYPE/ALU +
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -3021,10 +3007,9 @@ def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))),
|
|||||||
|
|
||||||
|
|
||||||
// Transfer global address into a register
|
// Transfer global address into a register
|
||||||
let isExtended = 1, opExtendable = 1, AddedComplexity=50, isMoveImm = 1,
|
let AddedComplexity=50, isMoveImm = 1, isReMaterializable = 1 in
|
||||||
isAsCheapAsAMove = 1, isReMaterializable = 1, validSubTargets = HasV4SubT in
|
def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$src1),
|
||||||
def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins s16Ext:$src1),
|
"$dst = ##$src1",
|
||||||
"$dst = #$src1",
|
|
||||||
[(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>,
|
[(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>,
|
||||||
Requires<[HasV4T]>;
|
Requires<[HasV4T]>;
|
||||||
|
|
||||||
|
@ -22,31 +22,29 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
#define DEBUG_TYPE "hexagon-nvj"
|
#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 "Hexagon.h"
|
||||||
#include "HexagonTargetMachine.h"
|
|
||||||
#include "HexagonRegisterInfo.h"
|
|
||||||
#include "HexagonSubtarget.h"
|
|
||||||
#include "HexagonInstrInfo.h"
|
#include "HexagonInstrInfo.h"
|
||||||
#include "HexagonMachineFunctionInfo.h"
|
#include "HexagonMachineFunctionInfo.h"
|
||||||
|
#include "HexagonRegisterInfo.h"
|
||||||
#include <map>
|
#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/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 <map>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
STATISTIC(NumNVJGenerated, "Number of New Value Jump Instructions created");
|
STATISTIC(NumNVJGenerated, "Number of New Value Jump Instructions created");
|
||||||
@ -59,11 +57,6 @@ static cl::opt<bool> DisableNewValueJumps("disable-nvjump", cl::Hidden,
|
|||||||
cl::ZeroOrMore, cl::init(false),
|
cl::ZeroOrMore, cl::init(false),
|
||||||
cl::desc("Disable New Value Jumps"));
|
cl::desc("Disable New Value Jumps"));
|
||||||
|
|
||||||
namespace llvm {
|
|
||||||
void initializeHexagonNewValueJumpPass(PassRegistry&);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct HexagonNewValueJump : public MachineFunctionPass {
|
struct HexagonNewValueJump : public MachineFunctionPass {
|
||||||
const HexagonInstrInfo *QII;
|
const HexagonInstrInfo *QII;
|
||||||
@ -72,9 +65,7 @@ namespace {
|
|||||||
public:
|
public:
|
||||||
static char ID;
|
static char ID;
|
||||||
|
|
||||||
HexagonNewValueJump() : MachineFunctionPass(ID) {
|
HexagonNewValueJump() : MachineFunctionPass(ID) { }
|
||||||
initializeHexagonNewValueJumpPass(*PassRegistry::getPassRegistry());
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
AU.addRequired<MachineBranchProbabilityInfo>();
|
AU.addRequired<MachineBranchProbabilityInfo>();
|
||||||
@ -97,13 +88,6 @@ namespace {
|
|||||||
|
|
||||||
char HexagonNewValueJump::ID = 0;
|
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,
|
// We have identified this II could be feeder to NVJ,
|
||||||
// verify that it can be.
|
// verify that it can be.
|
||||||
static bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII,
|
static bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII,
|
||||||
@ -235,7 +219,7 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned cmpReg1, cmpOp2 = 0; // cmpOp2 assignment silences compiler warning.
|
unsigned cmpReg1, cmpOp2;
|
||||||
cmpReg1 = MI->getOperand(1).getReg();
|
cmpReg1 = MI->getOperand(1).getReg();
|
||||||
|
|
||||||
if (secondReg) {
|
if (secondReg) {
|
||||||
@ -301,48 +285,43 @@ static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg,
|
|||||||
|
|
||||||
switch (MI->getOpcode()) {
|
switch (MI->getOpcode()) {
|
||||||
case Hexagon::CMPEQrr:
|
case Hexagon::CMPEQrr:
|
||||||
return taken ? Hexagon::CMPEQrr_t_Jumpnv_t_V4
|
return taken ? Hexagon::JMP_EQrrPt_nv_V4 : Hexagon::JMP_EQrrPnt_nv_V4;
|
||||||
: Hexagon::CMPEQrr_t_Jumpnv_nt_V4;
|
|
||||||
|
|
||||||
case Hexagon::CMPEQri: {
|
case Hexagon::CMPEQri: {
|
||||||
if (reg >= 0)
|
if (reg >= 0)
|
||||||
return taken ? Hexagon::CMPEQri_t_Jumpnv_t_V4
|
return taken ? Hexagon::JMP_EQriPt_nv_V4 : Hexagon::JMP_EQriPnt_nv_V4;
|
||||||
: Hexagon::CMPEQri_t_Jumpnv_nt_V4;
|
|
||||||
else
|
else
|
||||||
return taken ? Hexagon::CMPEQn1_t_Jumpnv_t_V4
|
return taken ? Hexagon::JMP_EQriPtneg_nv_V4
|
||||||
: Hexagon::CMPEQn1_t_Jumpnv_nt_V4;
|
: Hexagon::JMP_EQriPntneg_nv_V4;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Hexagon::CMPGTrr: {
|
case Hexagon::CMPGTrr: {
|
||||||
if (secondRegNewified)
|
if (secondRegNewified)
|
||||||
return taken ? Hexagon::CMPLTrr_t_Jumpnv_t_V4
|
return taken ? Hexagon::JMP_GTrrdnPt_nv_V4
|
||||||
: Hexagon::CMPLTrr_t_Jumpnv_nt_V4;
|
: Hexagon::JMP_GTrrdnPnt_nv_V4;
|
||||||
else
|
else
|
||||||
return taken ? Hexagon::CMPGTrr_t_Jumpnv_t_V4
|
return taken ? Hexagon::JMP_GTrrPt_nv_V4
|
||||||
: Hexagon::CMPGTrr_t_Jumpnv_nt_V4;
|
: Hexagon::JMP_GTrrPnt_nv_V4;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Hexagon::CMPGTri: {
|
case Hexagon::CMPGTri: {
|
||||||
if (reg >= 0)
|
if (reg >= 0)
|
||||||
return taken ? Hexagon::CMPGTri_t_Jumpnv_t_V4
|
return taken ? Hexagon::JMP_GTriPt_nv_V4 : Hexagon::JMP_GTriPnt_nv_V4;
|
||||||
: Hexagon::CMPGTri_t_Jumpnv_nt_V4;
|
|
||||||
else
|
else
|
||||||
return taken ? Hexagon::CMPGTn1_t_Jumpnv_t_V4
|
return taken ? Hexagon::JMP_GTriPtneg_nv_V4
|
||||||
: Hexagon::CMPGTn1_t_Jumpnv_nt_V4;
|
: Hexagon::JMP_GTriPntneg_nv_V4;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Hexagon::CMPGTUrr: {
|
case Hexagon::CMPGTUrr: {
|
||||||
if (secondRegNewified)
|
if (secondRegNewified)
|
||||||
return taken ? Hexagon::CMPLTUrr_t_Jumpnv_t_V4
|
return taken ? Hexagon::JMP_GTUrrdnPt_nv_V4
|
||||||
: Hexagon::CMPLTUrr_t_Jumpnv_nt_V4;
|
: Hexagon::JMP_GTUrrdnPnt_nv_V4;
|
||||||
else
|
else
|
||||||
return taken ? Hexagon::CMPGTUrr_t_Jumpnv_t_V4
|
return taken ? Hexagon::JMP_GTUrrPt_nv_V4 : Hexagon::JMP_GTUrrPnt_nv_V4;
|
||||||
: Hexagon::CMPGTUrr_t_Jumpnv_nt_V4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case Hexagon::CMPGTUri:
|
case Hexagon::CMPGTUri:
|
||||||
return taken ? Hexagon::CMPGTUri_t_Jumpnv_t_V4
|
return taken ? Hexagon::JMP_GTUriPt_nv_V4 : Hexagon::JMP_GTUriPnt_nv_V4;
|
||||||
: Hexagon::CMPGTUri_t_Jumpnv_nt_V4;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
llvm_unreachable("Could not find matching New Value Jump instruction.");
|
llvm_unreachable("Could not find matching New Value Jump instruction.");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user