1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00

[Hexagon] Removing more V4 predicates since V4 is the required minimum.

llvm-svn: 228614
This commit is contained in:
Colin LeMahieu 2015-02-09 21:56:37 +00:00
parent e9662c9d04
commit 6ba6e9c428
12 changed files with 222 additions and 466 deletions

View File

@ -21,27 +21,13 @@ include "llvm/Target/Target.td"
// Hexagon Subtarget features.
//===----------------------------------------------------------------------===//
// Hexagon Archtectures
def ArchV2 : SubtargetFeature<"v2", "HexagonArchVersion", "V2",
"Hexagon v2">;
def ArchV3 : SubtargetFeature<"v3", "HexagonArchVersion", "V3",
"Hexagon v3">;
def ArchV4 : SubtargetFeature<"v4", "HexagonArchVersion", "V4",
"Hexagon v4">;
def ArchV5 : SubtargetFeature<"v5", "HexagonArchVersion", "V5",
"Hexagon v5">;
// Hexagon Architectures
def ArchV4: SubtargetFeature<"v4", "HexagonArchVersion", "V4", "Hexagon V4">;
def ArchV5: SubtargetFeature<"v5", "HexagonArchVersion", "V5", "Hexagon V5">;
//===----------------------------------------------------------------------===//
// Hexagon Instruction Predicate Definitions.
//===----------------------------------------------------------------------===//
def HasV2T : Predicate<"Subtarget->hasV2TOps()">;
def HasV2TOnly : Predicate<"Subtarget->hasV2TOpsOnly()">;
def NoV2T : Predicate<"!Subtarget->hasV2TOps()">;
def HasV3T : Predicate<"Subtarget->hasV3TOps()">;
def HasV3TOnly : Predicate<"Subtarget->hasV3TOpsOnly()">;
def NoV3T : Predicate<"!Subtarget->hasV3TOps()">;
def HasV4T : Predicate<"Subtarget->hasV4TOps()">;
def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
def NoV5T : Predicate<"!Subtarget->hasV5TOps()">;
def UseMEMOP : Predicate<"Subtarget->useMemOps()">;
@ -210,8 +196,10 @@ class Proc<string Name, SchedMachineModel Model,
list<SubtargetFeature> Features>
: ProcessorModel<Name, Model, Features>;
def : Proc<"hexagonv4", HexagonModelV4, [ArchV2, ArchV3, ArchV4]>;
def : Proc<"hexagonv5", HexagonModelV4, [ArchV2, ArchV3, ArchV4, ArchV5]>;
def : Proc<"hexagonv4", HexagonModelV4,
[ArchV4]>;
def : Proc<"hexagonv5", HexagonModelV4,
[ArchV4, ArchV5]>;
//===----------------------------------------------------------------------===//
// Declare the target which we are implementing

View File

@ -179,18 +179,6 @@ static bool areCombinableOperations(const TargetRegisterInfo *TRI,
LowRegInst->getOpcode() == Hexagon::TFRI_V4) &&
"Assume individual instructions are of a combinable type");
const HexagonRegisterInfo *QRI =
static_cast<const HexagonRegisterInfo *>(TRI);
// V4 added some combine variations (mixed immediate and register source
// operands), if we are on < V4 we can only combine 2 register-to-register
// moves and 2 immediate-to-register moves. We also don't have
// constant-extenders.
if (!QRI->Subtarget.hasV4TOps())
return HighRegInst->getOpcode() == LowRegInst->getOpcode() &&
!isGreaterThan8BitTFRI(HighRegInst) &&
!isGreaterThan6BitTFRI(LowRegInst);
// There is no combine of two constant extended values.
if ((HighRegInst->getOpcode() == Hexagon::TFRI_V4 ||
isGreaterThan8BitTFRI(HighRegInst)) &&

View File

@ -166,8 +166,7 @@ void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
}
// Replace 'jumpr r31' instruction with dealloc_return for V4 and higher
// versions.
if (MF.getSubtarget<HexagonSubtarget>().hasV4TOps() &&
MBBI->getOpcode() == Hexagon::JMPret && !DisableDeallocRet) {
if (MBBI->getOpcode() == Hexagon::JMPret && !DisableDeallocRet) {
// Check for RESTORE_DEALLOC_RET_JMP_V4 call. Don't emit an extra DEALLOC
// instruction if we encounter it.
MachineBasicBlock::iterator BeforeJMPR =

View File

@ -1436,13 +1436,8 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::EH_RETURN, MVT::Other, Custom);
if (Subtarget->isSubtargetV2()) {
setExceptionPointerRegister(Hexagon::R20);
setExceptionSelectorRegister(Hexagon::R21);
} else {
setExceptionPointerRegister(Hexagon::R0);
setExceptionSelectorRegister(Hexagon::R1);
}
setExceptionPointerRegister(Hexagon::R0);
setExceptionSelectorRegister(Hexagon::R1);
// VASTART needs to be custom lowered to use the VarArgsFrameIndex.
setOperationAction(ISD::VASTART, MVT::Other, Custom);

View File

@ -578,10 +578,6 @@ unsigned HexagonInstrInfo::createVR(MachineFunction* MF, MVT VT) const {
}
bool HexagonInstrInfo::isExtendable(const MachineInstr *MI) const {
// Constant extenders are allowed only for V4 and above.
if (!Subtarget.hasV4TOps())
return false;
const MCInstrDesc &MID = MI->getDesc();
const uint64_t F = MID.TSFlags;
if ((F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask)
@ -705,7 +701,7 @@ bool HexagonInstrInfo::isPredicable(MachineInstr *MI) const {
case Hexagon::A2_sxth:
case Hexagon::A2_zxtb:
case Hexagon::A2_zxth:
return Subtarget.hasV4TOps();
return true;
}
return true;
@ -1006,8 +1002,7 @@ bool HexagonInstrInfo::mayBeNewStore(const MachineInstr *MI) const {
const uint64_t F = MI->getDesc().TSFlags;
return ((F >> HexagonII::mayNVStorePos) &
HexagonII::mayNVStoreMask &
QRI.Subtarget.hasV4TOps());
HexagonII::mayNVStoreMask);
}
bool
@ -1334,7 +1329,6 @@ isConditionalLoad (const MachineInstr* MI) const {
case Hexagon::L2_ploadruhf_io:
case Hexagon::L2_ploadrubt_io:
case Hexagon::L2_ploadrubf_io:
return true;
case Hexagon::L2_ploadrdt_pi:
case Hexagon::L2_ploadrdf_pi:
case Hexagon::L2_ploadrit_pi:
@ -1347,7 +1341,6 @@ isConditionalLoad (const MachineInstr* MI) const {
case Hexagon::L2_ploadruhf_pi:
case Hexagon::L2_ploadrubt_pi:
case Hexagon::L2_ploadrubf_pi:
return QRI.Subtarget.hasV4TOps();
case Hexagon::L4_ploadrdt_rr:
case Hexagon::L4_ploadrdf_rr:
case Hexagon::L4_ploadrbt_rr:
@ -1360,7 +1353,7 @@ isConditionalLoad (const MachineInstr* MI) const {
case Hexagon::L4_ploadruhf_rr:
case Hexagon::L4_ploadrit_rr:
case Hexagon::L4_ploadrif_rr:
return QRI.Subtarget.hasV4TOps();
return true;
}
}
@ -1434,7 +1427,6 @@ isConditionalStore (const MachineInstr* MI) const {
case Hexagon::S4_pstorerif_rr:
case Hexagon::S2_pstorerit_pi:
case Hexagon::S2_pstorerif_pi:
return QRI.Subtarget.hasV4TOps();
// V4 global address store before promoting to dot new.
case Hexagon::S4_pstorerdt_abs:
@ -1445,7 +1437,7 @@ isConditionalStore (const MachineInstr* MI) const {
case Hexagon::S4_pstorerhf_abs:
case Hexagon::S4_pstorerit_abs:
case Hexagon::S4_pstorerif_abs:
return QRI.Subtarget.hasV4TOps();
return true;
// Predicated new value stores (i.e. if (p0) memw(..)=r0.new) are excluded
// from the "Conditional Store" list. Because a predicated new value store
@ -1631,11 +1623,6 @@ bool HexagonInstrInfo::isSchedulingBoundary(const MachineInstr *MI,
}
bool HexagonInstrInfo::isConstExtended(MachineInstr *MI) const {
// Constant extenders are allowed only for V4 and above.
if (!Subtarget.hasV4TOps())
return false;
const uint64_t F = MI->getDesc().TSFlags;
unsigned isExtended = (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
if (isExtended) // Instruction must be extended.
@ -1708,10 +1695,6 @@ HexagonInstrInfo::getDotNewPredJumpOp(MachineInstr *MI,
// Returns true if a particular operand is extendable for an instruction.
bool HexagonInstrInfo::isOperandExtended(const MachineInstr *MI,
unsigned short OperandNum) const {
// Constant extenders are allowed only for V4 and above.
if (!Subtarget.hasV4TOps())
return false;
const uint64_t F = MI->getDesc().TSFlags;
return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask)

View File

@ -294,12 +294,10 @@ def HexagonWrapperCombineIR_V4 :
SDNode<"HexagonISD::WrapperCombineIR_V4", SDTHexagonI64I32I32>;
def : Pat <(HexagonWrapperCombineRI_V4 IntRegs:$r, s8ExtPred:$i),
(A4_combineri IntRegs:$r, s8ExtPred:$i)>,
Requires<[HasV4T]>;
(A4_combineri IntRegs:$r, s8ExtPred:$i)>;
def : Pat <(HexagonWrapperCombineIR_V4 s8ExtPred:$i, IntRegs:$r),
(A4_combineir s8ExtPred:$i, IntRegs:$r)>,
Requires<[HasV4T]>;
(A4_combineir s8ExtPred:$i, IntRegs:$r)>;
// A4_combineii: Set two small immediates.
let hasSideEffects = 0, isExtendable = 1, opExtentBits = 6, opExtendable = 2 in
@ -615,25 +613,21 @@ def: Pat<(i64 (zext (i32 IntRegs:$src1))),
// zext i32->i64
def: Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)),
(i64 (A4_combineir 0, (L2_loadri_io AddrFI:$src1, 0)))>,
Requires<[HasV4T]>;
(i64 (A4_combineir 0, (L2_loadri_io AddrFI:$src1, 0)))>;
let AddedComplexity = 100 in
def: Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
(i64 (A4_combineir 0, (L2_loadri_io IntRegs:$src1,
s11_2ExtPred:$offset)))>,
Requires<[HasV4T]>;
s11_2ExtPred:$offset)))>;
// anyext i32->i64
def: Pat <(i64 (extloadi32 ADDRriS11_2:$src1)),
(i64 (A4_combineir 0, (L2_loadri_io AddrFI:$src1, 0)))>,
Requires<[HasV4T]>;
(i64 (A4_combineir 0, (L2_loadri_io AddrFI:$src1, 0)))>;
let AddedComplexity = 100 in
def: Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
(i64 (A4_combineir 0, (L2_loadri_io IntRegs:$src1,
s11_2ExtPred:$offset)))>,
Requires<[HasV4T]>;
s11_2ExtPred:$offset)))>;
@ -1114,7 +1108,7 @@ let hasSideEffects = 0, addrMode = BaseImmOffset,
defm S4_storeiri : ST_Imm<"memw", "STriw", u6_2Imm, 0b10>;
}
let Predicates = [HasV4T], AddedComplexity = 10 in {
let AddedComplexity = 10 in {
def: Pat<(truncstorei8 s8ExtPred:$src3, (add IntRegs:$src1, u6_0ImmPred:$src2)),
(S4_storeirb_io IntRegs:$src1, u6_0ImmPred:$src2, s8ExtPred:$src3)>;
@ -1128,8 +1122,7 @@ def: Pat<(store s8ExtPred:$src3, (add IntRegs:$src1, u6_2ImmPred:$src2)),
let AddedComplexity = 6 in
def : Pat <(truncstorei8 s8ExtPred:$src2, (i32 IntRegs:$src1)),
(S4_storeirb_io IntRegs:$src1, 0, s8ExtPred:$src2)>,
Requires<[HasV4T]>;
(S4_storeirb_io IntRegs:$src1, 0, s8ExtPred:$src2)>;
// memb(Rx++#s4:0:circ(Mu))=Rt
// memb(Rx++I:circ(Mu))=Rt
@ -1144,8 +1137,7 @@ def : Pat <(truncstorei8 s8ExtPred:$src2, (i32 IntRegs:$src1)),
// memh(Rs+#s11:1)=Rt.H
let AddedComplexity = 6 in
def : Pat <(truncstorei16 s8ExtPred:$src2, (i32 IntRegs:$src1)),
(S4_storeirh_io IntRegs:$src1, 0, s8ExtPred:$src2)>,
Requires<[HasV4T]>;
(S4_storeirh_io IntRegs:$src1, 0, s8ExtPred:$src2)>;
// memh(Rs+Ru<<#u2)=Rt.H
// TODO: needs to be implemented.
@ -1176,8 +1168,7 @@ def : Pat <(truncstorei16 s8ExtPred:$src2, (i32 IntRegs:$src1)),
let AddedComplexity = 6 in
def : Pat <(store s8ExtPred:$src2, (i32 IntRegs:$src1)),
(S4_storeiri_io IntRegs:$src1, 0, s8ExtPred:$src2)>,
Requires<[HasV4T]>;
(S4_storeiri_io IntRegs:$src1, 0, s8ExtPred:$src2)>;
// memw(Rx++#s4:2)=Rt
// memw(Rx++#s4:2:circ(Mu))=Rt
@ -2976,8 +2967,7 @@ def : Pat <(i32 (zext (i1 (seteq (i32 (and (i32 IntRegs:$Rs), 255)),
u8ExtPred:$u8)))),
(i32 (TFR_condset_ii (i1 (A4_cmpbeqi (i32 IntRegs:$Rs),
(u8ExtPred:$u8))),
1, 0))>,
Requires<[HasV4T]>;
1, 0))>;
// For the sequence
// zext( setne ( and(Rs, 255), u8))
@ -2989,8 +2979,7 @@ def : Pat <(i32 (zext (i1 (setne (i32 (and (i32 IntRegs:$Rs), 255)),
u8ExtPred:$u8)))),
(i32 (TFR_condset_ii (i1 (A4_cmpbeqi (i32 IntRegs:$Rs),
(u8ExtPred:$u8))),
0, 1))>,
Requires<[HasV4T]>;
0, 1))>;
// For the sequence
// zext( seteq (Rs, and(Rt, 255)))
@ -3002,8 +2991,7 @@ def : Pat <(i32 (zext (i1 (seteq (i32 IntRegs:$Rt),
(i32 (and (i32 IntRegs:$Rs), 255)))))),
(i32 (TFR_condset_ii (i1 (A4_cmpbeq (i32 IntRegs:$Rs),
(i32 IntRegs:$Rt))),
1, 0))>,
Requires<[HasV4T]>;
1, 0))>;
// For the sequence
// zext( setne (Rs, and(Rt, 255)))
@ -3015,8 +3003,7 @@ def : Pat <(i32 (zext (i1 (setne (i32 IntRegs:$Rt),
(i32 (and (i32 IntRegs:$Rs), 255)))))),
(i32 (TFR_condset_ii (i1 (A4_cmpbeq (i32 IntRegs:$Rs),
(i32 IntRegs:$Rt))),
0, 1))>,
Requires<[HasV4T]>;
0, 1))>;
// For the sequence
// zext( setugt ( and(Rs, 255), u8))
@ -3028,8 +3015,7 @@ def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 255)),
u8ExtPred:$u8)))),
(i32 (TFR_condset_ii (i1 (A4_cmpbgtui (i32 IntRegs:$Rs),
(u8ExtPred:$u8))),
1, 0))>,
Requires<[HasV4T]>;
1, 0))>;
// For the sequence
// zext( setugt ( and(Rs, 254), u8))
@ -3041,8 +3027,7 @@ def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 254)),
u8ExtPred:$u8)))),
(i32 (TFR_condset_ii (i1 (A4_cmpbgtui (i32 IntRegs:$Rs),
(u8ExtPred:$u8))),
1, 0))>,
Requires<[HasV4T]>;
1, 0))>;
// For the sequence
// zext( setult ( Rs, Rt))
@ -3054,8 +3039,7 @@ def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 254)),
def : Pat <(i32 (zext (i1 (setult (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
(i32 (TFR_condset_ii (i1 (C2_cmpgtu (i32 IntRegs:$Rt),
(i32 IntRegs:$Rs))),
1, 0))>,
Requires<[HasV4T]>;
1, 0))>;
// For the sequence
// zext( setlt ( Rs, Rt))
@ -3067,8 +3051,7 @@ def : Pat <(i32 (zext (i1 (setult (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
def : Pat <(i32 (zext (i1 (setlt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
(i32 (TFR_condset_ii (i1 (C2_cmpgt (i32 IntRegs:$Rt),
(i32 IntRegs:$Rs))),
1, 0))>,
Requires<[HasV4T]>;
1, 0))>;
// For the sequence
// zext( setugt ( Rs, Rt))
@ -3079,8 +3062,7 @@ def : Pat <(i32 (zext (i1 (setlt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
def : Pat <(i32 (zext (i1 (setugt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
(i32 (TFR_condset_ii (i1 (C2_cmpgtu (i32 IntRegs:$Rs),
(i32 IntRegs:$Rt))),
1, 0))>,
Requires<[HasV4T]>;
1, 0))>;
// This pattern interefers with coremark performance, not implementing at this
// time.
@ -3101,8 +3083,7 @@ def : Pat <(i32 (zext (i1 (setugt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
def : Pat <(i32 (zext (i1 (setuge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
(i32 (TFR_condset_ii (i1 (C2_cmpgtu (i32 IntRegs:$Rt),
(i32 IntRegs:$Rs))),
0, 1))>,
Requires<[HasV4T]>;
0, 1))>;
// For the sequence
// zext( setge ( Rs, Rt))
@ -3114,8 +3095,7 @@ def : Pat <(i32 (zext (i1 (setuge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
def : Pat <(i32 (zext (i1 (setge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
(i32 (TFR_condset_ii (i1 (C2_cmpgt (i32 IntRegs:$Rt),
(i32 IntRegs:$Rs))),
0, 1))>,
Requires<[HasV4T]>;
0, 1))>;
// For the sequence
// zext( setule ( Rs, Rt))
@ -3126,8 +3106,7 @@ def : Pat <(i32 (zext (i1 (setge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
def : Pat <(i32 (zext (i1 (setule (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
(i32 (TFR_condset_ii (i1 (C2_cmpgtu (i32 IntRegs:$Rs),
(i32 IntRegs:$Rt))),
0, 1))>,
Requires<[HasV4T]>;
0, 1))>;
// For the sequence
// zext( setle ( Rs, Rt))
@ -3138,8 +3117,7 @@ def : Pat <(i32 (zext (i1 (setule (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
def : Pat <(i32 (zext (i1 (setle (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
(i32 (TFR_condset_ii (i1 (C2_cmpgt (i32 IntRegs:$Rs),
(i32 IntRegs:$Rt))),
0, 1))>,
Requires<[HasV4T]>;
0, 1))>;
// For the sequence
// zext( setult ( and(Rs, 255), u8))
@ -3228,8 +3206,7 @@ let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1,
def RESTORE_DEALLOC_RET_JMP_V4 : JInst<(outs),
(ins calltarget:$dst),
"jump $dst",
[]>,
Requires<[HasV4T]>;
[]>;
}
// Restore registers and dealloc frame before a tail call.
@ -3237,8 +3214,7 @@ let isCall = 1, Defs = [R29, R30, R31, PC], isAsmParserOnly = 1 in {
def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : JInst<(outs),
(ins calltarget:$dst),
"call $dst",
[]>,
Requires<[HasV4T]>;
[]>;
}
// Save registers function call.
@ -3246,8 +3222,7 @@ let isCall = 1, Uses = [R29, R31], isAsmParserOnly = 1 in {
def SAVE_REGISTERS_CALL_V4 : JInst<(outs),
(ins calltarget:$dst),
"call $dst // Save_calle_saved_registers",
[]>,
Requires<[HasV4T]>;
[]>;
}
//===----------------------------------------------------------------------===//
@ -3790,18 +3765,15 @@ let isExtended = 1, opExtendable = 1, AddedComplexity=50, isMoveImm = 1,
isAsCheapAsAMove = 1, isReMaterializable = 1, isCodeGenOnly = 1 in
def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins s16Ext:$src1),
"$dst = #$src1",
[(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>,
Requires<[HasV4T]>;
[(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>;
// Transfer a block address into a register
def : Pat<(HexagonCONST32_GP tblockaddress:$src1),
(TFRI_V4 tblockaddress:$src1)>,
Requires<[HasV4T]>;
(TFRI_V4 tblockaddress:$src1)>;
let AddedComplexity = 50, Predicates = [HasV4T] in
let AddedComplexity = 50 in
def : Pat<(HexagonCONST32_GP tglobaladdr:$src1),
(TFRI_V4 tglobaladdr:$src1)>,
Requires<[HasV4T]>;
(TFRI_V4 tglobaladdr:$src1)>;
// i8/i16/i32 -> i64 loads
// We need a complexity of 120 here to override preceding handling of

View File

@ -363,8 +363,7 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
MF.getSubtarget().getRegisterInfo());
MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
if (!QRI->Subtarget.hasV4TOps() ||
DisableNewValueJumps) {
if (DisableNewValueJumps) {
return false;
}

View File

@ -517,307 +517,204 @@ def u0AlwaysExt : Operand<i32>;
// Predicates for constant extendable operands
def s16ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate can fit in a 16-bit sign extended field.
return isInt<16>(v);
else {
if (isInt<16>(v))
return true;
if (isInt<16>(v))
return true;
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit signed field.
return isConstExtProfitable(Node) && isInt<32>(v);
}
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit signed field.
return isConstExtProfitable(Node) && isInt<32>(v);
}]>;
def s10ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate can fit in a 10-bit sign extended field.
return isInt<10>(v);
else {
if (isInt<10>(v))
return true;
if (isInt<10>(v))
return true;
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit signed field.
return isConstExtProfitable(Node) && isInt<32>(v);
}
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit signed field.
return isConstExtProfitable(Node) && isInt<32>(v);
}]>;
def s9ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate can fit in a 9-bit sign extended field.
return isInt<9>(v);
else {
if (isInt<9>(v))
return true;
if (isInt<9>(v))
return true;
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit unsigned field.
return isConstExtProfitable(Node) && isInt<32>(v);
}
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit unsigned field.
return isConstExtProfitable(Node) && isInt<32>(v);
}]>;
def s8ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate can fit in a 8-bit sign extended field.
return isInt<8>(v);
else {
if (isInt<8>(v))
return true;
if (isInt<8>(v))
return true;
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit signed field.
return isConstExtProfitable(Node) && isInt<32>(v);
}
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit signed field.
return isConstExtProfitable(Node) && isInt<32>(v);
}]>;
def s8_16ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate fits in a 8-bit sign extended field.
return isInt<8>(v);
else {
if (isInt<8>(v))
return true;
if (isInt<8>(v))
return true;
// Return true if extending this immediate is profitable and the value
// can't fit in a 16-bit signed field. This is required to avoid
// unnecessary constant extenders.
return isConstExtProfitable(Node) && !isInt<16>(v);
}
// Return true if extending this immediate is profitable and the value
// can't fit in a 16-bit signed field. This is required to avoid
// unnecessary constant extenders.
return isConstExtProfitable(Node) && !isInt<16>(v);
}]>;
def s6ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate can fit in a 6-bit sign extended field.
return isInt<6>(v);
else {
if (isInt<6>(v))
return true;
if (isInt<6>(v))
return true;
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit unsigned field.
return isConstExtProfitable(Node) && isInt<32>(v);
}
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit unsigned field.
return isConstExtProfitable(Node) && isInt<32>(v);
}]>;
def s6_16ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate fits in a 6-bit sign extended field.
return isInt<6>(v);
else {
if (isInt<6>(v))
return true;
if (isInt<6>(v))
return true;
// Return true if extending this immediate is profitable and the value
// can't fit in a 16-bit signed field. This is required to avoid
// unnecessary constant extenders.
return isConstExtProfitable(Node) && !isInt<16>(v);
}
// Return true if extending this immediate is profitable and the value
// can't fit in a 16-bit signed field. This is required to avoid
// unnecessary constant extenders.
return isConstExtProfitable(Node) && !isInt<16>(v);
}]>;
def s6_10ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate can fit in a 6-bit sign extended field.
return isInt<6>(v);
else {
if (isInt<6>(v))
return true;
if (isInt<6>(v))
return true;
// Return true if extending this immediate is profitable and the value
// can't fit in a 10-bit signed field. This is required to avoid
// unnecessary constant extenders.
return isConstExtProfitable(Node) && !isInt<10>(v);
}
// Return true if extending this immediate is profitable and the value
// can't fit in a 10-bit signed field. This is required to avoid
// unnecessary constant extenders.
return isConstExtProfitable(Node) && !isInt<10>(v);
}]>;
def s11_0ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate can fit in a 11-bit sign extended field.
return isShiftedInt<11,0>(v);
else {
if (isInt<11>(v))
return true;
if (isInt<11>(v))
return true;
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit signed field.
return isConstExtProfitable(Node) && isInt<32>(v);
}
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit signed field.
return isConstExtProfitable(Node) && isInt<32>(v);
}]>;
def s11_1ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate can fit in a 12-bit sign extended field and
// is 2 byte aligned.
if (isInt<12>(v))
return isShiftedInt<11,1>(v);
else {
if (isInt<12>(v))
return isShiftedInt<11,1>(v);
// Return true if extending this immediate is profitable and the low 1 bit
// is zero (2-byte aligned).
return isConstExtProfitable(Node) && isInt<32>(v) && ((v % 2) == 0);
}
// Return true if extending this immediate is profitable and the low 1 bit
// is zero (2-byte aligned).
return isConstExtProfitable(Node) && isInt<32>(v) && ((v % 2) == 0);
}]>;
def s11_2ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate can fit in a 13-bit sign extended field and
// is 4-byte aligned.
if (isInt<13>(v))
return isShiftedInt<11,2>(v);
else {
if (isInt<13>(v))
return isShiftedInt<11,2>(v);
// Return true if extending this immediate is profitable and the low 2-bits
// are zero (4-byte aligned).
return isConstExtProfitable(Node) && isInt<32>(v) && ((v % 4) == 0);
}
// Return true if extending this immediate is profitable and the low 2-bits
// are zero (4-byte aligned).
return isConstExtProfitable(Node) && isInt<32>(v) && ((v % 4) == 0);
}]>;
def s11_3ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate can fit in a 14-bit sign extended field and
// is 8-byte aligned.
return isShiftedInt<11,3>(v);
else {
if (isInt<14>(v))
return isShiftedInt<11,3>(v);
if (isInt<14>(v))
return isShiftedInt<11,3>(v);
// Return true if extending this immediate is profitable and the low 3-bits
// are zero (8-byte aligned).
return isConstExtProfitable(Node) && isInt<32>(v) && ((v % 8) == 0);
}
// Return true if extending this immediate is profitable and the low 3-bits
// are zero (8-byte aligned).
return isConstExtProfitable(Node) && isInt<32>(v) && ((v % 8) == 0);
}]>;
def u0AlwaysExtPred : PatLeaf<(i32 imm), [{
// Predicate for an unsigned 32-bit value that always needs to be extended.
if (Subtarget->hasV4TOps()) {
if (isConstExtProfitable(Node)) {
int64_t v = (int64_t)N->getSExtValue();
return isUInt<32>(v);
}
if (isConstExtProfitable(Node)) {
int64_t v = (int64_t)N->getSExtValue();
return isUInt<32>(v);
}
return false;
}]>;
def u6ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate can fit in a 6-bit unsigned field.
return isUInt<6>(v);
else {
if (isUInt<6>(v))
return true;
if (isUInt<6>(v))
return true;
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit unsigned field.
return isConstExtProfitable(Node) && isUInt<32>(v);
}
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit unsigned field.
return isConstExtProfitable(Node) && isUInt<32>(v);
}]>;
def u7ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate can fit in a 7-bit unsigned field.
return isUInt<7>(v);
else {
if (isUInt<7>(v))
return true;
if (isUInt<7>(v))
return true;
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit unsigned field.
return isConstExtProfitable(Node) && isUInt<32>(v);
}
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit unsigned field.
return isConstExtProfitable(Node) && isUInt<32>(v);
}]>;
def u8ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate can fit in a 8-bit unsigned field.
return isUInt<8>(v);
else {
if (isUInt<8>(v))
return true;
if (isUInt<8>(v))
return true;
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit unsigned field.
return isConstExtProfitable(Node) && isUInt<32>(v);
}
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit unsigned field.
return isConstExtProfitable(Node) && isUInt<32>(v);
}]>;
def u9ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate can fit in a 9-bit unsigned field.
return isUInt<9>(v);
else {
if (isUInt<9>(v))
return true;
if (isUInt<9>(v))
return true;
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit unsigned field.
return isConstExtProfitable(Node) && isUInt<32>(v);
}
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit unsigned field.
return isConstExtProfitable(Node) && isUInt<32>(v);
}]>;
def u6_1ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate can fit in a 7-bit unsigned field and
// is 2-byte aligned.
if (isUInt<7>(v))
return isShiftedUInt<6,1>(v);
else {
if (isUInt<7>(v))
return isShiftedUInt<6,1>(v);
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit unsigned field.
return isConstExtProfitable(Node) && isUInt<32>(v) && ((v % 2) == 0);
}
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit unsigned field.
return isConstExtProfitable(Node) && isUInt<32>(v) && ((v % 2) == 0);
}]>;
def u6_2ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate can fit in a 8-bit unsigned field and
// is 4-byte aligned.
if (isUInt<8>(v))
return isShiftedUInt<6,2>(v);
else {
if (isUInt<8>(v))
return isShiftedUInt<6,2>(v);
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit unsigned field.
return isConstExtProfitable(Node) && isUInt<32>(v) && ((v % 4) == 0);
}
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit unsigned field.
return isConstExtProfitable(Node) && isUInt<32>(v) && ((v % 4) == 0);
}]>;
def u6_3ExtPred : PatLeaf<(i32 imm), [{
int64_t v = (int64_t)N->getSExtValue();
if (!Subtarget->hasV4TOps())
// Return true if the immediate can fit in a 9-bit unsigned field and
// is 8-byte aligned.
if (isUInt<9>(v))
return isShiftedUInt<6,3>(v);
else {
if (isUInt<9>(v))
return isShiftedUInt<6,3>(v);
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit unsigned field.
return isConstExtProfitable(Node) && isUInt<32>(v) && ((v % 8) == 0);
}
// Return true if extending this immediate is profitable and the value
// can fit in a 32-bit unsigned field.
return isConstExtProfitable(Node) && isUInt<32>(v) && ((v % 8) == 0);
}]>;

View File

@ -45,9 +45,6 @@ HexagonRegisterInfo::HexagonRegisterInfo(HexagonSubtarget &st)
const MCPhysReg *
HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
static const MCPhysReg CalleeSavedRegsV2[] = {
Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0
};
static const MCPhysReg CalleeSavedRegsV3[] = {
Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23,
@ -55,11 +52,6 @@ HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
};
switch(Subtarget.getHexagonArchVersion()) {
case HexagonSubtarget::V1:
break;
case HexagonSubtarget::V2:
return CalleeSavedRegsV2;
case HexagonSubtarget::V3:
case HexagonSubtarget::V4:
case HexagonSubtarget::V5:
return CalleeSavedRegsV3;
@ -88,10 +80,6 @@ BitVector HexagonRegisterInfo::getReservedRegs(const MachineFunction &MF)
const TargetRegisterClass* const*
HexagonRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
static const TargetRegisterClass * const CalleeSavedRegClassesV2[] = {
&Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass,
&Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass,
};
static const TargetRegisterClass * const CalleeSavedRegClassesV3[] = {
&Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass,
&Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass,
@ -102,11 +90,6 @@ HexagonRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
};
switch(Subtarget.getHexagonArchVersion()) {
case HexagonSubtarget::V1:
break;
case HexagonSubtarget::V2:
return CalleeSavedRegClassesV2;
case HexagonSubtarget::V3:
case HexagonSubtarget::V4:
case HexagonSubtarget::V5:
return CalleeSavedRegClassesV3;
@ -211,40 +194,12 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
MI.getOperand(FIOperandNum+1).ChangeToImmediate(0);
} else if (TII.isMemOp(&MI)) {
// use the constant extender if the instruction provides it
// and we are V4TOps.
if (Subtarget.hasV4TOps()) {
if (TII.isConstExtended(&MI)) {
MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false);
MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset);
TII.immediateExtend(&MI);
} else {
llvm_unreachable("Need to implement for memops");
}
if (TII.isConstExtended(&MI)) {
MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false);
MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset);
TII.immediateExtend(&MI);
} else {
// Only V3 and older instructions here.
unsigned ResReg = HEXAGON_RESERVED_REG_1;
if (!MFI.hasVarSizedObjects() &&
TII.isValidOffset(MI.getOpcode(), (FrameSize+Offset))) {
MI.getOperand(FIOperandNum).ChangeToRegister(getStackRegister(),
false, false, false);
MI.getOperand(FIOperandNum+1).ChangeToImmediate(FrameSize+Offset);
} else if (!TII.isValidOffset(Hexagon::A2_addi, Offset)) {
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
TII.get(Hexagon::CONST32_Int_Real), ResReg).addImm(Offset);
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
TII.get(Hexagon::A2_add), ResReg).addReg(FrameReg).
addReg(ResReg);
MI.getOperand(FIOperandNum).ChangeToRegister(ResReg, false, false,
true);
MI.getOperand(FIOperandNum+1).ChangeToImmediate(0);
} else {
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
TII.get(Hexagon::A2_addi), ResReg).addReg(FrameReg).
addImm(Offset);
MI.getOperand(FIOperandNum).ChangeToRegister(ResReg, false, false,
true);
MI.getOperand(FIOperandNum+1).ChangeToImmediate(0);
}
llvm_unreachable("Need to implement for memops");
}
} else {
unsigned dstReg = MI.getOperand(0).getReg();

View File

@ -54,12 +54,7 @@ HexagonSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS) {
if (CPUString.empty())
CPUString = "hexagonv4";
if (CPUString == "hexagonv2") {
HexagonArchVersion = V2;
} else if (CPUString == "hexagonv3") {
EnableV3 = true;
HexagonArchVersion = V3;
} else if (CPUString == "hexagonv4") {
if (CPUString == "hexagonv4") {
HexagonArchVersion = V4;
} else if (CPUString == "hexagonv5") {
HexagonArchVersion = V5;

View File

@ -39,7 +39,7 @@ class HexagonSubtarget : public HexagonGenSubtargetInfo {
public:
enum HexagonArchEnum {
V1, V2, V3, V4, V5
V4, V5
};
HexagonArchEnum HexagonArchVersion;
@ -81,18 +81,11 @@ public:
/// subtarget options. Definition of function is auto generated by tblgen.
void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
bool hasV2TOps () const { return HexagonArchVersion >= V2; }
bool hasV2TOpsOnly () const { return HexagonArchVersion == V2; }
bool hasV3TOps () const { return HexagonArchVersion >= V3; }
bool hasV3TOpsOnly () const { return HexagonArchVersion == V3; }
bool hasV4TOps () const { return HexagonArchVersion >= V4; }
bool hasV4TOpsOnly () const { return HexagonArchVersion == V4; }
bool useMemOps () const { return HexagonArchVersion >= V4 && UseMemOps; }
bool hasV5TOps () const { return HexagonArchVersion >= V5; }
bool hasV5TOpsOnly () const { return HexagonArchVersion == V5; }
bool modeIEEERndNear () const { return ModeIEEERndNear; }
bool useMemOps() const { return UseMemOps; }
bool hasV5TOps() const { return getHexagonArchVersion() >= V5; }
bool hasV5TOpsOnly() const { return getHexagonArchVersion() == V5; }
bool modeIEEERndNear() const { return ModeIEEERndNear; }
bool isSubtargetV2() const { return HexagonArchVersion == V2;}
const std::string &getCPUString () const { return CPUString; }
// Threshold for small data section

View File

@ -720,10 +720,7 @@ bool HexagonPacketizerList::CanPromoteToNewValue(
MachineBasicBlock::iterator &MII) {
const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
const HexagonRegisterInfo *QRI =
(const HexagonRegisterInfo *)MF.getSubtarget().getRegisterInfo();
if (!QRI->Subtarget.hasV4TOps() ||
!QII->mayBeNewStore(MI))
if (!QII->mayBeNewStore(MI))
return false;
MachineInstr *PacketMI = PacketSU->getInstr();
@ -1054,84 +1051,82 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
// first store is not in SLOT0. New value store, new value jump,
// dealloc_return and memop always take SLOT0.
// Arch spec 3.4.4.2
if (QRI->Subtarget.hasV4TOps()) {
if (MCIDI.mayStore() && MCIDJ.mayStore() &&
(QII->isNewValueInst(J) || QII->isMemOp(J) || QII->isMemOp(I))) {
Dependence = true;
return false;
if (MCIDI.mayStore() && MCIDJ.mayStore() &&
(QII->isNewValueInst(J) || QII->isMemOp(J) || QII->isMemOp(I))) {
Dependence = true;
return false;
}
if ((QII->isMemOp(J) && MCIDI.mayStore())
|| (MCIDJ.mayStore() && QII->isMemOp(I))
|| (QII->isMemOp(J) && QII->isMemOp(I))) {
Dependence = true;
return false;
}
//if dealloc_return
if (MCIDJ.mayStore() && QII->isDeallocRet(I)) {
Dependence = true;
return false;
}
// If an instruction feeds new value jump, glue it.
MachineBasicBlock::iterator NextMII = I;
++NextMII;
if (NextMII != I->getParent()->end() && QII->isNewValueJump(NextMII)) {
MachineInstr *NextMI = NextMII;
bool secondRegMatch = false;
bool maintainNewValueJump = false;
if (NextMI->getOperand(1).isReg() &&
I->getOperand(0).getReg() == NextMI->getOperand(1).getReg()) {
secondRegMatch = true;
maintainNewValueJump = true;
}
if ((QII->isMemOp(J) && MCIDI.mayStore())
|| (MCIDJ.mayStore() && QII->isMemOp(I))
|| (QII->isMemOp(J) && QII->isMemOp(I))) {
Dependence = true;
return false;
if (!secondRegMatch &&
I->getOperand(0).getReg() == NextMI->getOperand(0).getReg()) {
maintainNewValueJump = true;
}
//if dealloc_return
if (MCIDJ.mayStore() && QII->isDeallocRet(I)) {
Dependence = true;
return false;
}
for (std::vector<MachineInstr*>::iterator
VI = CurrentPacketMIs.begin(),
VE = CurrentPacketMIs.end();
(VI != VE && maintainNewValueJump); ++VI) {
SUnit *PacketSU = MIToSUnit.find(*VI)->second;
// If an instruction feeds new value jump, glue it.
MachineBasicBlock::iterator NextMII = I;
++NextMII;
if (NextMII != I->getParent()->end() && QII->isNewValueJump(NextMII)) {
MachineInstr *NextMI = NextMII;
bool secondRegMatch = false;
bool maintainNewValueJump = false;
if (NextMI->getOperand(1).isReg() &&
I->getOperand(0).getReg() == NextMI->getOperand(1).getReg()) {
secondRegMatch = true;
maintainNewValueJump = true;
// NVJ can not be part of the dual jump - Arch Spec: section 7.8
if (PacketSU->getInstr()->getDesc().isCall()) {
Dependence = true;
break;
}
if (!secondRegMatch &&
I->getOperand(0).getReg() == NextMI->getOperand(0).getReg()) {
maintainNewValueJump = true;
// Validate
// 1. Packet does not have a store in it.
// 2. If the first operand of the nvj is newified, and the second
// operand is also a reg, it (second reg) is not defined in
// the same packet.
// 3. If the second operand of the nvj is newified, (which means
// first operand is also a reg), first reg is not defined in
// the same packet.
if (PacketSU->getInstr()->getDesc().mayStore() ||
PacketSU->getInstr()->getOpcode() == Hexagon::S2_allocframe ||
// Check #2.
(!secondRegMatch && NextMI->getOperand(1).isReg() &&
PacketSU->getInstr()->modifiesRegister(
NextMI->getOperand(1).getReg(), QRI)) ||
// Check #3.
(secondRegMatch &&
PacketSU->getInstr()->modifiesRegister(
NextMI->getOperand(0).getReg(), QRI))) {
Dependence = true;
break;
}
for (std::vector<MachineInstr*>::iterator
VI = CurrentPacketMIs.begin(),
VE = CurrentPacketMIs.end();
(VI != VE && maintainNewValueJump); ++VI) {
SUnit *PacketSU = MIToSUnit.find(*VI)->second;
// NVJ can not be part of the dual jump - Arch Spec: section 7.8
if (PacketSU->getInstr()->getDesc().isCall()) {
Dependence = true;
break;
}
// Validate
// 1. Packet does not have a store in it.
// 2. If the first operand of the nvj is newified, and the second
// operand is also a reg, it (second reg) is not defined in
// the same packet.
// 3. If the second operand of the nvj is newified, (which means
// first operand is also a reg), first reg is not defined in
// the same packet.
if (PacketSU->getInstr()->getDesc().mayStore() ||
PacketSU->getInstr()->getOpcode() == Hexagon::S2_allocframe ||
// Check #2.
(!secondRegMatch && NextMI->getOperand(1).isReg() &&
PacketSU->getInstr()->modifiesRegister(
NextMI->getOperand(1).getReg(), QRI)) ||
// Check #3.
(secondRegMatch &&
PacketSU->getInstr()->modifiesRegister(
NextMI->getOperand(0).getReg(), QRI))) {
Dependence = true;
break;
}
}
if (!Dependence)
GlueToNewValueJump = true;
else
return false;
}
if (!Dependence)
GlueToNewValueJump = true;
else
return false;
}
if (SUJ->isSucc(SUI)) {
@ -1253,9 +1248,7 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
else if ((DepType == SDep::Order) &&
!I->hasOrderedMemoryRef() &&
!J->hasOrderedMemoryRef()) {
if (QRI->Subtarget.hasV4TOps() &&
// hexagonv4 allows dual store.
MCIDI.mayStore() && MCIDJ.mayStore()) {
if (MCIDI.mayStore() && MCIDJ.mayStore()) {
/* do nothing */
}
// store followed by store-- not OK on V2
@ -1277,7 +1270,6 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
// packetized in a same packet. This implies that the store is using
// caller's SP. Hence, offset needs to be updated accordingly.
else if (DepType == SDep::Data
&& QRI->Subtarget.hasV4TOps()
&& J->getOpcode() == Hexagon::S2_allocframe
&& (I->getOpcode() == Hexagon::S2_storerd_io
|| I->getOpcode() == Hexagon::S2_storeri_io