aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/Hexagon
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Hexagon')
-rw-r--r--lib/Target/Hexagon/CMakeLists.txt2
-rw-r--r--lib/Target/Hexagon/Hexagon.h23
-rw-r--r--lib/Target/Hexagon/Hexagon.td54
-rw-r--r--lib/Target/Hexagon/HexagonCFGOptimizer.cpp26
-rw-r--r--lib/Target/Hexagon/HexagonCallingConvLower.cpp6
-rw-r--r--lib/Target/Hexagon/HexagonCallingConvLower.h1
-rw-r--r--lib/Target/Hexagon/HexagonCopyToCombine.cpp677
-rw-r--r--lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp29
-rw-r--r--lib/Target/Hexagon/HexagonFrameLowering.cpp80
-rw-r--r--lib/Target/Hexagon/HexagonISelDAGToDAG.cpp74
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.cpp39
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.h8
-rw-r--r--lib/Target/Hexagon/HexagonInstrFormats.td3
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.cpp1121
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.h15
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.td105
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfoV4.td569
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfoV5.td23
-rw-r--r--lib/Target/Hexagon/HexagonMachineScheduler.cpp3
-rw-r--r--lib/Target/Hexagon/HexagonMachineScheduler.h3
-rw-r--r--lib/Target/Hexagon/HexagonNewValueJump.cpp88
-rw-r--r--lib/Target/Hexagon/HexagonPeephole.cpp16
-rw-r--r--lib/Target/Hexagon/HexagonRegisterInfo.cpp18
-rw-r--r--lib/Target/Hexagon/HexagonRegisterInfo.h4
-rw-r--r--lib/Target/Hexagon/HexagonRegisterInfo.td4
-rw-r--r--lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp18
-rw-r--r--lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp2
-rw-r--r--lib/Target/Hexagon/HexagonSelectionDAGInfo.h2
-rw-r--r--lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp176
-rw-r--r--lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp27
-rw-r--r--lib/Target/Hexagon/HexagonTargetMachine.cpp72
-rw-r--r--lib/Target/Hexagon/HexagonTargetObjectFile.cpp8
-rw-r--r--lib/Target/Hexagon/HexagonTargetObjectFile.h1
-rw-r--r--lib/Target/Hexagon/HexagonVLIWPacketizer.cpp1842
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h3
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp2
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h4
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp11
38 files changed, 1956 insertions, 3203 deletions
diff --git a/lib/Target/Hexagon/CMakeLists.txt b/lib/Target/Hexagon/CMakeLists.txt
index b5b887e..57044b2 100644
--- a/lib/Target/Hexagon/CMakeLists.txt
+++ b/lib/Target/Hexagon/CMakeLists.txt
@@ -28,12 +28,14 @@ add_llvm_target(HexagonCodeGen
HexagonRegisterInfo.cpp
HexagonRemoveSZExtArgs.cpp
HexagonSelectionDAGInfo.cpp
+ HexagonSplitConst32AndConst64.cpp
HexagonSplitTFRCondSets.cpp
HexagonSubtarget.cpp
HexagonTargetMachine.cpp
HexagonTargetObjectFile.cpp
HexagonVLIWPacketizer.cpp
HexagonNewValueJump.cpp
+ HexagonCopyToCombine.cpp
)
add_subdirectory(TargetInfo)
diff --git a/lib/Target/Hexagon/Hexagon.h b/lib/Target/Hexagon/Hexagon.h
index dfbefc8..b88637a 100644
--- a/lib/Target/Hexagon/Hexagon.h
+++ b/lib/Target/Hexagon/Hexagon.h
@@ -29,26 +29,29 @@ namespace llvm {
class HexagonTargetMachine;
class raw_ostream;
- FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM,
+ FunctionPass *createHexagonISelDag(const HexagonTargetMachine &TM,
CodeGenOpt::Level OptLevel);
- FunctionPass *createHexagonDelaySlotFillerPass(TargetMachine &TM);
- FunctionPass *createHexagonFPMoverPass(TargetMachine &TM);
- FunctionPass *createHexagonRemoveExtendOps(HexagonTargetMachine &TM);
- FunctionPass *createHexagonCFGOptimizer(HexagonTargetMachine &TM);
-
- FunctionPass *createHexagonSplitTFRCondSets(HexagonTargetMachine &TM);
- FunctionPass *createHexagonExpandPredSpillCode(HexagonTargetMachine &TM);
+ FunctionPass *createHexagonDelaySlotFillerPass(const TargetMachine &TM);
+ FunctionPass *createHexagonFPMoverPass(const TargetMachine &TM);
+ FunctionPass *createHexagonRemoveExtendArgs(const HexagonTargetMachine &TM);
+ FunctionPass *createHexagonCFGOptimizer(const HexagonTargetMachine &TM);
+ FunctionPass *createHexagonSplitTFRCondSets(const HexagonTargetMachine &TM);
+ FunctionPass *createHexagonSplitConst32AndConst64(
+ const HexagonTargetMachine &TM);
+ FunctionPass *createHexagonExpandPredSpillCode(
+ const HexagonTargetMachine &TM);
FunctionPass *createHexagonHardwareLoops();
FunctionPass *createHexagonPeephole();
FunctionPass *createHexagonFixupHwLoops();
+ FunctionPass *createHexagonNewValueJump();
+ FunctionPass *createHexagonCopyToCombine();
FunctionPass *createHexagonPacketizer();
FunctionPass *createHexagonNewValueJump();
-
/* TODO: object output.
MCCodeEmitter *createHexagonMCCodeEmitter(const Target &,
- TargetMachine &TM,
+ const TargetMachine &TM,
MCContext &Ctx);
*/
/* TODO: assembler input.
diff --git a/lib/Target/Hexagon/Hexagon.td b/lib/Target/Hexagon/Hexagon.td
index af1c56b..568798c 100644
--- a/lib/Target/Hexagon/Hexagon.td
+++ b/lib/Target/Hexagon/Hexagon.td
@@ -84,6 +84,30 @@ def getPredOpcode : InstrMapping {
}
//===----------------------------------------------------------------------===//
+// 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.
//
@@ -96,15 +120,39 @@ def getPredNewOpcode : InstrMapping {
}
//===----------------------------------------------------------------------===//
+// Generate mapping table to relate .new predicated instructions with their old
+// format.
+//
+def getPredOldOpcode : InstrMapping {
+ let FilterClass = "PredNewRel";
+ let RowFields = ["BaseOpcode", "PredSense", "isNVStore"];
+ let ColFields = ["PNewValue"];
+ let KeyCol = ["new"];
+ let ValueCols = [[""]];
+}
+
+//===----------------------------------------------------------------------===//
// Generate mapping table to relate store instructions with their new-value
// format.
//
def getNewValueOpcode : InstrMapping {
let FilterClass = "NewValueRel";
let RowFields = ["BaseOpcode", "PredSense", "PNewValue"];
- let ColFields = ["isNVStore"];
- let KeyCol = ["0"];
- let ValueCols = [["1"]];
+ let ColFields = ["NValueST"];
+ let KeyCol = ["false"];
+ let ValueCols = [["true"]];
+}
+
+//===----------------------------------------------------------------------===//
+// Generate mapping table to relate new-value store instructions with their old
+// format.
+//
+def getNonNVStore : InstrMapping {
+ let FilterClass = "NewValueRel";
+ let RowFields = ["BaseOpcode", "PredSense", "PNewValue"];
+ let ColFields = ["NValueST"];
+ let KeyCol = ["true"];
+ let ValueCols = [["false"]];
}
def getBasedWithImmOffset : InstrMapping {
diff --git a/lib/Target/Hexagon/HexagonCFGOptimizer.cpp b/lib/Target/Hexagon/HexagonCFGOptimizer.cpp
index b6022ca..8597f11 100644
--- a/lib/Target/Hexagon/HexagonCFGOptimizer.cpp
+++ b/lib/Target/Hexagon/HexagonCFGOptimizer.cpp
@@ -26,21 +26,27 @@
using namespace llvm;
+namespace llvm {
+ void initializeHexagonCFGOptimizerPass(PassRegistry&);
+}
+
+
namespace {
class HexagonCFGOptimizer : public MachineFunctionPass {
private:
- HexagonTargetMachine& QTM;
+ const HexagonTargetMachine& QTM;
const HexagonSubtarget &QST;
void InvertAndChangeJumpTarget(MachineInstr*, MachineBasicBlock*);
public:
static char ID;
- HexagonCFGOptimizer(HexagonTargetMachine& TM) : MachineFunctionPass(ID),
- QTM(TM),
- QST(*TM.getSubtargetImpl()) {}
+ HexagonCFGOptimizer(const HexagonTargetMachine& TM)
+ : MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) {
+ initializeHexagonCFGOptimizerPass(*PassRegistry::getPassRegistry());
+ }
const char *getPassName() const {
return "Hexagon CFG Optimizer";
@@ -231,6 +237,16 @@ bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {
// Public Constructor Functions
//===----------------------------------------------------------------------===//
-FunctionPass *llvm::createHexagonCFGOptimizer(HexagonTargetMachine &TM) {
+static void initializePassOnce(PassRegistry &Registry) {
+ PassInfo *PI = new PassInfo("Hexagon CFG Optimizer", "hexagon-cfg",
+ &HexagonCFGOptimizer::ID, 0, false, false);
+ Registry.registerPass(*PI, true);
+}
+
+void llvm::initializeHexagonCFGOptimizerPass(PassRegistry &Registry) {
+ CALL_ONCE_INITIALIZATION(initializePassOnce)
+}
+
+FunctionPass *llvm::createHexagonCFGOptimizer(const HexagonTargetMachine &TM) {
return new HexagonCFGOptimizer(TM);
}
diff --git a/lib/Target/Hexagon/HexagonCallingConvLower.cpp b/lib/Target/Hexagon/HexagonCallingConvLower.cpp
index 2c93d04..fc5503a 100644
--- a/lib/Target/Hexagon/HexagonCallingConvLower.cpp
+++ b/lib/Target/Hexagon/HexagonCallingConvLower.cpp
@@ -27,12 +27,11 @@ Hexagon_CCState::Hexagon_CCState(CallingConv::ID CC, bool isVarArg,
const TargetMachine &tm,
SmallVector<CCValAssign, 16> &locs,
LLVMContext &c)
- : CallingConv(CC), IsVarArg(isVarArg), TM(tm),
- TRI(*TM.getRegisterInfo()), Locs(locs), Context(c) {
+ : CallingConv(CC), IsVarArg(isVarArg), TM(tm), Locs(locs), Context(c) {
// No stack is used.
StackOffset = 0;
- UsedRegs.resize((TRI.getNumRegs()+31)/32);
+ UsedRegs.resize((TM.getRegisterInfo()->getNumRegs()+31)/32);
}
// HandleByVal - Allocate a stack slot large enough to pass an argument by
@@ -56,6 +55,7 @@ void Hexagon_CCState::HandleByVal(unsigned ValNo, EVT ValVT,
/// MarkAllocated - Mark a register and all of its aliases as allocated.
void Hexagon_CCState::MarkAllocated(unsigned Reg) {
+ const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI)
UsedRegs[*AI/32] |= 1 << (*AI&31);
}
diff --git a/lib/Target/Hexagon/HexagonCallingConvLower.h b/lib/Target/Hexagon/HexagonCallingConvLower.h
index 489b3a3..eed99f4 100644
--- a/lib/Target/Hexagon/HexagonCallingConvLower.h
+++ b/lib/Target/Hexagon/HexagonCallingConvLower.h
@@ -48,7 +48,6 @@ class Hexagon_CCState {
CallingConv::ID CallingConv;
bool IsVarArg;
const TargetMachine &TM;
- const TargetRegisterInfo &TRI;
SmallVector<CCValAssign, 16> &Locs;
LLVMContext &Context;
diff --git a/lib/Target/Hexagon/HexagonCopyToCombine.cpp b/lib/Target/Hexagon/HexagonCopyToCombine.cpp
new file mode 100644
index 0000000..dc440cb
--- /dev/null
+++ b/lib/Target/Hexagon/HexagonCopyToCombine.cpp
@@ -0,0 +1,677 @@
+//===------- HexagonCopyToCombine.cpp - Hexagon Copy-To-Combine Pass ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This pass replaces transfer instructions by combine instructions.
+// We walk along a basic block and look for two combinable instructions and try
+// to move them together. If we can move them next to each other we do so and
+// replace them with a combine instruction.
+//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "hexagon-copy-combine"
+
+#include "llvm/PassSupport.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include "Hexagon.h"
+#include "HexagonInstrInfo.h"
+#include "HexagonRegisterInfo.h"
+#include "HexagonSubtarget.h"
+#include "HexagonTargetMachine.h"
+#include "HexagonMachineFunctionInfo.h"
+
+using namespace llvm;
+
+static
+cl::opt<bool> IsCombinesDisabled("disable-merge-into-combines",
+ cl::Hidden, cl::ZeroOrMore,
+ cl::init(false),
+ cl::desc("Disable merging into combines"));
+static
+cl::opt<unsigned>
+MaxNumOfInstsBetweenNewValueStoreAndTFR("max-num-inst-between-tfr-and-nv-store",
+ cl::Hidden, cl::init(4),
+ cl::desc("Maximum distance between a tfr feeding a store we "
+ "consider the store still to be newifiable"));
+
+namespace llvm {
+ void initializeHexagonCopyToCombinePass(PassRegistry&);
+}
+
+
+namespace {
+
+class HexagonCopyToCombine : public MachineFunctionPass {
+ const HexagonInstrInfo *TII;
+ const TargetRegisterInfo *TRI;
+ bool ShouldCombineAggressively;
+
+ DenseSet<MachineInstr *> PotentiallyNewifiableTFR;
+public:
+ static char ID;
+
+ HexagonCopyToCombine() : MachineFunctionPass(ID) {
+ initializeHexagonCopyToCombinePass(*PassRegistry::getPassRegistry());
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+ const char *getPassName() const {
+ return "Hexagon Copy-To-Combine Pass";
+ }
+
+ virtual bool runOnMachineFunction(MachineFunction &Fn);
+
+private:
+ MachineInstr *findPairable(MachineInstr *I1, bool &DoInsertAtI1);
+
+ void findPotentialNewifiableTFRs(MachineBasicBlock &);
+
+ void combine(MachineInstr *I1, MachineInstr *I2,
+ MachineBasicBlock::iterator &MI, bool DoInsertAtI1);
+
+ bool isSafeToMoveTogether(MachineInstr *I1, MachineInstr *I2,
+ unsigned I1DestReg, unsigned I2DestReg,
+ bool &DoInsertAtI1);
+
+ void emitCombineRR(MachineBasicBlock::iterator &Before, unsigned DestReg,
+ MachineOperand &HiOperand, MachineOperand &LoOperand);
+
+ void emitCombineRI(MachineBasicBlock::iterator &Before, unsigned DestReg,
+ MachineOperand &HiOperand, MachineOperand &LoOperand);
+
+ void emitCombineIR(MachineBasicBlock::iterator &Before, unsigned DestReg,
+ MachineOperand &HiOperand, MachineOperand &LoOperand);
+
+ void emitCombineII(MachineBasicBlock::iterator &Before, unsigned DestReg,
+ MachineOperand &HiOperand, MachineOperand &LoOperand);
+};
+
+} // End anonymous namespace.
+
+char HexagonCopyToCombine::ID = 0;
+
+INITIALIZE_PASS(HexagonCopyToCombine, "hexagon-copy-combine",
+ "Hexagon Copy-To-Combine Pass", false, false)
+
+static bool isCombinableInstType(MachineInstr *MI,
+ const HexagonInstrInfo *TII,
+ bool ShouldCombineAggressively) {
+ switch(MI->getOpcode()) {
+ case Hexagon::TFR: {
+ // A COPY instruction can be combined if its arguments are IntRegs (32bit).
+ assert(MI->getOperand(0).isReg() && MI->getOperand(1).isReg());
+
+ unsigned DestReg = MI->getOperand(0).getReg();
+ unsigned SrcReg = MI->getOperand(1).getReg();
+ return Hexagon::IntRegsRegClass.contains(DestReg) &&
+ Hexagon::IntRegsRegClass.contains(SrcReg);
+ }
+
+ case Hexagon::TFRI: {
+ // A transfer-immediate can be combined if its argument is a signed 8bit
+ // value.
+ assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
+ unsigned DestReg = MI->getOperand(0).getReg();
+
+ // Only combine constant extended TFRI if we are in aggressive mode.
+ return Hexagon::IntRegsRegClass.contains(DestReg) &&
+ (ShouldCombineAggressively || isInt<8>(MI->getOperand(1).getImm()));
+ }
+
+ case Hexagon::TFRI_V4: {
+ if (!ShouldCombineAggressively)
+ return false;
+ assert(MI->getOperand(0).isReg() && MI->getOperand(1).isGlobal());
+
+ // Ensure that TargetFlags are MO_NO_FLAG for a global. This is a
+ // workaround for an ABI bug that prevents GOT relocations on combine
+ // instructions
+ if (MI->getOperand(1).getTargetFlags() != HexagonII::MO_NO_FLAG)
+ return false;
+
+ unsigned DestReg = MI->getOperand(0).getReg();
+ return Hexagon::IntRegsRegClass.contains(DestReg);
+ }
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+static bool isGreaterThan8BitTFRI(MachineInstr *I) {
+ return I->getOpcode() == Hexagon::TFRI &&
+ !isInt<8>(I->getOperand(1).getImm());
+}
+static bool isGreaterThan6BitTFRI(MachineInstr *I) {
+ return I->getOpcode() == Hexagon::TFRI &&
+ !isUInt<6>(I->getOperand(1).getImm());
+}
+
+/// areCombinableOperations - Returns true if the two instruction can be merge
+/// into a combine (ignoring register constraints).
+static bool areCombinableOperations(const TargetRegisterInfo *TRI,
+ MachineInstr *HighRegInst,
+ MachineInstr *LowRegInst) {
+ assert((HighRegInst->getOpcode() == Hexagon::TFR ||
+ HighRegInst->getOpcode() == Hexagon::TFRI ||
+ HighRegInst->getOpcode() == Hexagon::TFRI_V4) &&
+ (LowRegInst->getOpcode() == Hexagon::TFR ||
+ LowRegInst->getOpcode() == Hexagon::TFRI ||
+ 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)) &&
+ (LowRegInst->getOpcode() == Hexagon::TFRI_V4 ||
+ isGreaterThan6BitTFRI(LowRegInst)))
+ return false;
+
+ return true;
+}
+
+static bool isEvenReg(unsigned Reg) {
+ assert(TargetRegisterInfo::isPhysicalRegister(Reg) &&
+ Hexagon::IntRegsRegClass.contains(Reg));
+ return (Reg - Hexagon::R0) % 2 == 0;
+}
+
+static void removeKillInfo(MachineInstr *MI, unsigned RegNotKilled) {
+ for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) {
+ MachineOperand &Op = MI->getOperand(I);
+ if (!Op.isReg() || Op.getReg() != RegNotKilled || !Op.isKill())
+ continue;
+ Op.setIsKill(false);
+ }
+}
+
+/// isUnsafeToMoveAcross - Returns true if it is unsafe to move a copy
+/// instruction from \p UseReg to \p DestReg over the instruction \p I.
+static bool isUnsafeToMoveAcross(MachineInstr *I, unsigned UseReg,
+ unsigned DestReg,
+ const TargetRegisterInfo *TRI) {
+ return (UseReg && (I->modifiesRegister(UseReg, TRI))) ||
+ I->modifiesRegister(DestReg, TRI) ||
+ I->readsRegister(DestReg, TRI) ||
+ I->hasUnmodeledSideEffects() ||
+ I->isInlineAsm() || I->isDebugValue();
+}
+
+/// isSafeToMoveTogether - Returns true if it is safe to move I1 next to I2 such
+/// that the two instructions can be paired in a combine.
+bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1,
+ MachineInstr *I2,
+ unsigned I1DestReg,
+ unsigned I2DestReg,
+ bool &DoInsertAtI1) {
+
+ bool IsImmUseReg = I2->getOperand(1).isImm() || I2->getOperand(1).isGlobal();
+ unsigned I2UseReg = IsImmUseReg ? 0 : I2->getOperand(1).getReg();
+
+ // It is not safe to move I1 and I2 into one combine if I2 has a true
+ // dependence on I1.
+ if (I2UseReg && I1->modifiesRegister(I2UseReg, TRI))
+ return false;
+
+ bool isSafe = true;
+
+ // First try to move I2 towards I1.
+ {
+ // A reverse_iterator instantiated like below starts before I2, and I1
+ // respectively.
+ // Look at instructions I in between I2 and (excluding) I1.
+ MachineBasicBlock::reverse_iterator I(I2),
+ End = --(MachineBasicBlock::reverse_iterator(I1));
+ // At 03 we got better results (dhrystone!) by being more conservative.
+ if (!ShouldCombineAggressively)
+ End = MachineBasicBlock::reverse_iterator(I1);
+ // If I2 kills its operand and we move I2 over an instruction that also
+ // uses I2's use reg we need to modify that (first) instruction to now kill
+ // this reg.
+ unsigned KilledOperand = 0;
+ if (I2->killsRegister(I2UseReg))
+ KilledOperand = I2UseReg;
+ MachineInstr *KillingInstr = 0;
+
+ for (; I != End; ++I) {
+ // If the intervening instruction I:
+ // * modifies I2's use reg
+ // * modifies I2's def reg
+ // * reads I2's def reg
+ // * or has unmodelled side effects
+ // we can't move I2 across it.
+ if (isUnsafeToMoveAcross(&*I, I2UseReg, I2DestReg, TRI)) {
+ isSafe = false;
+ break;
+ }
+
+ // Update first use of the killed operand.
+ if (!KillingInstr && KilledOperand &&
+ I->readsRegister(KilledOperand, TRI))
+ KillingInstr = &*I;
+ }
+ if (isSafe) {
+ // Update the intermediate instruction to with the kill flag.
+ if (KillingInstr) {
+ bool Added = KillingInstr->addRegisterKilled(KilledOperand, TRI, true);
+ (void)Added; // supress compiler warning
+ assert(Added && "Must successfully update kill flag");
+ removeKillInfo(I2, KilledOperand);
+ }
+ DoInsertAtI1 = true;
+ return true;
+ }
+ }
+
+ // Try to move I1 towards I2.
+ {
+ // Look at instructions I in between I1 and (excluding) I2.
+ MachineBasicBlock::iterator I(I1), End(I2);
+ // At O3 we got better results (dhrystone) by being more conservative here.
+ if (!ShouldCombineAggressively)
+ End = llvm::next(MachineBasicBlock::iterator(I2));
+ IsImmUseReg = I1->getOperand(1).isImm() || I1->getOperand(1).isGlobal();
+ unsigned I1UseReg = IsImmUseReg ? 0 : I1->getOperand(1).getReg();
+ // Track killed operands. If we move across an instruction that kills our
+ // operand, we need to update the kill information on the moved I1. It kills
+ // the operand now.
+ MachineInstr *KillingInstr = 0;
+ unsigned KilledOperand = 0;
+
+ while(++I != End) {
+ // If the intervening instruction I:
+ // * modifies I1's use reg
+ // * modifies I1's def reg
+ // * reads I1's def reg
+ // * or has unmodelled side effects
+ // We introduce this special case because llvm has no api to remove a
+ // kill flag for a register (a removeRegisterKilled() analogous to
+ // addRegisterKilled) that handles aliased register correctly.
+ // * or has a killed aliased register use of I1's use reg
+ // %D4<def> = TFRI64 16
+ // %R6<def> = TFR %R9
+ // %R8<def> = KILL %R8, %D4<imp-use,kill>
+ // If we want to move R6 = across the KILL instruction we would have
+ // to remove the %D4<imp-use,kill> operand. For now, we are
+ // conservative and disallow the move.
+ // we can't move I1 across it.
+ if (isUnsafeToMoveAcross(I, I1UseReg, I1DestReg, TRI) ||
+ // Check for an aliased register kill. Bail out if we see one.
+ (!I->killsRegister(I1UseReg) && I->killsRegister(I1UseReg, TRI)))
+ return false;
+
+ // Check for an exact kill (registers match).
+ if (I1UseReg && I->killsRegister(I1UseReg)) {
+ assert(KillingInstr == 0 && "Should only see one killing instruction");
+ KilledOperand = I1UseReg;
+ KillingInstr = &*I;
+ }
+ }
+ if (KillingInstr) {
+ removeKillInfo(KillingInstr, KilledOperand);
+ // Update I1 to set the kill flag. This flag will later be picked up by
+ // the new COMBINE instruction.
+ bool Added = I1->addRegisterKilled(KilledOperand, TRI);
+ (void)Added; // supress compiler warning
+ assert(Added && "Must successfully update kill flag");
+ }
+ DoInsertAtI1 = false;
+ }
+
+ return true;
+}
+
+/// findPotentialNewifiableTFRs - Finds tranfers that feed stores that could be
+/// newified. (A use of a 64 bit register define can not be newified)
+void
+HexagonCopyToCombine::findPotentialNewifiableTFRs(MachineBasicBlock &BB) {
+ DenseMap<unsigned, MachineInstr *> LastDef;
+ for (MachineBasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) {
+ MachineInstr *MI = I;
+ // Mark TFRs that feed a potential new value store as such.
+ if(TII->mayBeNewStore(MI)) {
+ // Look for uses of TFR instructions.
+ for (unsigned OpdIdx = 0, OpdE = MI->getNumOperands(); OpdIdx != OpdE;
+ ++OpdIdx) {
+ MachineOperand &Op = MI->getOperand(OpdIdx);
+
+ // Skip over anything except register uses.
+ if (!Op.isReg() || !Op.isUse() || !Op.getReg())
+ continue;
+
+ // Look for the defining instruction.
+ unsigned Reg = Op.getReg();
+ MachineInstr *DefInst = LastDef[Reg];
+ if (!DefInst)
+ continue;
+ if (!isCombinableInstType(DefInst, TII, ShouldCombineAggressively))
+ continue;
+
+ // Only close newifiable stores should influence the decision.
+ MachineBasicBlock::iterator It(DefInst);
+ unsigned NumInstsToDef = 0;
+ while (&*It++ != MI)
+ ++NumInstsToDef;
+
+ if (NumInstsToDef > MaxNumOfInstsBetweenNewValueStoreAndTFR)
+ continue;
+
+ PotentiallyNewifiableTFR.insert(DefInst);
+ }
+ // Skip to next instruction.
+ continue;
+ }
+
+ // Put instructions that last defined integer or double registers into the
+ // map.
+ for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) {
+ MachineOperand &Op = MI->getOperand(I);
+ if (!Op.isReg() || !Op.isDef() || !Op.getReg())
+ continue;
+ unsigned Reg = Op.getReg();
+ if (Hexagon::DoubleRegsRegClass.contains(Reg)) {
+ for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) {
+ LastDef[*SubRegs] = MI;
+ }
+ } else if (Hexagon::IntRegsRegClass.contains(Reg))
+ LastDef[Reg] = MI;
+ }
+ }
+}
+
+bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) {
+
+ if (IsCombinesDisabled) return false;
+
+ bool HasChanged = false;
+
+ // Get target info.
+ TRI = MF.getTarget().getRegisterInfo();
+ TII = static_cast<const HexagonInstrInfo *>(MF.getTarget().getInstrInfo());
+
+ // Combine aggressively (for code size)
+ ShouldCombineAggressively =
+ MF.getTarget().getOptLevel() <= CodeGenOpt::Default;
+
+ // Traverse basic blocks.
+ for (MachineFunction::iterator BI = MF.begin(), BE = MF.end(); BI != BE;
+ ++BI) {
+ PotentiallyNewifiableTFR.clear();
+ findPotentialNewifiableTFRs(*BI);
+
+ // Traverse instructions in basic block.
+ for(MachineBasicBlock::iterator MI = BI->begin(), End = BI->end();
+ MI != End;) {
+ MachineInstr *I1 = MI++;
+ // Don't combine a TFR whose user could be newified (instructions that
+ // define double registers can not be newified - Programmer's Ref Manual
+ // 5.4.2 New-value stores).
+ if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(I1))
+ continue;
+
+ // Ignore instructions that are not combinable.
+ if (!isCombinableInstType(I1, TII, ShouldCombineAggressively))
+ continue;
+
+ // Find a second instruction that can be merged into a combine
+ // instruction.
+ bool DoInsertAtI1 = false;
+ MachineInstr *I2 = findPairable(I1, DoInsertAtI1);
+ if (I2) {
+ HasChanged = true;
+ combine(I1, I2, MI, DoInsertAtI1);
+ }
+ }
+ }
+
+ return HasChanged;
+}
+
+/// findPairable - Returns an instruction that can be merged with \p I1 into a
+/// COMBINE instruction or 0 if no such instruction can be found. Returns true
+/// in \p DoInsertAtI1 if the combine must be inserted at instruction \p I1
+/// false if the combine must be inserted at the returned instruction.
+MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr *I1,
+ bool &DoInsertAtI1) {
+ MachineBasicBlock::iterator I2 = llvm::next(MachineBasicBlock::iterator(I1));
+ unsigned I1DestReg = I1->getOperand(0).getReg();
+
+ for (MachineBasicBlock::iterator End = I1->getParent()->end(); I2 != End;
+ ++I2) {
+ // Bail out early if we see a second definition of I1DestReg.
+ if (I2->modifiesRegister(I1DestReg, TRI))
+ break;
+
+ // Ignore non-combinable instructions.
+ if (!isCombinableInstType(I2, TII, ShouldCombineAggressively))
+ continue;
+
+ // Don't combine a TFR whose user could be newified.
+ if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(I2))
+ continue;
+
+ unsigned I2DestReg = I2->getOperand(0).getReg();
+
+ // Check that registers are adjacent and that the first destination register
+ // is even.
+ bool IsI1LowReg = (I2DestReg - I1DestReg) == 1;
+ bool IsI2LowReg = (I1DestReg - I2DestReg) == 1;
+ unsigned FirstRegIndex = IsI1LowReg ? I1DestReg : I2DestReg;
+ if ((!IsI1LowReg && !IsI2LowReg) || !isEvenReg(FirstRegIndex))
+ continue;
+
+ // Check that the two instructions are combinable. V4 allows more
+ // instructions to be merged into a combine.
+ // The order matters because in a TFRI we might can encode a int8 as the
+ // hi reg operand but only a uint6 as the low reg operand.
+ if ((IsI2LowReg && !areCombinableOperations(TRI, I1, I2)) ||
+ (IsI1LowReg && !areCombinableOperations(TRI, I2, I1)))
+ break;
+
+ if (isSafeToMoveTogether(I1, I2, I1DestReg, I2DestReg,
+ DoInsertAtI1))
+ return I2;
+
+ // Not safe. Stop searching.
+ break;
+ }
+ return 0;
+}
+
+void HexagonCopyToCombine::combine(MachineInstr *I1, MachineInstr *I2,
+ MachineBasicBlock::iterator &MI,
+ bool DoInsertAtI1) {
+ // We are going to delete I2. If MI points to I2 advance it to the next
+ // instruction.
+ if ((MachineInstr *)MI == I2) ++MI;
+
+ // Figure out whether I1 or I2 goes into the lowreg part.
+ unsigned I1DestReg = I1->getOperand(0).getReg();
+ unsigned I2DestReg = I2->getOperand(0).getReg();
+ bool IsI1Loreg = (I2DestReg - I1DestReg) == 1;
+ unsigned LoRegDef = IsI1Loreg ? I1DestReg : I2DestReg;
+
+ // Get the double word register.
+ unsigned DoubleRegDest =
+ TRI->getMatchingSuperReg(LoRegDef, Hexagon::subreg_loreg,
+ &Hexagon::DoubleRegsRegClass);
+ assert(DoubleRegDest != 0 && "Expect a valid register");
+
+
+ // Setup source operands.
+ MachineOperand &LoOperand = IsI1Loreg ? I1->getOperand(1) :
+ I2->getOperand(1);
+ MachineOperand &HiOperand = IsI1Loreg ? I2->getOperand(1) :
+ I1->getOperand(1);
+
+ // Figure out which source is a register and which a constant.
+ bool IsHiReg = HiOperand.isReg();
+ bool IsLoReg = LoOperand.isReg();
+
+ MachineBasicBlock::iterator InsertPt(DoInsertAtI1 ? I1 : I2);
+ // Emit combine.
+ if (IsHiReg && IsLoReg)
+ emitCombineRR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
+ else if (IsHiReg)
+ emitCombineRI(InsertPt, DoubleRegDest, HiOperand, LoOperand);
+ else if (IsLoReg)
+ emitCombineIR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
+ else
+ emitCombineII(InsertPt, DoubleRegDest, HiOperand, LoOperand);
+
+ I1->eraseFromParent();
+ I2->eraseFromParent();
+}
+
+void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt,
+ unsigned DoubleDestReg,
+ MachineOperand &HiOperand,
+ MachineOperand &LoOperand) {
+ DebugLoc DL = InsertPt->getDebugLoc();
+ MachineBasicBlock *BB = InsertPt->getParent();
+
+ // Handle globals.
+ if (HiOperand.isGlobal()) {
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ii), DoubleDestReg)
+ .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),
+ HiOperand.getTargetFlags())
+ .addImm(LoOperand.getImm());
+ return;
+ }
+ if (LoOperand.isGlobal()) {
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_iI_V4), DoubleDestReg)
+ .addImm(HiOperand.getImm())
+ .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),
+ LoOperand.getTargetFlags());
+ return;
+ }
+
+ // Handle constant extended immediates.
+ if (!isInt<8>(HiOperand.getImm())) {
+ assert(isInt<8>(LoOperand.getImm()));
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ii), DoubleDestReg)
+ .addImm(HiOperand.getImm())
+ .addImm(LoOperand.getImm());
+ return;
+ }
+
+ if (!isUInt<6>(LoOperand.getImm())) {
+ assert(isInt<8>(HiOperand.getImm()));
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_iI_V4), DoubleDestReg)
+ .addImm(HiOperand.getImm())
+ .addImm(LoOperand.getImm());
+ return;
+ }
+
+ // Insert new combine instruction.
+ // DoubleRegDest = combine #HiImm, #LoImm
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ii), DoubleDestReg)
+ .addImm(HiOperand.getImm())
+ .addImm(LoOperand.getImm());
+}
+
+void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt,
+ unsigned DoubleDestReg,
+ MachineOperand &HiOperand,
+ MachineOperand &LoOperand) {
+ unsigned LoReg = LoOperand.getReg();
+ unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill());
+
+ DebugLoc DL = InsertPt->getDebugLoc();
+ MachineBasicBlock *BB = InsertPt->getParent();
+
+ // Handle global.
+ if (HiOperand.isGlobal()) {
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ir_V4), DoubleDestReg)
+ .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),
+ HiOperand.getTargetFlags())
+ .addReg(LoReg, LoRegKillFlag);
+ return;
+ }
+ // Insert new combine instruction.
+ // DoubleRegDest = combine #HiImm, LoReg
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ir_V4), DoubleDestReg)
+ .addImm(HiOperand.getImm())
+ .addReg(LoReg, LoRegKillFlag);
+}
+
+void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt,
+ unsigned DoubleDestReg,
+ MachineOperand &HiOperand,
+ MachineOperand &LoOperand) {
+ unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill());
+ unsigned HiReg = HiOperand.getReg();
+
+ DebugLoc DL = InsertPt->getDebugLoc();
+ MachineBasicBlock *BB = InsertPt->getParent();
+
+ // Handle global.
+ if (LoOperand.isGlobal()) {
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_rI_V4), DoubleDestReg)
+ .addReg(HiReg, HiRegKillFlag)
+ .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),
+ LoOperand.getTargetFlags());
+ return;
+ }
+
+ // Insert new combine instruction.
+ // DoubleRegDest = combine HiReg, #LoImm
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_rI_V4), DoubleDestReg)
+ .addReg(HiReg, HiRegKillFlag)
+ .addImm(LoOperand.getImm());
+}
+
+void HexagonCopyToCombine::emitCombineRR(MachineBasicBlock::iterator &InsertPt,
+ unsigned DoubleDestReg,
+ MachineOperand &HiOperand,
+ MachineOperand &LoOperand) {
+ unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill());
+ unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill());
+ unsigned LoReg = LoOperand.getReg();
+ unsigned HiReg = HiOperand.getReg();
+
+ DebugLoc DL = InsertPt->getDebugLoc();
+ MachineBasicBlock *BB = InsertPt->getParent();
+
+ // Insert new combine instruction.
+ // DoubleRegDest = combine HiReg, LoReg
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_rr), DoubleDestReg)
+ .addReg(HiReg, HiRegKillFlag)
+ .addReg(LoReg, LoRegKillFlag);
+}
+
+FunctionPass *llvm::createHexagonCopyToCombine() {
+ return new HexagonCopyToCombine();
+}
diff --git a/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp b/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp
index 0814421..8a5991f 100644
--- a/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp
+++ b/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp
@@ -41,16 +41,24 @@
using namespace llvm;
+namespace llvm {
+ void initializeHexagonExpandPredSpillCodePass(PassRegistry&);
+}
+
+
namespace {
class HexagonExpandPredSpillCode : public MachineFunctionPass {
- HexagonTargetMachine& QTM;
+ const HexagonTargetMachine& QTM;
const HexagonSubtarget &QST;
public:
static char ID;
- HexagonExpandPredSpillCode(HexagonTargetMachine& TM) :
- MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) {}
+ HexagonExpandPredSpillCode(const HexagonTargetMachine& TM) :
+ MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) {
+ PassRegistry &Registry = *PassRegistry::getPassRegistry();
+ initializeHexagonExpandPredSpillCodePass(Registry);
+ }
const char *getPassName() const {
return "Hexagon Expand Predicate Spill Code";
@@ -175,6 +183,19 @@ bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) {
// Public Constructor Functions
//===----------------------------------------------------------------------===//
-FunctionPass *llvm::createHexagonExpandPredSpillCode(HexagonTargetMachine &TM) {
+static void initializePassOnce(PassRegistry &Registry) {
+ const char *Name = "Hexagon Expand Predicate Spill Code";
+ PassInfo *PI = new PassInfo(Name, "hexagon-spill-pred",
+ &HexagonExpandPredSpillCode::ID,
+ 0, false, false);
+ Registry.registerPass(*PI, true);
+}
+
+void llvm::initializeHexagonExpandPredSpillCodePass(PassRegistry &Registry) {
+ CALL_ONCE_INITIALIZATION(initializePassOnce)
+}
+
+FunctionPass*
+llvm::createHexagonExpandPredSpillCode(const HexagonTargetMachine &TM) {
return new HexagonExpandPredSpillCode(TM);
}
diff --git a/lib/Target/Hexagon/HexagonFrameLowering.cpp b/lib/Target/Hexagon/HexagonFrameLowering.cpp
index de993ee8..2b04f25 100644
--- a/lib/Target/Hexagon/HexagonFrameLowering.cpp
+++ b/lib/Target/Hexagon/HexagonFrameLowering.cpp
@@ -76,17 +76,12 @@ void HexagonFrameLowering::determineFrameLayout(MachineFunction &MF) const {
void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front();
MachineFrameInfo *MFI = MF.getFrameInfo();
- MachineModuleInfo &MMI = MF.getMMI();
MachineBasicBlock::iterator MBBI = MBB.begin();
const HexagonRegisterInfo *QRI =
static_cast<const HexagonRegisterInfo *>(MF.getTarget().getRegisterInfo());
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
determineFrameLayout(MF);
- // Check if frame moves are needed for EH.
- bool needsFrameMoves = MMI.hasDebugInfo() ||
- !MF.getFunction()->needsUnwindTableEntry();
-
// Get the number of bytes to allocate from the FrameInfo.
int NumBytes = (int) MFI->getStackSize();
@@ -113,28 +108,6 @@ void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const {
MO.setImm(MFI->getMaxCallFrameSize());
}
- std::vector<MachineMove> &Moves = MMI.getFrameMoves();
-
- if (needsFrameMoves) {
- // Advance CFA. DW_CFA_def_cfa
- unsigned FPReg = QRI->getFrameRegister();
- unsigned RAReg = QRI->getRARegister();
-
- MachineLocation Dst(MachineLocation::VirtualFP);
- MachineLocation Src(FPReg, -8);
- Moves.push_back(MachineMove(0, Dst, Src));
-
- // R31 = (R31 - #4)
- MachineLocation LRDst(RAReg, -4);
- MachineLocation LRSrc(RAReg);
- Moves.push_back(MachineMove(0, LRDst, LRSrc));
-
- // R30 = (R30 - #8)
- MachineLocation SPDst(FPReg, -8);
- MachineLocation SPSrc(FPReg);
- Moves.push_back(MachineMove(0, SPDst, SPSrc));
- }
-
//
// Only insert ALLOCFRAME if we need to.
//
@@ -174,30 +147,55 @@ void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock::iterator MBBI = prior(MBB.end());
DebugLoc dl = MBBI->getDebugLoc();
//
- // Only insert deallocframe if we need to.
+ // Only insert deallocframe if we need to. Also at -O0. See comment
+ // in emitPrologue above.
//
- if (hasFP(MF)) {
+ if (hasFP(MF) || MF.getTarget().getOptLevel() == CodeGenOpt::None) {
MachineBasicBlock::iterator MBBI = prior(MBB.end());
MachineBasicBlock::iterator MBBI_end = MBB.end();
- //
- // For Hexagon, we don't need the frame size.
- //
- MachineFrameInfo *MFI = MF.getFrameInfo();
- int NumBytes = (int) MFI->getStackSize();
const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
-
+ // Handle EH_RETURN.
+ if (MBBI->getOpcode() == Hexagon::EH_RETURN_JMPR) {
+ assert(MBBI->getOperand(0).isReg() && "Offset should be in register!");
+ BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME));
+ BuildMI(MBB, MBBI, dl, TII.get(Hexagon::ADD_rr),
+ Hexagon::R29).addReg(Hexagon::R29).addReg(Hexagon::R28);
+ return;
+ }
// Replace 'jumpr r31' instruction with dealloc_return for V4 and higher
// versions.
if (STI.hasV4TOps() && MBBI->getOpcode() == Hexagon::JMPret
&& !DisableDeallocRet) {
- // Remove jumpr node.
- MBB.erase(MBBI);
+ // Check for RESTORE_DEALLOC_RET_JMP_V4 call. Don't emit an extra DEALLOC
+ // instruction if we encounter it.
+ MachineBasicBlock::iterator BeforeJMPR =
+ MBB.begin() == MBBI ? MBBI : prior(MBBI);
+ if (BeforeJMPR != MBBI &&
+ BeforeJMPR->getOpcode() == Hexagon::RESTORE_DEALLOC_RET_JMP_V4) {
+ // Remove the JMPR node.
+ MBB.erase(MBBI);
+ return;
+ }
+
// Add dealloc_return.
- BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::DEALLOC_RET_V4))
- .addImm(NumBytes);
- } else { // Add deallocframe for V2 and V3.
- BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME)).addImm(NumBytes);
+ MachineInstrBuilder MIB =
+ BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::DEALLOC_RET_V4));
+ // Transfer the function live-out registers.
+ MIB->copyImplicitOps(*MBB.getParent(), &*MBBI);
+ // Remove the JUMPR node.
+ MBB.erase(MBBI);
+ } else { // Add deallocframe for V2 and V3, and V4 tail calls.
+ // Check for RESTORE_DEALLOC_BEFORE_TAILCALL_V4. We don't need an extra
+ // DEALLOCFRAME instruction after it.
+ MachineBasicBlock::iterator Term = MBB.getFirstTerminator();
+ MachineBasicBlock::iterator I =
+ Term == MBB.begin() ? MBB.end() : prior(Term);
+ if (I != MBB.end() &&
+ I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4)
+ return;
+
+ BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME));
}
}
}
diff --git a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
index ba6c100..22740b7 100644
--- a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
+++ b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
@@ -49,16 +49,14 @@ class HexagonDAGToDAGISel : public SelectionDAGISel {
const HexagonSubtarget &Subtarget;
// Keep a reference to HexagonTargetMachine.
- HexagonTargetMachine& TM;
- const HexagonInstrInfo *TII;
+ const HexagonTargetMachine& TM;
DenseMap<const GlobalValue *, unsigned> GlobalAddressUseCountMap;
public:
- explicit HexagonDAGToDAGISel(HexagonTargetMachine &targetmachine,
+ explicit HexagonDAGToDAGISel(const HexagonTargetMachine &targetmachine,
CodeGenOpt::Level OptLevel)
: SelectionDAGISel(targetmachine, OptLevel),
Subtarget(targetmachine.getSubtarget<HexagonSubtarget>()),
- TM(targetmachine),
- TII(static_cast<const HexagonInstrInfo*>(TM.getInstrInfo())) {
+ TM(targetmachine) {
initializeHexagonDAGToDAGISelPass(*PassRegistry::getPassRegistry());
}
bool hasNumUsesBelowThresGA(SDNode *N) const;
@@ -92,14 +90,14 @@ public:
bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset);
SDNode *SelectLoad(SDNode *N);
- SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl);
- SDNode *SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl);
+ SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl);
+ SDNode *SelectIndexedLoad(LoadSDNode *LD, SDLoc dl);
SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode,
- DebugLoc dl);
+ SDLoc dl);
SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode,
- DebugLoc dl);
- SDNode *SelectBaseOffsetStore(StoreSDNode *ST, DebugLoc dl);
- SDNode *SelectIndexedStore(StoreSDNode *ST, DebugLoc dl);
+ SDLoc dl);
+ SDNode *SelectBaseOffsetStore(StoreSDNode *ST, SDLoc dl);
+ SDNode *SelectIndexedStore(StoreSDNode *ST, SDLoc dl);
SDNode *SelectStore(SDNode *N);
SDNode *SelectSHL(SDNode *N);
SDNode *SelectSelect(SDNode *N);
@@ -180,7 +178,7 @@ inline SDValue XformUToUM1Imm(unsigned Imm) {
/// createHexagonISelDag - This pass converts a legalized DAG into a
/// Hexagon-specific DAG, ready for instruction scheduling.
///
-FunctionPass *llvm::createHexagonISelDag(HexagonTargetMachine &TM,
+FunctionPass *llvm::createHexagonISelDag(const HexagonTargetMachine &TM,
CodeGenOpt::Level OptLevel) {
return new HexagonDAGToDAGISel(TM, OptLevel);
}
@@ -385,7 +383,7 @@ static bool OffsetFitsS11(EVT MemType, int64_t Offset) {
// lowering for GlobalAddress nodes has already turned it into a
// CONST32.
//
-SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) {
+SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl) {
SDValue Chain = LD->getChain();
SDNode* Const32 = LD->getBasePtr().getNode();
unsigned Opcode = 0;
@@ -396,7 +394,7 @@ SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) {
EVT LoadedVT = LD->getMemoryVT();
int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) {
- MVT PointerTy = TLI.getPointerTy();
+ MVT PointerTy = TLI->getPointerTy();
const GlobalValue* GV =
cast<GlobalAddressSDNode>(Base)->getGlobal();
SDValue TargAddr =
@@ -433,7 +431,7 @@ SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) {
SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
unsigned Opcode,
- DebugLoc dl)
+ SDLoc dl)
{
SDValue Chain = LD->getChain();
EVT LoadedVT = LD->getMemoryVT();
@@ -444,6 +442,9 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
SDValue N1 = LD->getOperand(1);
SDValue CPTmpN1_0;
SDValue CPTmpN1_1;
+
+ const HexagonInstrInfo *TII =
+ static_cast<const HexagonInstrInfo*>(TM.getInstrInfo());
if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
N1.getNode()->getValueType(0) == MVT::i32) {
if (TII->isValidAutoIncImm(LoadedVT, Val)) {
@@ -497,7 +498,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
unsigned Opcode,
- DebugLoc dl)
+ SDLoc dl)
{
SDValue Chain = LD->getChain();
EVT LoadedVT = LD->getMemoryVT();
@@ -508,6 +509,9 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
SDValue N1 = LD->getOperand(1);
SDValue CPTmpN1_0;
SDValue CPTmpN1_1;
+
+ const HexagonInstrInfo *TII =
+ static_cast<const HexagonInstrInfo*>(TM.getInstrInfo());
if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
N1.getNode()->getValueType(0) == MVT::i32) {
if (TII->isValidAutoIncImm(LoadedVT, Val)) {
@@ -572,7 +576,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
}
-SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl) {
+SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, SDLoc dl) {
SDValue Chain = LD->getChain();
SDValue Base = LD->getBasePtr();
SDValue Offset = LD->getOffset();
@@ -586,6 +590,8 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl) {
bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);
// Figure out the opcode.
+ const HexagonInstrInfo *TII =
+ static_cast<const HexagonInstrInfo*>(TM.getInstrInfo());
if (LoadedVT == MVT::i64) {
if (TII->isValidAutoIncImm(LoadedVT, Val))
Opcode = Hexagon::POST_LDrid;
@@ -667,7 +673,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl) {
SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
SDNode *result;
- DebugLoc dl = N->getDebugLoc();
+ SDLoc dl(N);
LoadSDNode *LD = cast<LoadSDNode>(N);
ISD::MemIndexedMode AM = LD->getAddressingMode();
@@ -682,7 +688,7 @@ SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
}
-SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) {
+SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) {
SDValue Chain = ST->getChain();
SDValue Base = ST->getBasePtr();
SDValue Offset = ST->getOffset();
@@ -694,6 +700,8 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) {
// Offset value must be within representable range
// and must have correct alignment properties.
+ const HexagonInstrInfo *TII =
+ static_cast<const HexagonInstrInfo*>(TM.getInstrInfo());
if (TII->isValidAutoIncImm(StoredVT, Val)) {
SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value,
Chain};
@@ -751,7 +759,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) {
SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
- DebugLoc dl) {
+ SDLoc dl) {
SDValue Chain = ST->getChain();
SDNode* Const32 = ST->getBasePtr().getNode();
SDValue Value = ST->getValue();
@@ -769,7 +777,7 @@ SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
EVT StoredVT = ST->getMemoryVT();
int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) {
- MVT PointerTy = TLI.getPointerTy();
+ MVT PointerTy = TLI->getPointerTy();
const GlobalValue* GV =
cast<GlobalAddressSDNode>(Base)->getGlobal();
SDValue TargAddr =
@@ -805,7 +813,7 @@ SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
- DebugLoc dl = N->getDebugLoc();
+ SDLoc dl(N);
StoreSDNode *ST = cast<StoreSDNode>(N);
ISD::MemIndexedMode AM = ST->getAddressingMode();
@@ -818,7 +826,7 @@ SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
}
SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
- DebugLoc dl = N->getDebugLoc();
+ SDLoc dl(N);
//
// %conv.i = sext i32 %tmp1 to i64
@@ -902,7 +910,7 @@ SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
- DebugLoc dl = N->getDebugLoc();
+ SDLoc dl(N);
SDValue N0 = N->getOperand(0);
if (N0.getOpcode() == ISD::SETCC) {
SDValue N00 = N0.getOperand(0);
@@ -969,7 +977,7 @@ SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
- DebugLoc dl = N->getDebugLoc();
+ SDLoc dl(N);
SDValue Shift = N->getOperand(0);
//
@@ -1082,7 +1090,7 @@ SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
- DebugLoc dl = N->getDebugLoc();
+ SDLoc dl(N);
if (N->getValueType(0) == MVT::i32) {
SDValue Shl_0 = N->getOperand(0);
SDValue Shl_1 = N->getOperand(1);
@@ -1158,7 +1166,7 @@ SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
// We want to preserve all the lower 8-bits and, not just 1 LSB bit.
//
SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
- DebugLoc dl = N->getDebugLoc();
+ SDLoc dl(N);
SDNode *IsIntrinsic = N->getOperand(0).getNode();
if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
unsigned ID =
@@ -1201,12 +1209,14 @@ SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
// and lowering to the actual intrinsic.
//
SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
- DebugLoc dl = N->getDebugLoc();
+ SDLoc dl(N);
unsigned ID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
unsigned IntrinsicWithPred = doesIntrinsicContainPredicate(ID);
// We are concerned with only those intrinsics that have predicate registers
// as at least one of the operands.
+ const HexagonInstrInfo *TII =
+ static_cast<const HexagonInstrInfo*>(TM.getInstrInfo());
if (IntrinsicWithPred) {
SmallVector<SDValue, 8> Ops;
const MCInstrDesc &MCID = TII->get(IntrinsicWithPred);
@@ -1251,7 +1261,7 @@ SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
// Map floating point constant values.
//
SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
- DebugLoc dl = N->getDebugLoc();
+ SDLoc dl(N);
ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
APFloat APF = CN->getValueAPF();
if (N->getValueType(0) == MVT::f32) {
@@ -1271,7 +1281,7 @@ SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
// Map predicate true (encoded as -1 in LLVM) to a XOR.
//
SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
- DebugLoc dl = N->getDebugLoc();
+ SDLoc dl(N);
if (N->getValueType(0) == MVT::i1) {
SDNode* Result;
int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
@@ -1310,7 +1320,7 @@ SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
// Map add followed by a asr -> asr +=.
//
SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
- DebugLoc dl = N->getDebugLoc();
+ SDLoc dl(N);
if (N->getValueType(0) != MVT::i32) {
return SelectCode(N);
}
@@ -1660,7 +1670,7 @@ bool HexagonDAGToDAGISel::foldGlobalAddressImpl(SDValue &N, SDValue &R,
!hasNumUsesBelowThresGA(GA))
return false;
R = CurDAG->getTargetGlobalAddress(GA->getGlobal(),
- Const->getDebugLoc(),
+ SDLoc(Const),
N.getValueType(),
GA->getOffset() +
(uint64_t)Const->getSExtValue());
diff --git a/lib/Target/Hexagon/HexagonISelLowering.cpp b/lib/Target/Hexagon/HexagonISelLowering.cpp
index 0e5b8dc..2b0fa5e 100644
--- a/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -285,7 +285,7 @@ const {
static SDValue
CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain,
ISD::ArgFlagsTy Flags, SelectionDAG &DAG,
- DebugLoc dl) {
+ SDLoc dl) {
SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i32);
return DAG.getMemcpy(Chain, dl, Dst, Src, SizeNode, Flags.getByValAlign(),
@@ -302,7 +302,7 @@ HexagonTargetLowering::LowerReturn(SDValue Chain,
CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<SDValue> &OutVals,
- DebugLoc dl, SelectionDAG &DAG) const {
+ SDLoc dl, SelectionDAG &DAG) const {
// CCValAssign - represent the assignment of the return value to locations.
SmallVector<CCValAssign, 16> RVLocs;
@@ -351,7 +351,7 @@ HexagonTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
CallingConv::ID CallConv, bool isVarArg,
const
SmallVectorImpl<ISD::InputArg> &Ins,
- DebugLoc dl, SelectionDAG &DAG,
+ SDLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals,
const SmallVectorImpl<SDValue> &OutVals,
SDValue Callee) const {
@@ -382,7 +382,7 @@ SDValue
HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
- DebugLoc &dl = CLI.DL;
+ SDLoc &dl = CLI.DL;
SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs;
SmallVector<SDValue, 32> &OutVals = CLI.OutVals;
SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins;
@@ -513,7 +513,8 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
if (!isTailCall)
Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumBytes,
- getPointerTy(), true));
+ getPointerTy(), true),
+ dl);
// Build a sequence of copy-to-reg nodes chained together with token
// chain and flag operands which copy the outgoing args into registers.
@@ -588,7 +589,7 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// Create the CALLSEQ_END node.
Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true),
- DAG.getIntPtrConstant(0, true), InFlag);
+ DAG.getIntPtrConstant(0, true), InFlag, dl);
InFlag = Chain.getValue(1);
// Handle result values, copying them out of physregs into vregs that we
@@ -730,7 +731,7 @@ LowerBR_JT(SDValue Op, SelectionDAG &DAG) const
SDValue Chain = Op.getOperand(0);
SDValue Table = Op.getOperand(1);
SDValue Index = Op.getOperand(2);
- DebugLoc dl = Op.getDebugLoc();
+ SDLoc dl(Op);
JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
unsigned JTI = JT->getIndex();
MachineFunction &MF = DAG.getMachineFunction();
@@ -766,7 +767,7 @@ HexagonTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
SelectionDAG &DAG) const {
SDValue Chain = Op.getOperand(0);
SDValue Size = Op.getOperand(1);
- DebugLoc dl = Op.getDebugLoc();
+ SDLoc dl(Op);
unsigned SPReg = getStackPointerRegisterToSaveRestore();
@@ -812,7 +813,7 @@ HexagonTargetLowering::LowerFormalArguments(SDValue Chain,
bool isVarArg,
const
SmallVectorImpl<ISD::InputArg> &Ins,
- DebugLoc dl, SelectionDAG &DAG,
+ SDLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals)
const {
@@ -925,7 +926,7 @@ HexagonTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
HexagonMachineFunctionInfo *QFI = MF.getInfo<HexagonMachineFunctionInfo>();
SDValue Addr = DAG.getFrameIndex(QFI->getVarArgsFrameIndex(), MVT::i32);
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
- return DAG.getStore(Op.getOperand(0), Op.getDebugLoc(), Addr,
+ return DAG.getStore(Op.getOperand(0), SDLoc(Op), Addr,
Op.getOperand(1), MachinePointerInfo(SV), false,
false, 0);
}
@@ -937,7 +938,7 @@ HexagonTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
SDValue CC = Op.getOperand(4);
SDValue TrueVal = Op.getOperand(2);
SDValue FalseVal = Op.getOperand(3);
- DebugLoc dl = Op.getDebugLoc();
+ SDLoc dl(Op);
SDNode* OpNode = Op.getNode();
EVT SVT = OpNode->getValueType(0);
@@ -948,8 +949,7 @@ HexagonTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
SDValue
HexagonTargetLowering::LowerConstantPool(SDValue Op, SelectionDAG &DAG) const {
EVT ValTy = Op.getValueType();
-
- DebugLoc dl = Op.getDebugLoc();
+ SDLoc dl(Op);
ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
SDValue Res;
if (CP->isMachineConstantPoolEntry())
@@ -969,7 +969,7 @@ HexagonTargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const {
MFI->setReturnAddressIsTaken(true);
EVT VT = Op.getValueType();
- DebugLoc dl = Op.getDebugLoc();
+ SDLoc dl(Op);
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
if (Depth) {
SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
@@ -991,7 +991,7 @@ HexagonTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
MFI->setFrameAddressIsTaken(true);
EVT VT = Op.getValueType();
- DebugLoc dl = Op.getDebugLoc();
+ SDLoc dl(Op);
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
TRI->getFrameRegister(), VT);
@@ -1004,7 +1004,7 @@ HexagonTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
SDValue HexagonTargetLowering::LowerATOMIC_FENCE(SDValue Op,
SelectionDAG& DAG) const {
- DebugLoc dl = Op.getDebugLoc();
+ SDLoc dl(Op);
return DAG.getNode(HexagonISD::BARRIER, dl, MVT::Other, Op.getOperand(0));
}
@@ -1014,7 +1014,7 @@ SDValue HexagonTargetLowering::LowerGLOBALADDRESS(SDValue Op,
SDValue Result;
const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
- DebugLoc dl = Op.getDebugLoc();
+ SDLoc dl(Op);
Result = DAG.getTargetGlobalAddress(GV, dl, getPointerTy(), Offset);
const HexagonTargetObjectFile &TLOF =
@@ -1030,7 +1030,7 @@ SDValue
HexagonTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const {
const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
SDValue BA_SD = DAG.getTargetBlockAddress(BA, MVT::i32);
- DebugLoc dl = Op.getDebugLoc();
+ SDLoc dl(Op);
return DAG.getNode(HexagonISD::CONST32_GP, dl, getPointerTy(), BA_SD);
}
@@ -1361,7 +1361,6 @@ HexagonTargetLowering::HexagonTargetLowering(HexagonTargetMachine
// Increase jump tables cutover to 5, was 4.
setMinimumJumpTableEntries(5);
- setOperationAction(ISD::BR_CC, MVT::Other, Expand);
setOperationAction(ISD::BR_CC, MVT::f32, Expand);
setOperationAction(ISD::BR_CC, MVT::f64, Expand);
setOperationAction(ISD::BR_CC, MVT::i1, Expand);
@@ -1515,7 +1514,7 @@ HexagonTargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const {
SDValue Chain = Op.getOperand(0);
SDValue Offset = Op.getOperand(1);
SDValue Handler = Op.getOperand(2);
- DebugLoc dl = Op.getDebugLoc();
+ SDLoc dl(Op);
// Mark function as containing a call to EH_RETURN.
HexagonMachineFunctionInfo *FuncInfo =
diff --git a/lib/Target/Hexagon/HexagonISelLowering.h b/lib/Target/Hexagon/HexagonISelLowering.h
index bb1acc1..70642e6 100644
--- a/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/lib/Target/Hexagon/HexagonISelLowering.h
@@ -106,7 +106,7 @@ namespace llvm {
SDValue LowerFormalArguments(SDValue Chain,
CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
- DebugLoc dl, SelectionDAG &DAG,
+ SDLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
@@ -117,7 +117,7 @@ namespace llvm {
SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
- DebugLoc dl, SelectionDAG &DAG,
+ SDLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals,
const SmallVectorImpl<SDValue> &OutVals,
SDValue Callee) const;
@@ -131,7 +131,7 @@ namespace llvm {
CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<SDValue> &OutVals,
- DebugLoc dl, SelectionDAG &DAG) const;
+ SDLoc dl, SelectionDAG &DAG) const;
virtual MachineBasicBlock
*EmitInstrWithCustomInserter(MachineInstr *MI,
@@ -139,7 +139,7 @@ namespace llvm {
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
- virtual EVT getSetCCResultType(EVT VT) const {
+ virtual EVT getSetCCResultType(LLVMContext &, EVT) const {
return MVT::i1;
}
diff --git a/lib/Target/Hexagon/HexagonInstrFormats.td b/lib/Target/Hexagon/HexagonInstrFormats.td
index 587fa7d..e71386a 100644
--- a/lib/Target/Hexagon/HexagonInstrFormats.td
+++ b/lib/Target/Hexagon/HexagonInstrFormats.td
@@ -54,6 +54,7 @@ def AbsoluteSet : AddrModeType<2>; // Absolute set addressing mode
def BaseImmOffset : AddrModeType<3>; // Indirect with offset
def BaseLongOffset : AddrModeType<4>; // Indirect with long offset
def BaseRegOffset : AddrModeType<5>; // Indirect with register offset
+def PostInc : AddrModeType<6>; // Post increment addressing mode
class MemAccessSize<bits<3> value> {
bits<3> Value = value;
@@ -157,6 +158,7 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern,
string CextOpcode = "";
string PredSense = "";
string PNewValue = "";
+ string NValueST = ""; // Set to "true" for new-value stores.
string InputType = ""; // Input is "imm" or "reg" type.
string isMEMri = "false"; // Set to "true" for load/store with MEMri operand.
string isFloat = "false"; // Set to "true" for the floating-point load/store.
@@ -165,6 +167,7 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern,
let PredSense = !if(isPredicated, !if(isPredicatedFalse, "false", "true"),
"");
let PNewValue = !if(isPredicatedNew, "new", "");
+ let NValueST = !if(isNVStore, "true", "false");
// *** Must match MCTargetDesc/HexagonBaseInfo.h ***
}
diff --git a/lib/Target/Hexagon/HexagonInstrInfo.cpp b/lib/Target/Hexagon/HexagonInstrInfo.cpp
index e0beab0..3218134 100644
--- a/lib/Target/Hexagon/HexagonInstrInfo.cpp
+++ b/lib/Target/Hexagon/HexagonInstrInfo.cpp
@@ -25,6 +25,7 @@
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
#define GET_INSTRINFO_CTOR
#define GET_INSTRMAP_INFO
#include "HexagonGenInstrInfo.inc"
@@ -57,7 +58,7 @@ const int Hexagon_MEMB_AUTOINC_MIN = -8;
HexagonInstrInfo::HexagonInstrInfo(HexagonSubtarget &ST)
: HexagonGenInstrInfo(Hexagon::ADJCALLSTACKDOWN, Hexagon::ADJCALLSTACKUP),
- RI(ST, *this), Subtarget(ST) {
+ RI(ST), Subtarget(ST) {
}
@@ -625,292 +626,8 @@ bool HexagonInstrInfo::isExtended(const MachineInstr *MI) const {
return false;
}
-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 {
- switch (MI->getOpcode()) {
- default: return false;
- // Store Byte
- case Hexagon::STrib_nv_V4:
- case Hexagon::STrib_indexed_nv_V4:
- case Hexagon::STrib_indexed_shl_nv_V4:
- case Hexagon::STrib_shl_nv_V4:
- case Hexagon::STb_GP_nv_V4:
- case Hexagon::POST_STbri_nv_V4:
- case Hexagon::STrib_cPt_nv_V4:
- case Hexagon::STrib_cdnPt_nv_V4:
- case Hexagon::STrib_cNotPt_nv_V4:
- case Hexagon::STrib_cdnNotPt_nv_V4:
- case Hexagon::STrib_indexed_cPt_nv_V4:
- case Hexagon::STrib_indexed_cdnPt_nv_V4:
- case Hexagon::STrib_indexed_cNotPt_nv_V4:
- case Hexagon::STrib_indexed_cdnNotPt_nv_V4:
- case Hexagon::STrib_indexed_shl_cPt_nv_V4:
- case Hexagon::STrib_indexed_shl_cdnPt_nv_V4:
- case Hexagon::STrib_indexed_shl_cNotPt_nv_V4:
- case Hexagon::STrib_indexed_shl_cdnNotPt_nv_V4:
- case Hexagon::POST_STbri_cPt_nv_V4:
- case Hexagon::POST_STbri_cdnPt_nv_V4:
- case Hexagon::POST_STbri_cNotPt_nv_V4:
- case Hexagon::POST_STbri_cdnNotPt_nv_V4:
- case Hexagon::STb_GP_cPt_nv_V4:
- case Hexagon::STb_GP_cNotPt_nv_V4:
- case Hexagon::STb_GP_cdnPt_nv_V4:
- case Hexagon::STb_GP_cdnNotPt_nv_V4:
- case Hexagon::STrib_abs_nv_V4:
- case Hexagon::STrib_abs_cPt_nv_V4:
- case Hexagon::STrib_abs_cdnPt_nv_V4:
- case Hexagon::STrib_abs_cNotPt_nv_V4:
- case Hexagon::STrib_abs_cdnNotPt_nv_V4:
-
- // Store Halfword
- case Hexagon::STrih_nv_V4:
- case Hexagon::STrih_indexed_nv_V4:
- case Hexagon::STrih_indexed_shl_nv_V4:
- case Hexagon::STrih_shl_nv_V4:
- case Hexagon::STh_GP_nv_V4:
- case Hexagon::POST_SThri_nv_V4:
- case Hexagon::STrih_cPt_nv_V4:
- case Hexagon::STrih_cdnPt_nv_V4:
- case Hexagon::STrih_cNotPt_nv_V4:
- case Hexagon::STrih_cdnNotPt_nv_V4:
- case Hexagon::STrih_indexed_cPt_nv_V4:
- case Hexagon::STrih_indexed_cdnPt_nv_V4:
- case Hexagon::STrih_indexed_cNotPt_nv_V4:
- case Hexagon::STrih_indexed_cdnNotPt_nv_V4:
- case Hexagon::STrih_indexed_shl_cPt_nv_V4:
- case Hexagon::STrih_indexed_shl_cdnPt_nv_V4:
- case Hexagon::STrih_indexed_shl_cNotPt_nv_V4:
- case Hexagon::STrih_indexed_shl_cdnNotPt_nv_V4:
- case Hexagon::POST_SThri_cPt_nv_V4:
- case Hexagon::POST_SThri_cdnPt_nv_V4:
- case Hexagon::POST_SThri_cNotPt_nv_V4:
- case Hexagon::POST_SThri_cdnNotPt_nv_V4:
- case Hexagon::STh_GP_cPt_nv_V4:
- case Hexagon::STh_GP_cNotPt_nv_V4:
- case Hexagon::STh_GP_cdnPt_nv_V4:
- case Hexagon::STh_GP_cdnNotPt_nv_V4:
- case Hexagon::STrih_abs_nv_V4:
- case Hexagon::STrih_abs_cPt_nv_V4:
- case Hexagon::STrih_abs_cdnPt_nv_V4:
- case Hexagon::STrih_abs_cNotPt_nv_V4:
- case Hexagon::STrih_abs_cdnNotPt_nv_V4:
-
- // Store Word
- case Hexagon::STriw_nv_V4:
- case Hexagon::STriw_indexed_nv_V4:
- case Hexagon::STriw_indexed_shl_nv_V4:
- case Hexagon::STriw_shl_nv_V4:
- case Hexagon::STw_GP_nv_V4:
- case Hexagon::POST_STwri_nv_V4:
- case Hexagon::STriw_cPt_nv_V4:
- case Hexagon::STriw_cdnPt_nv_V4:
- case Hexagon::STriw_cNotPt_nv_V4:
- case Hexagon::STriw_cdnNotPt_nv_V4:
- case Hexagon::STriw_indexed_cPt_nv_V4:
- case Hexagon::STriw_indexed_cdnPt_nv_V4:
- case Hexagon::STriw_indexed_cNotPt_nv_V4:
- case Hexagon::STriw_indexed_cdnNotPt_nv_V4:
- case Hexagon::STriw_indexed_shl_cPt_nv_V4:
- case Hexagon::STriw_indexed_shl_cdnPt_nv_V4:
- case Hexagon::STriw_indexed_shl_cNotPt_nv_V4:
- case Hexagon::STriw_indexed_shl_cdnNotPt_nv_V4:
- case Hexagon::POST_STwri_cPt_nv_V4:
- case Hexagon::POST_STwri_cdnPt_nv_V4:
- case Hexagon::POST_STwri_cNotPt_nv_V4:
- case Hexagon::POST_STwri_cdnNotPt_nv_V4:
- case Hexagon::STw_GP_cPt_nv_V4:
- case Hexagon::STw_GP_cNotPt_nv_V4:
- case Hexagon::STw_GP_cdnPt_nv_V4:
- case Hexagon::STw_GP_cdnNotPt_nv_V4:
- case Hexagon::STriw_abs_nv_V4:
- case Hexagon::STriw_abs_cPt_nv_V4:
- case Hexagon::STriw_abs_cdnPt_nv_V4:
- case Hexagon::STriw_abs_cNotPt_nv_V4:
- case Hexagon::STriw_abs_cdnNotPt_nv_V4:
- return true;
- }
-}
-
-bool HexagonInstrInfo::isPostIncrement (const MachineInstr* MI) const {
- switch (MI->getOpcode())
- {
- default: return false;
- // Load Byte
- case Hexagon::POST_LDrib:
- case Hexagon::POST_LDrib_cPt:
- case Hexagon::POST_LDrib_cNotPt:
- case Hexagon::POST_LDrib_cdnPt_V4:
- case Hexagon::POST_LDrib_cdnNotPt_V4:
-
- // Load unsigned byte
- case Hexagon::POST_LDriub:
- case Hexagon::POST_LDriub_cPt:
- case Hexagon::POST_LDriub_cNotPt:
- case Hexagon::POST_LDriub_cdnPt_V4:
- case Hexagon::POST_LDriub_cdnNotPt_V4:
-
- // Load halfword
- case Hexagon::POST_LDrih:
- case Hexagon::POST_LDrih_cPt:
- case Hexagon::POST_LDrih_cNotPt:
- case Hexagon::POST_LDrih_cdnPt_V4:
- case Hexagon::POST_LDrih_cdnNotPt_V4:
-
- // Load unsigned halfword
- case Hexagon::POST_LDriuh:
- case Hexagon::POST_LDriuh_cPt:
- case Hexagon::POST_LDriuh_cNotPt:
- case Hexagon::POST_LDriuh_cdnPt_V4:
- case Hexagon::POST_LDriuh_cdnNotPt_V4:
-
- // Load word
- case Hexagon::POST_LDriw:
- case Hexagon::POST_LDriw_cPt:
- case Hexagon::POST_LDriw_cNotPt:
- case Hexagon::POST_LDriw_cdnPt_V4:
- case Hexagon::POST_LDriw_cdnNotPt_V4:
-
- // Load double word
- case Hexagon::POST_LDrid:
- case Hexagon::POST_LDrid_cPt:
- case Hexagon::POST_LDrid_cNotPt:
- case Hexagon::POST_LDrid_cdnPt_V4:
- case Hexagon::POST_LDrid_cdnNotPt_V4:
-
- // Store byte
- case Hexagon::POST_STbri:
- case Hexagon::POST_STbri_cPt:
- case Hexagon::POST_STbri_cNotPt:
- case Hexagon::POST_STbri_cdnPt_V4:
- case Hexagon::POST_STbri_cdnNotPt_V4:
-
- // Store halfword
- case Hexagon::POST_SThri:
- case Hexagon::POST_SThri_cPt:
- case Hexagon::POST_SThri_cNotPt:
- case Hexagon::POST_SThri_cdnPt_V4:
- case Hexagon::POST_SThri_cdnNotPt_V4:
-
- // Store word
- case Hexagon::POST_STwri:
- case Hexagon::POST_STwri_cPt:
- case Hexagon::POST_STwri_cNotPt:
- case Hexagon::POST_STwri_cdnPt_V4:
- case Hexagon::POST_STwri_cdnNotPt_V4:
-
- // Store double word
- case Hexagon::POST_STdri:
- case Hexagon::POST_STdri_cPt:
- case Hexagon::POST_STdri_cNotPt:
- case Hexagon::POST_STdri_cdnPt_V4:
- case Hexagon::POST_STdri_cdnNotPt_V4:
- return true;
- }
+bool HexagonInstrInfo::isBranch (const MachineInstr *MI) const {
+ return MI->getDesc().isBranch();
}
bool HexagonInstrInfo::isNewValueInst(const MachineInstr *MI) const {
@@ -1018,466 +735,40 @@ bool HexagonInstrInfo::isPredicable(MachineInstr *MI) const {
// cPt ---> cNotPt
// cNotPt ---> cPt
//
-// however, these inversiones are NOT included:
-//
-// cdnPt -X-> cdnNotPt
-// cdnNotPt -X-> cdnPt
-// cPt_nv -X-> cNotPt_nv (new value stores)
-// cNotPt_nv -X-> cPt_nv (new value stores)
-//
-// because only the following transformations are allowed:
-//
-// cNotPt ---> cdnNotPt
-// cPt ---> cdnPt
-// 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:
- return Hexagon::TFR_cNotPt;
- case Hexagon::TFR_cNotPt:
- return Hexagon::TFR_cPt;
-
- case Hexagon::TFRI_cPt:
- return Hexagon::TFRI_cNotPt;
- case Hexagon::TFRI_cNotPt:
- return Hexagon::TFRI_cPt;
-
- case Hexagon::JMP_t:
- return Hexagon::JMP_f;
- case Hexagon::JMP_f:
- return Hexagon::JMP_t;
-
- case Hexagon::ADD_ri_cPt:
- return Hexagon::ADD_ri_cNotPt;
- case Hexagon::ADD_ri_cNotPt:
- return Hexagon::ADD_ri_cPt;
-
- case Hexagon::ADD_rr_cPt:
- return Hexagon::ADD_rr_cNotPt;
- case Hexagon::ADD_rr_cNotPt:
- return Hexagon::ADD_rr_cPt;
-
- case Hexagon::XOR_rr_cPt:
- return Hexagon::XOR_rr_cNotPt;
- case Hexagon::XOR_rr_cNotPt:
- return Hexagon::XOR_rr_cPt;
-
- case Hexagon::AND_rr_cPt:
- return Hexagon::AND_rr_cNotPt;
- case Hexagon::AND_rr_cNotPt:
- return Hexagon::AND_rr_cPt;
-
- case Hexagon::OR_rr_cPt:
- return Hexagon::OR_rr_cNotPt;
- case Hexagon::OR_rr_cNotPt:
- return Hexagon::OR_rr_cPt;
-
- case Hexagon::SUB_rr_cPt:
- return Hexagon::SUB_rr_cNotPt;
- case Hexagon::SUB_rr_cNotPt:
- return Hexagon::SUB_rr_cPt;
-
case Hexagon::COMBINE_rr_cPt:
return Hexagon::COMBINE_rr_cNotPt;
case Hexagon::COMBINE_rr_cNotPt:
return Hexagon::COMBINE_rr_cPt;
- case Hexagon::ASLH_cPt_V4:
- return Hexagon::ASLH_cNotPt_V4;
- case Hexagon::ASLH_cNotPt_V4:
- return Hexagon::ASLH_cPt_V4;
-
- case Hexagon::ASRH_cPt_V4:
- return Hexagon::ASRH_cNotPt_V4;
- case Hexagon::ASRH_cNotPt_V4:
- return Hexagon::ASRH_cPt_V4;
-
- case Hexagon::SXTB_cPt_V4:
- return Hexagon::SXTB_cNotPt_V4;
- case Hexagon::SXTB_cNotPt_V4:
- return Hexagon::SXTB_cPt_V4;
-
- case Hexagon::SXTH_cPt_V4:
- return Hexagon::SXTH_cNotPt_V4;
- case Hexagon::SXTH_cNotPt_V4:
- return Hexagon::SXTH_cPt_V4;
-
- case Hexagon::ZXTB_cPt_V4:
- return Hexagon::ZXTB_cNotPt_V4;
- case Hexagon::ZXTB_cNotPt_V4:
- return Hexagon::ZXTB_cPt_V4;
-
- case Hexagon::ZXTH_cPt_V4:
- return Hexagon::ZXTH_cNotPt_V4;
- case Hexagon::ZXTH_cNotPt_V4:
- return Hexagon::ZXTH_cPt_V4;
-
-
- case Hexagon::JMPR_t:
- return Hexagon::JMPR_f;
- case Hexagon::JMPR_f:
- return Hexagon::JMPR_t;
-
- // V4 indexed+scaled load.
- case Hexagon::LDrid_indexed_shl_cPt_V4:
- return Hexagon::LDrid_indexed_shl_cNotPt_V4;
- case Hexagon::LDrid_indexed_shl_cNotPt_V4:
- return Hexagon::LDrid_indexed_shl_cPt_V4;
-
- case Hexagon::LDrib_indexed_shl_cPt_V4:
- return Hexagon::LDrib_indexed_shl_cNotPt_V4;
- case Hexagon::LDrib_indexed_shl_cNotPt_V4:
- return Hexagon::LDrib_indexed_shl_cPt_V4;
-
- case Hexagon::LDriub_indexed_shl_cPt_V4:
- return Hexagon::LDriub_indexed_shl_cNotPt_V4;
- case Hexagon::LDriub_indexed_shl_cNotPt_V4:
- return Hexagon::LDriub_indexed_shl_cPt_V4;
-
- case Hexagon::LDrih_indexed_shl_cPt_V4:
- return Hexagon::LDrih_indexed_shl_cNotPt_V4;
- case Hexagon::LDrih_indexed_shl_cNotPt_V4:
- return Hexagon::LDrih_indexed_shl_cPt_V4;
-
- case Hexagon::LDriuh_indexed_shl_cPt_V4:
- return Hexagon::LDriuh_indexed_shl_cNotPt_V4;
- case Hexagon::LDriuh_indexed_shl_cNotPt_V4:
- return Hexagon::LDriuh_indexed_shl_cPt_V4;
-
- case Hexagon::LDriw_indexed_shl_cPt_V4:
- return Hexagon::LDriw_indexed_shl_cNotPt_V4;
- case Hexagon::LDriw_indexed_shl_cNotPt_V4:
- return Hexagon::LDriw_indexed_shl_cPt_V4;
-
- // Byte.
- case Hexagon::POST_STbri_cPt:
- return Hexagon::POST_STbri_cNotPt;
- case Hexagon::POST_STbri_cNotPt:
- return Hexagon::POST_STbri_cPt;
-
- case Hexagon::STrib_cPt:
- return Hexagon::STrib_cNotPt;
- case Hexagon::STrib_cNotPt:
- return Hexagon::STrib_cPt;
-
- case Hexagon::STrib_indexed_cPt:
- return Hexagon::STrib_indexed_cNotPt;
- case Hexagon::STrib_indexed_cNotPt:
- return Hexagon::STrib_indexed_cPt;
-
- case Hexagon::STrib_imm_cPt_V4:
- return Hexagon::STrib_imm_cNotPt_V4;
- case Hexagon::STrib_imm_cNotPt_V4:
- return Hexagon::STrib_imm_cPt_V4;
-
- case Hexagon::STrib_indexed_shl_cPt_V4:
- return Hexagon::STrib_indexed_shl_cNotPt_V4;
- case Hexagon::STrib_indexed_shl_cNotPt_V4:
- return Hexagon::STrib_indexed_shl_cPt_V4;
-
- // Halfword.
- case Hexagon::POST_SThri_cPt:
- return Hexagon::POST_SThri_cNotPt;
- case Hexagon::POST_SThri_cNotPt:
- return Hexagon::POST_SThri_cPt;
-
- case Hexagon::STrih_cPt:
- return Hexagon::STrih_cNotPt;
- case Hexagon::STrih_cNotPt:
- return Hexagon::STrih_cPt;
-
- case Hexagon::STrih_indexed_cPt:
- return Hexagon::STrih_indexed_cNotPt;
- case Hexagon::STrih_indexed_cNotPt:
- return Hexagon::STrih_indexed_cPt;
-
- case Hexagon::STrih_imm_cPt_V4:
- return Hexagon::STrih_imm_cNotPt_V4;
- case Hexagon::STrih_imm_cNotPt_V4:
- return Hexagon::STrih_imm_cPt_V4;
-
- case Hexagon::STrih_indexed_shl_cPt_V4:
- return Hexagon::STrih_indexed_shl_cNotPt_V4;
- case Hexagon::STrih_indexed_shl_cNotPt_V4:
- return Hexagon::STrih_indexed_shl_cPt_V4;
-
- // Word.
- case Hexagon::POST_STwri_cPt:
- return Hexagon::POST_STwri_cNotPt;
- case Hexagon::POST_STwri_cNotPt:
- return Hexagon::POST_STwri_cPt;
-
- case Hexagon::STriw_cPt:
- return Hexagon::STriw_cNotPt;
- case Hexagon::STriw_cNotPt:
- return Hexagon::STriw_cPt;
-
- case Hexagon::STriw_indexed_cPt:
- return Hexagon::STriw_indexed_cNotPt;
- case Hexagon::STriw_indexed_cNotPt:
- return Hexagon::STriw_indexed_cPt;
-
- case Hexagon::STriw_indexed_shl_cPt_V4:
- return Hexagon::STriw_indexed_shl_cNotPt_V4;
- case Hexagon::STriw_indexed_shl_cNotPt_V4:
- return Hexagon::STriw_indexed_shl_cPt_V4;
-
- case Hexagon::STriw_imm_cPt_V4:
- return Hexagon::STriw_imm_cNotPt_V4;
- case Hexagon::STriw_imm_cNotPt_V4:
- return Hexagon::STriw_imm_cPt_V4;
-
- // Double word.
- case Hexagon::POST_STdri_cPt:
- return Hexagon::POST_STdri_cNotPt;
- case Hexagon::POST_STdri_cNotPt:
- return Hexagon::POST_STdri_cPt;
-
- case Hexagon::STrid_cPt:
- return Hexagon::STrid_cNotPt;
- case Hexagon::STrid_cNotPt:
- return Hexagon::STrid_cPt;
-
- case Hexagon::STrid_indexed_cPt:
- return Hexagon::STrid_indexed_cNotPt;
- case Hexagon::STrid_indexed_cNotPt:
- return Hexagon::STrid_indexed_cPt;
-
- case Hexagon::STrid_indexed_shl_cPt_V4:
- return Hexagon::STrid_indexed_shl_cNotPt_V4;
- case Hexagon::STrid_indexed_shl_cNotPt_V4:
- return Hexagon::STrid_indexed_shl_cPt_V4;
-
- // V4 Store to global address.
- case Hexagon::STd_GP_cPt_V4:
- return Hexagon::STd_GP_cNotPt_V4;
- case Hexagon::STd_GP_cNotPt_V4:
- return Hexagon::STd_GP_cPt_V4;
-
- case Hexagon::STb_GP_cPt_V4:
- return Hexagon::STb_GP_cNotPt_V4;
- case Hexagon::STb_GP_cNotPt_V4:
- return Hexagon::STb_GP_cPt_V4;
-
- case Hexagon::STh_GP_cPt_V4:
- return Hexagon::STh_GP_cNotPt_V4;
- case Hexagon::STh_GP_cNotPt_V4:
- return Hexagon::STh_GP_cPt_V4;
-
- case Hexagon::STw_GP_cPt_V4:
- return Hexagon::STw_GP_cNotPt_V4;
- case Hexagon::STw_GP_cNotPt_V4:
- return Hexagon::STw_GP_cPt_V4;
-
- // Load.
- case Hexagon::LDrid_cPt:
- return Hexagon::LDrid_cNotPt;
- case Hexagon::LDrid_cNotPt:
- return Hexagon::LDrid_cPt;
-
- case Hexagon::LDriw_cPt:
- return Hexagon::LDriw_cNotPt;
- case Hexagon::LDriw_cNotPt:
- return Hexagon::LDriw_cPt;
-
- case Hexagon::LDrih_cPt:
- return Hexagon::LDrih_cNotPt;
- case Hexagon::LDrih_cNotPt:
- return Hexagon::LDrih_cPt;
-
- case Hexagon::LDriuh_cPt:
- return Hexagon::LDriuh_cNotPt;
- case Hexagon::LDriuh_cNotPt:
- return Hexagon::LDriuh_cPt;
-
- case Hexagon::LDrib_cPt:
- return Hexagon::LDrib_cNotPt;
- case Hexagon::LDrib_cNotPt:
- return Hexagon::LDrib_cPt;
-
- case Hexagon::LDriub_cPt:
- return Hexagon::LDriub_cNotPt;
- case Hexagon::LDriub_cNotPt:
- return Hexagon::LDriub_cPt;
-
- // Load Indexed.
- case Hexagon::LDrid_indexed_cPt:
- return Hexagon::LDrid_indexed_cNotPt;
- case Hexagon::LDrid_indexed_cNotPt:
- return Hexagon::LDrid_indexed_cPt;
-
- case Hexagon::LDriw_indexed_cPt:
- return Hexagon::LDriw_indexed_cNotPt;
- case Hexagon::LDriw_indexed_cNotPt:
- return Hexagon::LDriw_indexed_cPt;
-
- case Hexagon::LDrih_indexed_cPt:
- return Hexagon::LDrih_indexed_cNotPt;
- case Hexagon::LDrih_indexed_cNotPt:
- return Hexagon::LDrih_indexed_cPt;
-
- case Hexagon::LDriuh_indexed_cPt:
- return Hexagon::LDriuh_indexed_cNotPt;
- case Hexagon::LDriuh_indexed_cNotPt:
- return Hexagon::LDriuh_indexed_cPt;
-
- case Hexagon::LDrib_indexed_cPt:
- return Hexagon::LDrib_indexed_cNotPt;
- case Hexagon::LDrib_indexed_cNotPt:
- return Hexagon::LDrib_indexed_cPt;
-
- case Hexagon::LDriub_indexed_cPt:
- return Hexagon::LDriub_indexed_cNotPt;
- case Hexagon::LDriub_indexed_cNotPt:
- return Hexagon::LDriub_indexed_cPt;
-
- // Post Inc Load.
- case Hexagon::POST_LDrid_cPt:
- return Hexagon::POST_LDrid_cNotPt;
- case Hexagon::POST_LDriw_cNotPt:
- return Hexagon::POST_LDriw_cPt;
-
- case Hexagon::POST_LDrih_cPt:
- return Hexagon::POST_LDrih_cNotPt;
- case Hexagon::POST_LDrih_cNotPt:
- return Hexagon::POST_LDrih_cPt;
-
- case Hexagon::POST_LDriuh_cPt:
- return Hexagon::POST_LDriuh_cNotPt;
- case Hexagon::POST_LDriuh_cNotPt:
- return Hexagon::POST_LDriuh_cPt;
-
- case Hexagon::POST_LDrib_cPt:
- return Hexagon::POST_LDrib_cNotPt;
- case Hexagon::POST_LDrib_cNotPt:
- return Hexagon::POST_LDrib_cPt;
-
- case Hexagon::POST_LDriub_cPt:
- return Hexagon::POST_LDriub_cNotPt;
- case Hexagon::POST_LDriub_cNotPt:
- return Hexagon::POST_LDriub_cPt;
-
- // Dealloc_return.
+ // Dealloc_return.
case Hexagon::DEALLOC_RET_cPt_V4:
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;
}
}
+// New Value Store instructions.
+bool HexagonInstrInfo::isNewValueStore(const MachineInstr *MI) const {
+ const uint64_t F = MI->getDesc().TSFlags;
+
+ return ((F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask);
+}
+
+bool HexagonInstrInfo::isNewValueStore(unsigned Opcode) const {
+ const uint64_t F = get(Opcode).TSFlags;
+
+ return ((F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask);
+}
int HexagonInstrInfo::
getMatchingCondBranchOpcode(int Opc, bool invertPredicate) const {
@@ -1491,223 +782,21 @@ getMatchingCondBranchOpcode(int Opc, bool invertPredicate) const {
// This switch case will be removed once all the instructions have been
// modified to use relation maps.
switch(Opc) {
- case Hexagon::TFR:
- return !invertPredicate ? Hexagon::TFR_cPt :
- Hexagon::TFR_cNotPt;
case Hexagon::TFRI_f:
return !invertPredicate ? Hexagon::TFRI_cPt_f :
Hexagon::TFRI_cNotPt_f;
- case Hexagon::TFRI:
- return !invertPredicate ? Hexagon::TFRI_cPt :
- Hexagon::TFRI_cNotPt;
- 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;
- case Hexagon::ASLH:
- return !invertPredicate ? Hexagon::ASLH_cPt_V4 :
- Hexagon::ASLH_cNotPt_V4;
- case Hexagon::ASRH:
- return !invertPredicate ? Hexagon::ASRH_cPt_V4 :
- Hexagon::ASRH_cNotPt_V4;
- case Hexagon::SXTB:
- return !invertPredicate ? Hexagon::SXTB_cPt_V4 :
- Hexagon::SXTB_cNotPt_V4;
- case Hexagon::SXTH:
- return !invertPredicate ? Hexagon::SXTH_cPt_V4 :
- Hexagon::SXTH_cNotPt_V4;
- case Hexagon::ZXTB:
- return !invertPredicate ? Hexagon::ZXTB_cPt_V4 :
- Hexagon::ZXTB_cNotPt_V4;
- case Hexagon::ZXTH:
- return !invertPredicate ? Hexagon::ZXTH_cPt_V4 :
- Hexagon::ZXTH_cNotPt_V4;
-
- case Hexagon::JMPR:
- return !invertPredicate ? Hexagon::JMPR_t :
- Hexagon::JMPR_f;
-
- // V4 indexed+scaled load.
- case Hexagon::LDrid_indexed_shl_V4:
- return !invertPredicate ? Hexagon::LDrid_indexed_shl_cPt_V4 :
- Hexagon::LDrid_indexed_shl_cNotPt_V4;
- case Hexagon::LDrib_indexed_shl_V4:
- return !invertPredicate ? Hexagon::LDrib_indexed_shl_cPt_V4 :
- Hexagon::LDrib_indexed_shl_cNotPt_V4;
- case Hexagon::LDriub_indexed_shl_V4:
- return !invertPredicate ? Hexagon::LDriub_indexed_shl_cPt_V4 :
- Hexagon::LDriub_indexed_shl_cNotPt_V4;
- case Hexagon::LDrih_indexed_shl_V4:
- return !invertPredicate ? Hexagon::LDrih_indexed_shl_cPt_V4 :
- Hexagon::LDrih_indexed_shl_cNotPt_V4;
- case Hexagon::LDriuh_indexed_shl_V4:
- return !invertPredicate ? Hexagon::LDriuh_indexed_shl_cPt_V4 :
- Hexagon::LDriuh_indexed_shl_cNotPt_V4;
- case Hexagon::LDriw_indexed_shl_V4:
- return !invertPredicate ? Hexagon::LDriw_indexed_shl_cPt_V4 :
- Hexagon::LDriw_indexed_shl_cNotPt_V4;
-
- // V4 Load from global address
- case Hexagon::LDd_GP_V4:
- return !invertPredicate ? Hexagon::LDd_GP_cPt_V4 :
- Hexagon::LDd_GP_cNotPt_V4;
- case Hexagon::LDb_GP_V4:
- return !invertPredicate ? Hexagon::LDb_GP_cPt_V4 :
- Hexagon::LDb_GP_cNotPt_V4;
- case Hexagon::LDub_GP_V4:
- return !invertPredicate ? Hexagon::LDub_GP_cPt_V4 :
- Hexagon::LDub_GP_cNotPt_V4;
- case Hexagon::LDh_GP_V4:
- return !invertPredicate ? Hexagon::LDh_GP_cPt_V4 :
- Hexagon::LDh_GP_cNotPt_V4;
- case Hexagon::LDuh_GP_V4:
- return !invertPredicate ? Hexagon::LDuh_GP_cPt_V4 :
- Hexagon::LDuh_GP_cNotPt_V4;
- case Hexagon::LDw_GP_V4:
- return !invertPredicate ? Hexagon::LDw_GP_cPt_V4 :
- Hexagon::LDw_GP_cNotPt_V4;
-
- // Byte.
- case Hexagon::POST_STbri:
- return !invertPredicate ? Hexagon::POST_STbri_cPt :
- Hexagon::POST_STbri_cNotPt;
- case Hexagon::STrib:
- return !invertPredicate ? Hexagon::STrib_cPt :
- Hexagon::STrib_cNotPt;
- case Hexagon::STrib_indexed:
- return !invertPredicate ? Hexagon::STrib_indexed_cPt :
- Hexagon::STrib_indexed_cNotPt;
- case Hexagon::STrib_imm_V4:
- return !invertPredicate ? Hexagon::STrib_imm_cPt_V4 :
- Hexagon::STrib_imm_cNotPt_V4;
- case Hexagon::STrib_indexed_shl_V4:
- return !invertPredicate ? Hexagon::STrib_indexed_shl_cPt_V4 :
- Hexagon::STrib_indexed_shl_cNotPt_V4;
- // Halfword.
- case Hexagon::POST_SThri:
- return !invertPredicate ? Hexagon::POST_SThri_cPt :
- Hexagon::POST_SThri_cNotPt;
- case Hexagon::STrih:
- return !invertPredicate ? Hexagon::STrih_cPt :
- Hexagon::STrih_cNotPt;
- case Hexagon::STrih_indexed:
- return !invertPredicate ? Hexagon::STrih_indexed_cPt :
- Hexagon::STrih_indexed_cNotPt;
- case Hexagon::STrih_imm_V4:
- return !invertPredicate ? Hexagon::STrih_imm_cPt_V4 :
- Hexagon::STrih_imm_cNotPt_V4;
- case Hexagon::STrih_indexed_shl_V4:
- return !invertPredicate ? Hexagon::STrih_indexed_shl_cPt_V4 :
- Hexagon::STrih_indexed_shl_cNotPt_V4;
+
// Word.
- case Hexagon::POST_STwri:
- return !invertPredicate ? Hexagon::POST_STwri_cPt :
- Hexagon::POST_STwri_cNotPt;
- case Hexagon::STriw:
+ case Hexagon::STriw_f:
return !invertPredicate ? Hexagon::STriw_cPt :
Hexagon::STriw_cNotPt;
- case Hexagon::STriw_indexed:
+ case Hexagon::STriw_indexed_f:
return !invertPredicate ? Hexagon::STriw_indexed_cPt :
Hexagon::STriw_indexed_cNotPt;
- case Hexagon::STriw_indexed_shl_V4:
- return !invertPredicate ? Hexagon::STriw_indexed_shl_cPt_V4 :
- Hexagon::STriw_indexed_shl_cNotPt_V4;
- case Hexagon::STriw_imm_V4:
- return !invertPredicate ? Hexagon::STriw_imm_cPt_V4 :
- Hexagon::STriw_imm_cNotPt_V4;
- // Double word.
- case Hexagon::POST_STdri:
- return !invertPredicate ? Hexagon::POST_STdri_cPt :
- Hexagon::POST_STdri_cNotPt;
- case Hexagon::STrid:
- return !invertPredicate ? Hexagon::STrid_cPt :
- Hexagon::STrid_cNotPt;
- case Hexagon::STrid_indexed:
- return !invertPredicate ? Hexagon::STrid_indexed_cPt :
- Hexagon::STrid_indexed_cNotPt;
- case Hexagon::STrid_indexed_shl_V4:
- return !invertPredicate ? Hexagon::STrid_indexed_shl_cPt_V4 :
- Hexagon::STrid_indexed_shl_cNotPt_V4;
-
- // V4 Store to global address
- case Hexagon::STd_GP_V4:
- return !invertPredicate ? Hexagon::STd_GP_cPt_V4 :
- Hexagon::STd_GP_cNotPt_V4;
- case Hexagon::STb_GP_V4:
- return !invertPredicate ? Hexagon::STb_GP_cPt_V4 :
- Hexagon::STb_GP_cNotPt_V4;
- case Hexagon::STh_GP_V4:
- return !invertPredicate ? Hexagon::STh_GP_cPt_V4 :
- Hexagon::STh_GP_cNotPt_V4;
- case Hexagon::STw_GP_V4:
- return !invertPredicate ? Hexagon::STw_GP_cPt_V4 :
- Hexagon::STw_GP_cNotPt_V4;
-
- // Load.
- case Hexagon::LDrid:
- return !invertPredicate ? Hexagon::LDrid_cPt :
- Hexagon::LDrid_cNotPt;
- case Hexagon::LDriw:
- return !invertPredicate ? Hexagon::LDriw_cPt :
- Hexagon::LDriw_cNotPt;
- case Hexagon::LDrih:
- return !invertPredicate ? Hexagon::LDrih_cPt :
- Hexagon::LDrih_cNotPt;
- case Hexagon::LDriuh:
- return !invertPredicate ? Hexagon::LDriuh_cPt :
- Hexagon::LDriuh_cNotPt;
- case Hexagon::LDrib:
- return !invertPredicate ? Hexagon::LDrib_cPt :
- Hexagon::LDrib_cNotPt;
- case Hexagon::LDriub:
- return !invertPredicate ? Hexagon::LDriub_cPt :
- Hexagon::LDriub_cNotPt;
- // Load Indexed.
- case Hexagon::LDrid_indexed:
- return !invertPredicate ? Hexagon::LDrid_indexed_cPt :
- Hexagon::LDrid_indexed_cNotPt;
- case Hexagon::LDriw_indexed:
- return !invertPredicate ? Hexagon::LDriw_indexed_cPt :
- Hexagon::LDriw_indexed_cNotPt;
- case Hexagon::LDrih_indexed:
- return !invertPredicate ? Hexagon::LDrih_indexed_cPt :
- Hexagon::LDrih_indexed_cNotPt;
- case Hexagon::LDriuh_indexed:
- return !invertPredicate ? Hexagon::LDriuh_indexed_cPt :
- Hexagon::LDriuh_indexed_cNotPt;
- case Hexagon::LDrib_indexed:
- return !invertPredicate ? Hexagon::LDrib_indexed_cPt :
- Hexagon::LDrib_indexed_cNotPt;
- case Hexagon::LDriub_indexed:
- return !invertPredicate ? Hexagon::LDriub_indexed_cPt :
- Hexagon::LDriub_indexed_cNotPt;
- // Post Increment Load.
- case Hexagon::POST_LDrid:
- return !invertPredicate ? Hexagon::POST_LDrid_cPt :
- Hexagon::POST_LDrid_cNotPt;
- case Hexagon::POST_LDriw:
- return !invertPredicate ? Hexagon::POST_LDriw_cPt :
- Hexagon::POST_LDriw_cNotPt;
- case Hexagon::POST_LDrih:
- return !invertPredicate ? Hexagon::POST_LDrih_cPt :
- Hexagon::POST_LDrih_cNotPt;
- case Hexagon::POST_LDriuh:
- return !invertPredicate ? Hexagon::POST_LDriuh_cPt :
- Hexagon::POST_LDriuh_cNotPt;
- case Hexagon::POST_LDrib:
- return !invertPredicate ? Hexagon::POST_LDrib_cPt :
- Hexagon::POST_LDrib_cNotPt;
- case Hexagon::POST_LDriub:
- return !invertPredicate ? Hexagon::POST_LDriub_cPt :
- Hexagon::POST_LDriub_cNotPt;
+
// DEALLOC_RETURN.
case Hexagon::DEALLOC_RET_V4:
return !invertPredicate ? Hexagon::DEALLOC_RET_cPt_V4 :
@@ -1889,13 +978,41 @@ 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;
@@ -1903,6 +1020,23 @@ 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);
+}
+
+// Returns true, if a ST insn can be promoted to a new-value store.
+bool HexagonInstrInfo::mayBeNewStore(const MachineInstr *MI) const {
+ const HexagonRegisterInfo& QRI = getRegisterInfo();
+ const uint64_t F = MI->getDesc().TSFlags;
+
+ return ((F >> HexagonII::mayNVStorePos) &
+ HexagonII::mayNVStoreMask &
+ QRI.Subtarget.hasV4TOps());
+}
+
bool
HexagonInstrInfo::DefinesPredicate(MachineInstr *MI,
std::vector<MachineOperand> &Pred) const {
@@ -2087,6 +1221,8 @@ isValidAutoIncImm(const EVT VT, const int Offset) const {
bool HexagonInstrInfo::
isMemOp(const MachineInstr *MI) const {
+// return MI->getDesc().mayLoad() && MI->getDesc().mayStore();
+
switch (MI->getOpcode())
{
default: return false;
@@ -2371,6 +1507,22 @@ isConditionalStore (const MachineInstr* MI) const {
}
}
+
+bool HexagonInstrInfo::isNewValueJump(const MachineInstr *MI) const {
+ if (isNewValue(MI) && isBranch(MI))
+ return true;
+ return false;
+}
+
+bool HexagonInstrInfo::isPostIncrement (const MachineInstr* MI) const {
+ return (getAddrMode(MI) == HexagonII::PostInc);
+}
+
+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 {
@@ -2378,6 +1530,97 @@ bool HexagonInstrInfo::isDotNewInst (const MachineInstr* MI) const {
(isPredicated(MI) && isPredicatedNew(MI)));
}
+// Returns the most basic instruction for the .new predicated instructions and
+// new-value stores.
+// For example, all of the following instructions will be converted back to the
+// same instruction:
+// 1) if (p0.new) memw(R0+#0) = R1.new --->
+// 2) if (p0) memw(R0+#0)= R1.new -------> if (p0) memw(R0+#0) = R1
+// 3) if (p0.new) memw(R0+#0) = R1 --->
+//
+
+int HexagonInstrInfo::GetDotOldOp(const int opc) const {
+ int NewOp = opc;
+ if (isPredicated(NewOp) && isPredicatedNew(NewOp)) { // Get predicate old form
+ NewOp = Hexagon::getPredOldOpcode(NewOp);
+ if (NewOp < 0)
+ assert(0 && "Couldn't change predicate new instruction to its old form.");
+ }
+
+ if (isNewValueStore(NewOp)) { // Convert into non new-value format
+ NewOp = Hexagon::getNonNVStore(NewOp);
+ if (NewOp < 0)
+ assert(0 && "Couldn't change new-value store to its old form.");
+ }
+ return NewOp;
+}
+
+// Return the new value instruction for a given store.
+int HexagonInstrInfo::GetDotNewOp(const MachineInstr* MI) const {
+ int NVOpcode = Hexagon::getNewValueOpcode(MI->getOpcode());
+ if (NVOpcode >= 0) // Valid new-value store instruction.
+ return NVOpcode;
+
+ switch (MI->getOpcode()) {
+ default: llvm_unreachable("Unknown .new type");
+ // store new value byte
+ case Hexagon::STrib_shl_V4:
+ return Hexagon::STrib_shl_nv_V4;
+
+ case Hexagon::STrih_shl_V4:
+ return Hexagon::STrih_shl_nv_V4;
+
+ case Hexagon::STriw_f:
+ return Hexagon::STriw_nv_V4;
+
+ case Hexagon::STriw_indexed_f:
+ return Hexagon::STriw_indexed_nv_V4;
+
+ case Hexagon::STriw_shl_V4:
+ return Hexagon::STriw_shl_nv_V4;
+
+ }
+ return 0;
+}
+
+// Return .new predicate version for an instruction.
+int HexagonInstrInfo::GetDotNewPredOp(MachineInstr *MI,
+ const MachineBranchProbabilityInfo
+ *MBPI) const {
+
+ int NewOpcode = Hexagon::getPredNewOpcode(MI->getOpcode());
+ if (NewOpcode >= 0) // Valid predicate new instruction
+ return NewOpcode;
+
+ switch (MI->getOpcode()) {
+ default: llvm_unreachable("Unknown .new type");
+ // Condtional Jumps
+ case Hexagon::JMP_t:
+ case Hexagon::JMP_f:
+ return getDotNewPredJumpOp(MI, MBPI);
+
+ case Hexagon::JMPR_t:
+ return Hexagon::JMPR_tnew_tV3;
+
+ case Hexagon::JMPR_f:
+ return Hexagon::JMPR_fnew_tV3;
+
+ case Hexagon::JMPret_t:
+ return Hexagon::JMPret_tnew_tV3;
+
+ case Hexagon::JMPret_f:
+ return Hexagon::JMPret_fnew_tV3;
+
+
+ // Conditional combine
+ case Hexagon::COMBINE_rr_cPt :
+ return Hexagon::COMBINE_rr_cdnPt;
+ case Hexagon::COMBINE_rr_cNotPt :
+ return Hexagon::COMBINE_rr_cdnNotPt;
+ }
+}
+
+
unsigned HexagonInstrInfo::getAddrMode(const MachineInstr* MI) const {
const uint64_t F = MI->getDesc().TSFlags;
diff --git a/lib/Target/Hexagon/HexagonInstrInfo.h b/lib/Target/Hexagon/HexagonInstrInfo.h
index e0bec04..42ffb48 100644
--- a/lib/Target/Hexagon/HexagonInstrInfo.h
+++ b/lib/Target/Hexagon/HexagonInstrInfo.h
@@ -27,7 +27,7 @@ namespace llvm {
class HexagonInstrInfo : public HexagonGenInstrInfo {
const HexagonRegisterInfo RI;
- const HexagonSubtarget& Subtarget;
+ const HexagonSubtarget &Subtarget;
typedef unsigned Opcode_t;
public:
@@ -113,6 +113,7 @@ 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,
@@ -129,7 +130,11 @@ 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<MachineOperand> &Pred) const;
virtual bool
@@ -178,13 +183,21 @@ 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;
+ int GetDotOldOp(const int opc) const;
+ int GetDotNewOp(const MachineInstr* MI) const;
+ int GetDotNewPredOp(MachineInstr *MI,
+ const MachineBranchProbabilityInfo
+ *MBPI) const;
+ bool mayBeNewStore(const MachineInstr* MI) const;
bool isDeallocRet(const MachineInstr *MI) const;
unsigned getInvertedPredicatedOpcode(const int Opc) const;
bool isExtendable(const MachineInstr* MI) const;
bool isExtended(const MachineInstr* MI) const;
bool isPostIncrement(const MachineInstr* MI) const;
bool isNewValueStore(const MachineInstr* MI) const;
+ bool isNewValueStore(unsigned Opcode) const;
bool isNewValueJump(const MachineInstr* MI) const;
bool isNewValueJumpCandidate(const MachineInstr *MI) const;
diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td
index 2a4b17b..c96aaca 100644
--- a/lib/Target/Hexagon/HexagonInstrInfo.td
+++ b/lib/Target/Hexagon/HexagonInstrInfo.td
@@ -384,6 +384,12 @@ def TFCR : CRInst<(outs CRRegs:$dst), (ins IntRegs:$src1),
// ALU32/PERM +
//===----------------------------------------------------------------------===//
+let neverHasSideEffects = 1 in
+def COMBINE_ii : ALU32_ii<(outs DoubleRegs:$dst),
+ (ins s8Imm:$src1, s8Imm:$src2),
+ "$dst = combine(#$src1, #$src2)",
+ []>;
+
// Mux.
def VMUX_prr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1,
DoubleRegs:$src2,
@@ -932,12 +938,21 @@ multiclass LD_MEMri<string mnemonic, string CextOp, RegisterClass RC,
}
let addrMode = BaseImmOffset, isMEMri = "true" in {
- defm LDrib: LD_MEMri < "memb", "LDrib", IntRegs, 11, 6>, AddrModeRel;
- defm LDriub: LD_MEMri < "memub" , "LDriub", IntRegs, 11, 6>, AddrModeRel;
- defm LDrih: LD_MEMri < "memh", "LDrih", IntRegs, 12, 7>, AddrModeRel;
- defm LDriuh: LD_MEMri < "memuh", "LDriuh", IntRegs, 12, 7>, AddrModeRel;
- defm LDriw: LD_MEMri < "memw", "LDriw", IntRegs, 13, 8>, AddrModeRel;
- defm LDrid: LD_MEMri < "memd", "LDrid", DoubleRegs, 14, 9>, AddrModeRel;
+ let accessSize = ByteAccess in {
+ defm LDrib: LD_MEMri < "memb", "LDrib", IntRegs, 11, 6>, AddrModeRel;
+ defm LDriub: LD_MEMri < "memub" , "LDriub", IntRegs, 11, 6>, AddrModeRel;
+ }
+
+ let accessSize = HalfWordAccess in {
+ defm LDrih: LD_MEMri < "memh", "LDrih", IntRegs, 12, 7>, AddrModeRel;
+ defm LDriuh: LD_MEMri < "memuh", "LDriuh", IntRegs, 12, 7>, AddrModeRel;
+ }
+
+ let accessSize = WordAccess in
+ defm LDriw: LD_MEMri < "memw", "LDriw", IntRegs, 13, 8>, AddrModeRel;
+
+ let accessSize = DoubleWordAccess in
+ defm LDrid: LD_MEMri < "memd", "LDrid", DoubleRegs, 14, 9>, AddrModeRel;
}
def : Pat < (i32 (sextloadi8 ADDRriS11_0:$addr)),
@@ -1000,18 +1015,25 @@ multiclass LD_Idxd<string mnemonic, string CextOp, RegisterClass RC,
}
let addrMode = BaseImmOffset in {
- defm LDrib_indexed: LD_Idxd <"memb", "LDrib", IntRegs, s11_0Ext, u6_0Ext,
- 11, 6>, AddrModeRel;
- defm LDriub_indexed: LD_Idxd <"memub" , "LDriub", IntRegs, s11_0Ext, u6_0Ext,
- 11, 6>, AddrModeRel;
- defm LDrih_indexed: LD_Idxd <"memh", "LDrih", IntRegs, s11_1Ext, u6_1Ext,
- 12, 7>, AddrModeRel;
- defm LDriuh_indexed: LD_Idxd <"memuh", "LDriuh", IntRegs, s11_1Ext, u6_1Ext,
- 12, 7>, AddrModeRel;
- defm LDriw_indexed: LD_Idxd <"memw", "LDriw", IntRegs, s11_2Ext, u6_2Ext,
- 13, 8>, AddrModeRel;
- defm LDrid_indexed: LD_Idxd <"memd", "LDrid", DoubleRegs, s11_3Ext, u6_3Ext,
- 14, 9>, AddrModeRel;
+ let accessSize = ByteAccess in {
+ defm LDrib_indexed: LD_Idxd <"memb", "LDrib", IntRegs, s11_0Ext, u6_0Ext,
+ 11, 6>, AddrModeRel;
+ defm LDriub_indexed: LD_Idxd <"memub" , "LDriub", IntRegs, s11_0Ext, u6_0Ext,
+ 11, 6>, AddrModeRel;
+ }
+ let accessSize = HalfWordAccess in {
+ defm LDrih_indexed: LD_Idxd <"memh", "LDrih", IntRegs, s11_1Ext, u6_1Ext,
+ 12, 7>, AddrModeRel;
+ defm LDriuh_indexed: LD_Idxd <"memuh", "LDriuh", IntRegs, s11_1Ext, u6_1Ext,
+ 12, 7>, AddrModeRel;
+ }
+ let accessSize = WordAccess in
+ defm LDriw_indexed: LD_Idxd <"memw", "LDriw", IntRegs, s11_2Ext, u6_2Ext,
+ 13, 8>, AddrModeRel;
+
+ let accessSize = DoubleWordAccess in
+ defm LDrid_indexed: LD_Idxd <"memd", "LDrid", DoubleRegs, s11_3Ext, u6_3Ext,
+ 14, 9>, AddrModeRel;
}
let AddedComplexity = 20 in {
@@ -1036,8 +1058,6 @@ def : Pat < (i64 (load (add IntRegs:$src1, s11_3ExtPred:$offset))),
//===----------------------------------------------------------------------===//
// Post increment load
-// Make sure that in post increment load, the first operand is always the post
-// increment operand.
//===----------------------------------------------------------------------===//
multiclass LD_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp,
@@ -1079,7 +1099,7 @@ multiclass LD_PostInc<string mnemonic, string BaseOp, RegisterClass RC,
}
}
-let hasCtrlDep = 1, neverHasSideEffects = 1 in {
+let hasCtrlDep = 1, neverHasSideEffects = 1, addrMode = PostInc in {
defm POST_LDrib : LD_PostInc<"memb", "LDrib", IntRegs, s4_0Imm>,
PredNewRel;
defm POST_LDriub : LD_PostInc<"memub", "LDriub", IntRegs, s4_0Imm>,
@@ -1382,7 +1402,7 @@ multiclass ST_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp,
multiclass ST_PostInc_Pred<string mnemonic, RegisterClass RC,
Operand ImmOp, bit PredNot> {
let isPredicatedFalse = PredNot in {
- defm _c#NAME# : ST_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>;
+ defm _c#NAME : ST_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>;
// Predicate new
let Predicates = [HasV4T], validSubTargets = HasV4SubT in
defm _cdn#NAME#_V4 : ST_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 1>;
@@ -1397,7 +1417,7 @@ multiclass ST_PostInc<string mnemonic, string BaseOp, RegisterClass RC,
let isPredicable = 1 in
def NAME : STInst2PI<(outs IntRegs:$dst),
(ins IntRegs:$src1, ImmOp:$offset, RC:$src2),
- #mnemonic#"($src1++#$offset) = $src2",
+ mnemonic#"($src1++#$offset) = $src2",
[],
"$src1 = $dst">;
@@ -1474,12 +1494,17 @@ multiclass ST_MEMri<string mnemonic, string CextOp, RegisterClass RC,
}
let addrMode = BaseImmOffset, isMEMri = "true" in {
- defm STrib: ST_MEMri < "memb", "STrib", IntRegs, 11, 6>, AddrModeRel;
- defm STrih: ST_MEMri < "memh", "STrih", IntRegs, 12, 7>, AddrModeRel;
- defm STriw: ST_MEMri < "memw", "STriw", IntRegs, 13, 8>, AddrModeRel;
+ let accessSize = ByteAccess in
+ defm STrib: ST_MEMri < "memb", "STrib", IntRegs, 11, 6>, AddrModeRel;
+
+ let accessSize = HalfWordAccess in
+ defm STrih: ST_MEMri < "memh", "STrih", IntRegs, 12, 7>, AddrModeRel;
- let isNVStorable = 0 in
- defm STrid: ST_MEMri < "memd", "STrid", DoubleRegs, 14, 9>, AddrModeRel;
+ let accessSize = WordAccess in
+ defm STriw: ST_MEMri < "memw", "STriw", IntRegs, 13, 8>, AddrModeRel;
+
+ let accessSize = DoubleWordAccess, isNVStorable = 0 in
+ defm STrid: ST_MEMri < "memd", "STrid", DoubleRegs, 14, 9>, AddrModeRel;
}
def : Pat<(truncstorei8 (i32 IntRegs:$src1), ADDRriS11_0:$addr),
@@ -1541,15 +1566,21 @@ multiclass ST_Idxd<string mnemonic, string CextOp, RegisterClass RC,
}
let addrMode = BaseImmOffset, InputType = "reg" in {
- defm STrib_indexed: ST_Idxd < "memb", "STrib", IntRegs, s11_0Ext,
- u6_0Ext, 11, 6>, AddrModeRel, ImmRegRel;
- defm STrih_indexed: ST_Idxd < "memh", "STrih", IntRegs, s11_1Ext,
- u6_1Ext, 12, 7>, AddrModeRel, ImmRegRel;
- defm STriw_indexed: ST_Idxd < "memw", "STriw", IntRegs, s11_2Ext,
- u6_2Ext, 13, 8>, AddrModeRel, ImmRegRel;
- let isNVStorable = 0 in
- defm STrid_indexed: ST_Idxd < "memd", "STrid", DoubleRegs, s11_3Ext,
- u6_3Ext, 14, 9>, AddrModeRel;
+ let accessSize = ByteAccess in
+ defm STrib_indexed: ST_Idxd < "memb", "STrib", IntRegs, s11_0Ext,
+ u6_0Ext, 11, 6>, AddrModeRel, ImmRegRel;
+
+ let accessSize = HalfWordAccess in
+ defm STrih_indexed: ST_Idxd < "memh", "STrih", IntRegs, s11_1Ext,
+ u6_1Ext, 12, 7>, AddrModeRel, ImmRegRel;
+
+ let accessSize = WordAccess in
+ defm STriw_indexed: ST_Idxd < "memw", "STriw", IntRegs, s11_2Ext,
+ u6_2Ext, 13, 8>, AddrModeRel, ImmRegRel;
+
+ let accessSize = DoubleWordAccess, isNVStorable = 0 in
+ defm STrid_indexed: ST_Idxd < "memd", "STrid", DoubleRegs, s11_3Ext,
+ u6_3Ext, 14, 9>, AddrModeRel;
}
let AddedComplexity = 10 in {
diff --git a/lib/Target/Hexagon/HexagonInstrInfoV4.td b/lib/Target/Hexagon/HexagonInstrInfoV4.td
index 744efe8..fee83fb 100644
--- a/lib/Target/Hexagon/HexagonInstrInfoV4.td
+++ b/lib/Target/Hexagon/HexagonInstrInfoV4.td
@@ -213,7 +213,7 @@ def COMBINE_iI_V4 : ALU32_ii<(outs DoubleRegs:$dst),
// Template class for load instructions with Absolute set addressing mode.
//===----------------------------------------------------------------------===//
let isExtended = 1, opExtendable = 2, neverHasSideEffects = 1,
-validSubTargets = HasV4SubT in
+validSubTargets = HasV4SubT, addrMode = AbsoluteSet in
class T_LD_abs_set<string mnemonic, RegisterClass RC>:
LDInst2<(outs RC:$dst1, IntRegs:$dst2),
(ins u0AlwaysExt:$addr),
@@ -266,12 +266,23 @@ multiclass ld_idxd_shl<string mnemonic, string CextOp, RegisterClass RC> {
}
let addrMode = BaseRegOffset in {
- defm LDrib_indexed_shl: ld_idxd_shl<"memb", "LDrib", IntRegs>, AddrModeRel;
- defm LDriub_indexed_shl: ld_idxd_shl<"memub", "LDriub", IntRegs>, AddrModeRel;
- defm LDrih_indexed_shl: ld_idxd_shl<"memh", "LDrih", IntRegs>, AddrModeRel;
- defm LDriuh_indexed_shl: ld_idxd_shl<"memuh", "LDriuh", IntRegs>, AddrModeRel;
- defm LDriw_indexed_shl: ld_idxd_shl<"memw", "LDriw", IntRegs>, AddrModeRel;
- defm LDrid_indexed_shl: ld_idxd_shl<"memd", "LDrid", DoubleRegs>, AddrModeRel;
+ let accessSize = ByteAccess in {
+ defm LDrib_indexed_shl: ld_idxd_shl<"memb", "LDrib", IntRegs>,
+ AddrModeRel;
+ defm LDriub_indexed_shl: ld_idxd_shl<"memub", "LDriub", IntRegs>,
+ AddrModeRel;
+ }
+ let accessSize = HalfWordAccess in {
+ defm LDrih_indexed_shl: ld_idxd_shl<"memh", "LDrih", IntRegs>, AddrModeRel;
+ defm LDriuh_indexed_shl: ld_idxd_shl<"memuh", "LDriuh", IntRegs>,
+ AddrModeRel;
+ }
+ let accessSize = WordAccess in
+ defm LDriw_indexed_shl: ld_idxd_shl<"memw", "LDriw", IntRegs>, AddrModeRel;
+
+ let accessSize = DoubleWordAccess in
+ defm LDrid_indexed_shl: ld_idxd_shl<"memd", "LDrid", DoubleRegs>,
+ AddrModeRel;
}
// 'def pats' for load instructions with base + register offset and non-zero
@@ -456,7 +467,8 @@ def: Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
//===----------------------------------------------------------------------===//
// Template class for store instructions with Absolute set addressing mode.
//===----------------------------------------------------------------------===//
-let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in
+let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT,
+addrMode = AbsoluteSet in
class T_ST_abs_set<string mnemonic, RegisterClass RC>:
STInst2<(outs IntRegs:$dst1),
(ins RC:$src1, u0AlwaysExt:$src2),
@@ -551,17 +563,20 @@ multiclass ST_Idxd_shl_nv<string mnemonic, string CextOp, RegisterClass RC> {
let addrMode = BaseRegOffset, neverHasSideEffects = 1,
validSubTargets = HasV4SubT in {
- defm STrib_indexed_shl: ST_Idxd_shl<"memb", "STrib", IntRegs>,
- ST_Idxd_shl_nv<"memb", "STrib", IntRegs>, AddrModeRel;
+ let accessSize = ByteAccess in
+ defm STrib_indexed_shl: ST_Idxd_shl<"memb", "STrib", IntRegs>,
+ ST_Idxd_shl_nv<"memb", "STrib", IntRegs>, AddrModeRel;
- defm STrih_indexed_shl: ST_Idxd_shl<"memh", "STrih", IntRegs>,
- ST_Idxd_shl_nv<"memh", "STrih", IntRegs>, AddrModeRel;
+ let accessSize = HalfWordAccess in
+ defm STrih_indexed_shl: ST_Idxd_shl<"memh", "STrih", IntRegs>,
+ ST_Idxd_shl_nv<"memh", "STrih", IntRegs>, AddrModeRel;
- defm STriw_indexed_shl: ST_Idxd_shl<"memw", "STriw", IntRegs>,
- ST_Idxd_shl_nv<"memw", "STriw", IntRegs>, AddrModeRel;
+ let accessSize = WordAccess in
+ defm STriw_indexed_shl: ST_Idxd_shl<"memw", "STriw", IntRegs>,
+ ST_Idxd_shl_nv<"memw", "STriw", IntRegs>, AddrModeRel;
- let isNVStorable = 0 in
- defm STrid_indexed_shl: ST_Idxd_shl<"memd", "STrid", DoubleRegs>, AddrModeRel;
+ let isNVStorable = 0, accessSize = DoubleWordAccess in
+ defm STrid_indexed_shl: ST_Idxd_shl<"memd", "STrid", DoubleRegs>, AddrModeRel;
}
let Predicates = [HasV4T], AddedComplexity = 10 in {
@@ -695,10 +710,15 @@ multiclass ST_Imm<string mnemonic, string CextOp, Operand OffsetOp> {
}
let addrMode = BaseImmOffset, InputType = "imm",
- validSubTargets = HasV4SubT in {
- defm STrib_imm : ST_Imm<"memb", "STrib", u6_0Imm>, ImmRegRel, PredNewRel;
- defm STrih_imm : ST_Imm<"memh", "STrih", u6_1Imm>, ImmRegRel, PredNewRel;
- defm STriw_imm : ST_Imm<"memw", "STriw", u6_2Imm>, ImmRegRel, PredNewRel;
+validSubTargets = HasV4SubT in {
+ let accessSize = ByteAccess in
+ defm STrib_imm : ST_Imm<"memb", "STrib", u6_0Imm>, ImmRegRel, PredNewRel;
+
+ let accessSize = HalfWordAccess in
+ defm STrih_imm : ST_Imm<"memh", "STrih", u6_1Imm>, ImmRegRel, PredNewRel;
+
+ let accessSize = WordAccess in
+ defm STriw_imm : ST_Imm<"memw", "STriw", u6_2Imm>, ImmRegRel, PredNewRel;
}
let Predicates = [HasV4T], AddedComplexity = 10 in {
@@ -834,12 +854,17 @@ multiclass ST_Idxd_nv<string mnemonic, string CextOp, RegisterClass RC,
}
let addrMode = BaseImmOffset, validSubTargets = HasV4SubT in {
- defm STrib_indexed: ST_Idxd_nv<"memb", "STrib", IntRegs, s11_0Ext,
- u6_0Ext, 11, 6>, AddrModeRel;
- defm STrih_indexed: ST_Idxd_nv<"memh", "STrih", IntRegs, s11_1Ext,
- u6_1Ext, 12, 7>, AddrModeRel;
- defm STriw_indexed: ST_Idxd_nv<"memw", "STriw", IntRegs, s11_2Ext,
- u6_2Ext, 13, 8>, AddrModeRel;
+ let accessSize = ByteAccess in
+ defm STrib_indexed: ST_Idxd_nv<"memb", "STrib", IntRegs, s11_0Ext,
+ u6_0Ext, 11, 6>, AddrModeRel;
+
+ let accessSize = HalfWordAccess in
+ defm STrih_indexed: ST_Idxd_nv<"memh", "STrih", IntRegs, s11_1Ext,
+ u6_1Ext, 12, 7>, AddrModeRel;
+
+ let accessSize = WordAccess in
+ defm STriw_indexed: ST_Idxd_nv<"memw", "STriw", IntRegs, s11_2Ext,
+ u6_2Ext, 13, 8>, AddrModeRel;
}
// multiclass for new-value store instructions with base + immediate offset.
@@ -887,9 +912,14 @@ multiclass ST_MEMri_nv<string mnemonic, string CextOp, RegisterClass RC,
let addrMode = BaseImmOffset, isMEMri = "true", validSubTargets = HasV4SubT,
mayStore = 1 in {
- defm STrib: ST_MEMri_nv<"memb", "STrib", IntRegs, 11, 6>, AddrModeRel;
- defm STrih: ST_MEMri_nv<"memh", "STrih", IntRegs, 12, 7>, AddrModeRel;
- defm STriw: ST_MEMri_nv<"memw", "STriw", IntRegs, 13, 8>, AddrModeRel;
+ let accessSize = ByteAccess in
+ defm STrib: ST_MEMri_nv<"memb", "STrib", IntRegs, 11, 6>, AddrModeRel;
+
+ let accessSize = HalfWordAccess in
+ defm STrih: ST_MEMri_nv<"memh", "STrih", IntRegs, 12, 7>, AddrModeRel;
+
+ let accessSize = WordAccess in
+ defm STriw: ST_MEMri_nv<"memw", "STriw", IntRegs, 13, 8>, AddrModeRel;
}
//===----------------------------------------------------------------------===//
@@ -939,7 +969,7 @@ multiclass ST_PostInc_nv<string mnemonic, string BaseOp, RegisterClass RC,
}
}
-let validSubTargets = HasV4SubT in {
+let addrMode = PostInc, validSubTargets = HasV4SubT in {
defm POST_STbri: ST_PostInc_nv <"memb", "STrib", IntRegs, s4_0Imm>, AddrModeRel;
defm POST_SThri: ST_PostInc_nv <"memh", "STrih", IntRegs, s4_1Imm>, AddrModeRel;
defm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel;
@@ -967,179 +997,193 @@ defm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel;
// NV/J +
//===----------------------------------------------------------------------===//
-multiclass NVJ_type_basic_reg<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.new, $src2)) jump:",
- !strconcat(TakenStr, " $offset"))))),
- []>,
- Requires<[HasV4T]>;
+//===----------------------------------------------------------------------===//
+// multiclass/template class for the new-value compare jumps with the register
+// operands.
+//===----------------------------------------------------------------------===//
- 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]>;
-}
+let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11 in
+class NVJrr_template<string mnemonic, bits<3> 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]> {
-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]>;
+ bits<5> src1;
+ bits<5> src2;
+ bits<3> Ns; // New-Value Operand
+ bits<5> RegOp; // Non New-Value Operand
+ bits<11> offset;
- 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]>;
-}
+ let isBrTaken = !if(isTaken, "true", "false");
+ let isPredicatedFalse = isNegCond;
-multiclass NVJ_type_basic_imm<string NotStr, string OpcStr, string TakenStr> {
- 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]>;
+ let Ns = !if(!eq(NvOpNum, 0), src1{2-0}, src2{2-0});
+ let RegOp = !if(!eq(NvOpNum, 0), src2, src1);
- 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]>;
+ 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_neg<string NotStr, string OpcStr, string TakenStr> {
- 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]>;
- 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 NVJrr_cond<string mnemonic, bits<3> majOp, bit NvOpNum,
+ bit isNegCond> {
+ // Branch not taken:
+ def _nt_V4: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 0>;
+ // Branch taken:
+ def _t_V4: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 1>;
}
-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]>;
+// NvOpNum = 0 -> First Operand is a new-value Register
+// NvOpNum = 1 -> Second Operand is a new-value Register
- 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 NVJrr_base<string mnemonic, string BaseOp, bits<3> majOp,
+ bit NvOpNum> {
+ let BaseOpcode = BaseOp#_NVJ in {
+ defm _t_Jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 0>; // True cond
+ defm _f_Jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 1>; // False cond
+ }
}
-// 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">;
-}
+// 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 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">;
+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;
}
-// 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/template class for the new-value compare jumps instruction
+// with a register and an unsigned immediate (U5) operand.
+//===----------------------------------------------------------------------===//
-// 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">;
-}
+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]> {
-// 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">;
+ 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 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 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 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 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
+ }
}
-// 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>;
+// 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 for tstbit.
-multiclass NVJ_type_r0<string OpcStr> {
- defm r0Not : NVJ_type_br_pred_tstbit<"!", OpcStr>;
- defm r0 : NVJ_type_br_pred_tstbit<"", OpcStr>;
- }
+//===----------------------------------------------------------------------===//
+// 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]> {
-// 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 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};
}
-let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC] in {
- defm JMP_ : NVJ_type;
+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>;
}
-//===----------------------------------------------------------------------===//
-// NV/J -
-//===----------------------------------------------------------------------===//
+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 +
@@ -2520,8 +2564,9 @@ def NTSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
//Deallocate frame and return.
// dealloc_return
let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicable = 1,
- Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1 in {
- def DEALLOC_RET_V4 : NVInst_V4<(outs), (ins i32imm:$amt1),
+ Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1 in {
+let validSubTargets = HasV4SubT in
+ def DEALLOC_RET_V4 : LD0Inst<(outs), (ins),
"dealloc_return",
[]>,
Requires<[HasV4T]>;
@@ -2530,9 +2575,10 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicable = 1,
// Restore registers and dealloc return function call.
let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1,
Defs = [R29, R30, R31, PC] in {
+let validSubTargets = HasV4SubT in
def RESTORE_DEALLOC_RET_JMP_V4 : JInst<(outs),
(ins calltarget:$dst),
- "jump $dst // Restore_and_dealloc_return",
+ "jump $dst",
[]>,
Requires<[HasV4T]>;
}
@@ -2540,9 +2586,10 @@ let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1,
// Restore registers and dealloc frame before a tail call.
let isCall = 1, isBarrier = 1,
Defs = [R29, R30, R31, PC] in {
+let validSubTargets = HasV4SubT in
def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : JInst<(outs),
(ins calltarget:$dst),
- "call $dst // Restore_and_dealloc_before_tailcall",
+ "call $dst",
[]>,
Requires<[HasV4T]>;
}
@@ -2559,10 +2606,11 @@ let isCall = 1, isBarrier = 1,
// if (Ps) dealloc_return
let isReturn = 1, isTerminator = 1,
- Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
+ Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
isPredicated = 1 in {
- def DEALLOC_RET_cPt_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, i32imm:$amt1),
+let validSubTargets = HasV4SubT in
+ def DEALLOC_RET_cPt_V4 : LD0Inst<(outs),
+ (ins PredRegs:$src1),
"if ($src1) dealloc_return",
[]>,
Requires<[HasV4T]>;
@@ -2570,10 +2618,10 @@ let isReturn = 1, isTerminator = 1,
// if (!Ps) dealloc_return
let isReturn = 1, isTerminator = 1,
- Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
- isPredicated = 1 in {
- def DEALLOC_RET_cNotPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
- i32imm:$amt1),
+ Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
+ isPredicated = 1, isPredicatedFalse = 1 in {
+let validSubTargets = HasV4SubT in
+ def DEALLOC_RET_cNotPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
"if (!$src1) dealloc_return",
[]>,
Requires<[HasV4T]>;
@@ -2581,10 +2629,10 @@ let isReturn = 1, isTerminator = 1,
// if (Ps.new) dealloc_return:nt
let isReturn = 1, isTerminator = 1,
- Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
+ Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
isPredicated = 1 in {
- def DEALLOC_RET_cdnPnt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
- i32imm:$amt1),
+let validSubTargets = HasV4SubT in
+ def DEALLOC_RET_cdnPnt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
"if ($src1.new) dealloc_return:nt",
[]>,
Requires<[HasV4T]>;
@@ -2592,10 +2640,10 @@ let isReturn = 1, isTerminator = 1,
// if (!Ps.new) dealloc_return:nt
let isReturn = 1, isTerminator = 1,
- Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
- isPredicated = 1 in {
- def DEALLOC_RET_cNotdnPnt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
- i32imm:$amt1),
+ Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
+ isPredicated = 1, isPredicatedFalse = 1 in {
+let validSubTargets = HasV4SubT in
+ def DEALLOC_RET_cNotdnPnt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
"if (!$src1.new) dealloc_return:nt",
[]>,
Requires<[HasV4T]>;
@@ -2603,21 +2651,21 @@ let isReturn = 1, isTerminator = 1,
// if (Ps.new) dealloc_return:t
let isReturn = 1, isTerminator = 1,
- Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
+ Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
isPredicated = 1 in {
- def DEALLOC_RET_cdnPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
- i32imm:$amt1),
+let validSubTargets = HasV4SubT in
+ def DEALLOC_RET_cdnPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
"if ($src1.new) dealloc_return:t",
[]>,
Requires<[HasV4T]>;
}
-// if (!Ps.new) dealloc_return:nt
+// if (!Ps.new) dealloc_return:nt
let isReturn = 1, isTerminator = 1,
- Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
- isPredicated = 1 in {
- def DEALLOC_RET_cNotdnPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
- i32imm:$amt1),
+ Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
+ isPredicated = 1, isPredicatedFalse = 1 in {
+let validSubTargets = HasV4SubT in
+ def DEALLOC_RET_cNotdnPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
"if (!$src1.new) dealloc_return:t",
[]>,
Requires<[HasV4T]>;
@@ -3007,9 +3055,10 @@ def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))),
// Transfer global address into a register
-let AddedComplexity=50, isMoveImm = 1, isReMaterializable = 1 in
-def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$src1),
- "$dst = ##$src1",
+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",
[(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>,
Requires<[HasV4T]>;
@@ -3018,37 +3067,42 @@ def : Pat<(HexagonCONST32_GP tblockaddress:$src1),
(TFRI_V4 tblockaddress:$src1)>,
Requires<[HasV4T]>;
-let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
+let isExtended = 1, opExtendable = 2, AddedComplexity=50,
+neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
def TFRI_cPt_V4 : ALU32_ri<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$src2),
- "if($src1) $dst = ##$src2",
+ (ins PredRegs:$src1, s16Ext:$src2),
+ "if($src1) $dst = #$src2",
[]>,
Requires<[HasV4T]>;
-let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
+let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1,
+neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
def TFRI_cNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$src2),
- "if(!$src1) $dst = ##$src2",
+ (ins PredRegs:$src1, s16Ext:$src2),
+ "if(!$src1) $dst = #$src2",
[]>,
Requires<[HasV4T]>;
-let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
+let isExtended = 1, opExtendable = 2, AddedComplexity=50,
+neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
def TFRI_cdnPt_V4 : ALU32_ri<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$src2),
- "if($src1.new) $dst = ##$src2",
+ (ins PredRegs:$src1, s16Ext:$src2),
+ "if($src1.new) $dst = #$src2",
[]>,
Requires<[HasV4T]>;
-let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
+let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1,
+neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
def TFRI_cdnNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$src2),
- "if(!$src1.new) $dst = ##$src2",
+ (ins PredRegs:$src1, s16Ext:$src2),
+ "if(!$src1.new) $dst = #$src2",
[]>,
Requires<[HasV4T]>;
let AddedComplexity = 50, Predicates = [HasV4T] in
def : Pat<(HexagonCONST32_GP tglobaladdr:$src1),
- (TFRI_V4 tglobaladdr:$src1)>;
+ (TFRI_V4 tglobaladdr:$src1)>,
+ Requires<[HasV4T]>;
// Load - Indirect with long offset: These instructions take global address
@@ -3134,6 +3188,93 @@ def STriw_offset_ext_V4 : STInst<(outs),
(add IntRegs:$src1, u6_2ImmPred:$src2))]>,
Requires<[HasV4T]>;
+def : Pat<(i64 (ctlz (i64 DoubleRegs:$src1))),
+ (i64 (COMBINE_Ir_V4 (i32 0), (i32 (CTLZ64_rr DoubleRegs:$src1))))>,
+ Requires<[HasV4T]>;
+
+def : Pat<(i64 (cttz (i64 DoubleRegs:$src1))),
+ (i64 (COMBINE_Ir_V4 (i32 0), (i32 (CTTZ64_rr DoubleRegs:$src1))))>,
+ Requires<[HasV4T]>;
+
+
+// i8 -> i64 loads
+// We need a complexity of 120 here to overide preceeding handling of
+// zextloadi8.
+let Predicates = [HasV4T], AddedComplexity = 120 in {
+def: Pat <(i64 (extloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
+ (i64 (COMBINE_Ir_V4 0, (LDrib_abs_V4 tglobaladdr:$addr)))>;
+
+def: Pat <(i64 (zextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
+ (i64 (COMBINE_Ir_V4 0, (LDriub_abs_V4 tglobaladdr:$addr)))>;
+
+def: Pat <(i64 (sextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
+ (i64 (SXTW (LDrib_abs_V4 tglobaladdr:$addr)))>;
+
+def: Pat <(i64 (extloadi8 FoldGlobalAddr:$addr)),
+ (i64 (COMBINE_Ir_V4 0, (LDrib_abs_V4 FoldGlobalAddr:$addr)))>;
+
+def: Pat <(i64 (zextloadi8 FoldGlobalAddr:$addr)),
+ (i64 (COMBINE_Ir_V4 0, (LDriub_abs_V4 FoldGlobalAddr:$addr)))>;
+
+def: Pat <(i64 (sextloadi8 FoldGlobalAddr:$addr)),
+ (i64 (SXTW (LDrib_abs_V4 FoldGlobalAddr:$addr)))>;
+}
+// i16 -> i64 loads
+// We need a complexity of 120 here to overide preceeding handling of
+// zextloadi16.
+let AddedComplexity = 120 in {
+def: Pat <(i64 (extloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
+ (i64 (COMBINE_Ir_V4 0, (LDrih_abs_V4 tglobaladdr:$addr)))>,
+ Requires<[HasV4T]>;
+
+def: Pat <(i64 (zextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
+ (i64 (COMBINE_Ir_V4 0, (LDriuh_abs_V4 tglobaladdr:$addr)))>,
+ Requires<[HasV4T]>;
+
+def: Pat <(i64 (sextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
+ (i64 (SXTW (LDrih_abs_V4 tglobaladdr:$addr)))>,
+ Requires<[HasV4T]>;
+
+def: Pat <(i64 (extloadi16 FoldGlobalAddr:$addr)),
+ (i64 (COMBINE_Ir_V4 0, (LDrih_abs_V4 FoldGlobalAddr:$addr)))>,
+ Requires<[HasV4T]>;
+
+def: Pat <(i64 (zextloadi16 FoldGlobalAddr:$addr)),
+ (i64 (COMBINE_Ir_V4 0, (LDriuh_abs_V4 FoldGlobalAddr:$addr)))>,
+ Requires<[HasV4T]>;
+
+def: Pat <(i64 (sextloadi16 FoldGlobalAddr:$addr)),
+ (i64 (SXTW (LDrih_abs_V4 FoldGlobalAddr:$addr)))>,
+ Requires<[HasV4T]>;
+}
+// i32->i64 loads
+// We need a complexity of 120 here to overide preceeding handling of
+// zextloadi32.
+let AddedComplexity = 120 in {
+def: Pat <(i64 (extloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
+ (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 tglobaladdr:$addr)))>,
+ Requires<[HasV4T]>;
+
+def: Pat <(i64 (zextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
+ (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 tglobaladdr:$addr)))>,
+ Requires<[HasV4T]>;
+
+def: Pat <(i64 (sextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
+ (i64 (SXTW (LDriw_abs_V4 tglobaladdr:$addr)))>,
+ Requires<[HasV4T]>;
+
+def: Pat <(i64 (extloadi32 FoldGlobalAddr:$addr)),
+ (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>,
+ Requires<[HasV4T]>;
+
+def: Pat <(i64 (zextloadi32 FoldGlobalAddr:$addr)),
+ (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>,
+ Requires<[HasV4T]>;
+
+def: Pat <(i64 (sextloadi32 FoldGlobalAddr:$addr)),
+ (i64 (SXTW (LDriw_abs_V4 FoldGlobalAddr:$addr)))>,
+ Requires<[HasV4T]>;
+}
// Indexed store double word - global address.
// memw(Rs+#u6:2)=#S8
diff --git a/lib/Target/Hexagon/HexagonInstrInfoV5.td b/lib/Target/Hexagon/HexagonInstrInfoV5.td
index 92d098c..9da6074 100644
--- a/lib/Target/Hexagon/HexagonInstrInfoV5.td
+++ b/lib/Target/Hexagon/HexagonInstrInfoV5.td
@@ -26,22 +26,29 @@ def CONST32_Float_Real : LDInst<(outs IntRegs:$dst), (ins f32imm:$src1),
// Only works with single precision fp value.
// For double precision, use CONST64_float_real, as 64bit transfer
// can only hold 40-bit values - 32 from const ext + 8 bit immediate.
-let isMoveImm = 1, isReMaterializable = 1, isPredicable = 1 in
-def TFRI_f : ALU32_ri<(outs IntRegs:$dst), (ins f32imm:$src1),
- "$dst = ##$src1",
+// Make sure that complexity is more than the CONST32 pattern in
+// HexagonInstrInfo.td patterns.
+let isExtended = 1, opExtendable = 1, isMoveImm = 1, isReMaterializable = 1,
+isPredicable = 1, AddedComplexity = 30, validSubTargets = HasV5SubT,
+isCodeGenOnly = 1 in
+def TFRI_f : ALU32_ri<(outs IntRegs:$dst), (ins f32Ext:$src1),
+ "$dst = #$src1",
[(set IntRegs:$dst, fpimm:$src1)]>,
Requires<[HasV5T]>;
+let isExtended = 1, opExtendable = 2, isPredicated = 1,
+neverHasSideEffects = 1, validSubTargets = HasV5SubT in
def TFRI_cPt_f : ALU32_ri<(outs IntRegs:$dst),
- (ins PredRegs:$src1, f32imm:$src2),
- "if ($src1) $dst = ##$src2",
+ (ins PredRegs:$src1, f32Ext:$src2),
+ "if ($src1) $dst = #$src2",
[]>,
Requires<[HasV5T]>;
-let isPredicated = 1 in
+let isExtended = 1, opExtendable = 2, isPredicated = 1, isPredicatedFalse = 1,
+neverHasSideEffects = 1, validSubTargets = HasV5SubT in
def TFRI_cNotPt_f : ALU32_ri<(outs IntRegs:$dst),
- (ins PredRegs:$src1, f32imm:$src2),
- "if (!$src1) $dst = ##$src2",
+ (ins PredRegs:$src1, f32Ext:$src2),
+ "if (!$src1) $dst =#$src2",
[]>,
Requires<[HasV5T]>;
diff --git a/lib/Target/Hexagon/HexagonMachineScheduler.cpp b/lib/Target/Hexagon/HexagonMachineScheduler.cpp
index 1388ad4..6e966ec 100644
--- a/lib/Target/Hexagon/HexagonMachineScheduler.cpp
+++ b/lib/Target/Hexagon/HexagonMachineScheduler.cpp
@@ -195,7 +195,6 @@ void VLIWMachineScheduler::schedule() {
void ConvergingVLIWScheduler::initialize(ScheduleDAGMI *dag) {
DAG = static_cast<VLIWMachineScheduler*>(dag);
SchedModel = DAG->getSchedModel();
- TRI = DAG->TRI;
Top.init(DAG, SchedModel);
Bot.init(DAG, SchedModel);
@@ -409,7 +408,7 @@ void ConvergingVLIWScheduler::traceCandidate(const char *Label,
SUnit *SU, PressureElement P) {
dbgs() << Label << " " << Q.getName() << " ";
if (P.isValid())
- dbgs() << TRI->getRegPressureSetName(P.PSetID) << ":" << P.UnitIncrease
+ dbgs() << DAG->TRI->getRegPressureSetName(P.PSetID) << ":" << P.UnitIncrease
<< " ";
else
dbgs() << " ";
diff --git a/lib/Target/Hexagon/HexagonMachineScheduler.h b/lib/Target/Hexagon/HexagonMachineScheduler.h
index f68dadf..171193e 100644
--- a/lib/Target/Hexagon/HexagonMachineScheduler.h
+++ b/lib/Target/Hexagon/HexagonMachineScheduler.h
@@ -190,7 +190,6 @@ class ConvergingVLIWScheduler : public MachineSchedStrategy {
VLIWMachineScheduler *DAG;
const TargetSchedModel *SchedModel;
- const TargetRegisterInfo *TRI;
// State of the top and bottom scheduled instruction boundaries.
SchedBoundary Top;
@@ -205,7 +204,7 @@ public:
};
ConvergingVLIWScheduler():
- DAG(0), SchedModel(0), TRI(0), Top(TopQID, "TopQ"), Bot(BotQID, "BotQ") {}
+ DAG(0), SchedModel(0), Top(TopQID, "TopQ"), Bot(BotQID, "BotQ") {}
virtual void initialize(ScheduleDAGMI *dag);
diff --git a/lib/Target/Hexagon/HexagonNewValueJump.cpp b/lib/Target/Hexagon/HexagonNewValueJump.cpp
index 72af876..f7c4513 100644
--- a/lib/Target/Hexagon/HexagonNewValueJump.cpp
+++ b/lib/Target/Hexagon/HexagonNewValueJump.cpp
@@ -22,29 +22,31 @@
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "hexagon-nvj"
-#include "Hexagon.h"
-#include "HexagonInstrInfo.h"
-#include "HexagonMachineFunctionInfo.h"
-#include "HexagonRegisterInfo.h"
-#include "HexagonSubtarget.h"
-#include "HexagonTargetMachine.h"
+#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/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/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 <map>
+
+#include "llvm/Support/CommandLine.h"
using namespace llvm;
STATISTIC(NumNVJGenerated, "Number of New Value Jump Instructions created");
@@ -57,6 +59,11 @@ static cl::opt<bool> 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;
@@ -65,7 +72,9 @@ namespace {
public:
static char ID;
- HexagonNewValueJump() : MachineFunctionPass(ID) { }
+ HexagonNewValueJump() : MachineFunctionPass(ID) {
+ initializeHexagonNewValueJumpPass(*PassRegistry::getPassRegistry());
+ }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<MachineBranchProbabilityInfo>();
@@ -88,6 +97,13 @@ 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,
@@ -219,7 +235,7 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII,
return false;
}
- unsigned cmpReg1, cmpOp2;
+ unsigned cmpReg1, cmpOp2 = 0; // cmpOp2 assignment silences compiler warning.
cmpReg1 = MI->getOperand(1).getReg();
if (secondReg) {
@@ -285,43 +301,48 @@ static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg,
switch (MI->getOpcode()) {
case Hexagon::CMPEQrr:
- return taken ? Hexagon::JMP_EQrrPt_nv_V4 : Hexagon::JMP_EQrrPnt_nv_V4;
+ return taken ? Hexagon::CMPEQrr_t_Jumpnv_t_V4
+ : Hexagon::CMPEQrr_t_Jumpnv_nt_V4;
case Hexagon::CMPEQri: {
if (reg >= 0)
- return taken ? Hexagon::JMP_EQriPt_nv_V4 : Hexagon::JMP_EQriPnt_nv_V4;
+ return taken ? Hexagon::CMPEQri_t_Jumpnv_t_V4
+ : Hexagon::CMPEQri_t_Jumpnv_nt_V4;
else
- return taken ? Hexagon::JMP_EQriPtneg_nv_V4
- : Hexagon::JMP_EQriPntneg_nv_V4;
+ return taken ? Hexagon::CMPEQn1_t_Jumpnv_t_V4
+ : Hexagon::CMPEQn1_t_Jumpnv_nt_V4;
}
case Hexagon::CMPGTrr: {
if (secondRegNewified)
- return taken ? Hexagon::JMP_GTrrdnPt_nv_V4
- : Hexagon::JMP_GTrrdnPnt_nv_V4;
+ return taken ? Hexagon::CMPLTrr_t_Jumpnv_t_V4
+ : Hexagon::CMPLTrr_t_Jumpnv_nt_V4;
else
- return taken ? Hexagon::JMP_GTrrPt_nv_V4
- : Hexagon::JMP_GTrrPnt_nv_V4;
+ return taken ? Hexagon::CMPGTrr_t_Jumpnv_t_V4
+ : Hexagon::CMPGTrr_t_Jumpnv_nt_V4;
}
case Hexagon::CMPGTri: {
if (reg >= 0)
- return taken ? Hexagon::JMP_GTriPt_nv_V4 : Hexagon::JMP_GTriPnt_nv_V4;
+ return taken ? Hexagon::CMPGTri_t_Jumpnv_t_V4
+ : Hexagon::CMPGTri_t_Jumpnv_nt_V4;
else
- return taken ? Hexagon::JMP_GTriPtneg_nv_V4
- : Hexagon::JMP_GTriPntneg_nv_V4;
+ return taken ? Hexagon::CMPGTn1_t_Jumpnv_t_V4
+ : Hexagon::CMPGTn1_t_Jumpnv_nt_V4;
}
case Hexagon::CMPGTUrr: {
if (secondRegNewified)
- return taken ? Hexagon::JMP_GTUrrdnPt_nv_V4
- : Hexagon::JMP_GTUrrdnPnt_nv_V4;
+ return taken ? Hexagon::CMPLTUrr_t_Jumpnv_t_V4
+ : Hexagon::CMPLTUrr_t_Jumpnv_nt_V4;
else
- return taken ? Hexagon::JMP_GTUrrPt_nv_V4 : Hexagon::JMP_GTUrrPnt_nv_V4;
+ return taken ? Hexagon::CMPGTUrr_t_Jumpnv_t_V4
+ : Hexagon::CMPGTUrr_t_Jumpnv_nt_V4;
}
case Hexagon::CMPGTUri:
- return taken ? Hexagon::JMP_GTUriPt_nv_V4 : Hexagon::JMP_GTUriPnt_nv_V4;
+ return taken ? Hexagon::CMPGTUri_t_Jumpnv_t_V4
+ : Hexagon::CMPGTUri_t_Jumpnv_nt_V4;
default:
llvm_unreachable("Could not find matching New Value Jump instruction.");
@@ -610,6 +631,7 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
.addMBB(jmpTarget);
assert(NewMI && "New Value Jump Instruction Not created!");
+ (void)NewMI;
if (cmpInstr->getOperand(0).isReg() &&
cmpInstr->getOperand(0).isKill())
cmpInstr->getOperand(0).setIsKill(false);
diff --git a/lib/Target/Hexagon/HexagonPeephole.cpp b/lib/Target/Hexagon/HexagonPeephole.cpp
index 6c4eb7e..89e3406 100644
--- a/lib/Target/Hexagon/HexagonPeephole.cpp
+++ b/lib/Target/Hexagon/HexagonPeephole.cpp
@@ -61,10 +61,6 @@ static cl::opt<bool> DisableHexagonPeephole("disable-hexagon-peephole",
cl::Hidden, cl::ZeroOrMore, cl::init(false),
cl::desc("Disable Peephole Optimization"));
-static cl::opt<int>
-DbgPNPCount("pnp-count", cl::init(-1), cl::Hidden,
- cl::desc("Maximum number of P=NOT(P) to be optimized"));
-
static cl::opt<bool> DisablePNotP("disable-hexagon-pnotp",
cl::Hidden, cl::ZeroOrMore, cl::init(false),
cl::desc("Disable Optimization of PNotP"));
@@ -77,6 +73,10 @@ static cl::opt<bool> DisableOptExtTo64("disable-hexagon-opt-ext-to-64",
cl::Hidden, cl::ZeroOrMore, cl::init(false),
cl::desc("Disable Optimization of extensions to i64."));
+namespace llvm {
+ void initializeHexagonPeepholePass(PassRegistry&);
+}
+
namespace {
struct HexagonPeephole : public MachineFunctionPass {
const HexagonInstrInfo *QII;
@@ -85,7 +85,9 @@ namespace {
public:
static char ID;
- HexagonPeephole() : MachineFunctionPass(ID) { }
+ HexagonPeephole() : MachineFunctionPass(ID) {
+ initializeHexagonPeepholePass(*PassRegistry::getPassRegistry());
+ }
bool runOnMachineFunction(MachineFunction &MF);
@@ -104,8 +106,10 @@ namespace {
char HexagonPeephole::ID = 0;
-bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
+INITIALIZE_PASS(HexagonPeephole, "hexagon-peephole", "Hexagon Peephole",
+ false, false)
+bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
QII = static_cast<const HexagonInstrInfo *>(MF.getTarget().
getInstrInfo());
QRI = static_cast<const HexagonRegisterInfo *>(MF.getTarget().
diff --git a/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/lib/Target/Hexagon/HexagonRegisterInfo.cpp
index d8b4e2f..d5ca4d7 100644
--- a/lib/Target/Hexagon/HexagonRegisterInfo.cpp
+++ b/lib/Target/Hexagon/HexagonRegisterInfo.cpp
@@ -38,11 +38,9 @@
using namespace llvm;
-HexagonRegisterInfo::HexagonRegisterInfo(HexagonSubtarget &st,
- const HexagonInstrInfo &tii)
+HexagonRegisterInfo::HexagonRegisterInfo(HexagonSubtarget &st)
: HexagonGenRegisterInfo(Hexagon::R31),
- Subtarget(st),
- TII(tii) {
+ Subtarget(st) {
}
const uint16_t* HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction
@@ -130,6 +128,8 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
// Addressable stack objects are accessed using neg. offsets from %fp.
MachineFunction &MF = *MI.getParent()->getParent();
+ const HexagonInstrInfo &TII =
+ *static_cast<const HexagonInstrInfo*>(MF.getTarget().getInstrInfo());
int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
MachineFrameInfo &MFI = *MF.getFrameInfo();
@@ -295,16 +295,6 @@ unsigned HexagonRegisterInfo::getStackRegister() const {
return Hexagon::R29;
}
-void HexagonRegisterInfo::getInitialFrameState(std::vector<MachineMove>
- &Moves) const
-{
- // VirtualFP = (R30 + #0).
- unsigned FPReg = getFrameRegister();
- MachineLocation Dst(MachineLocation::VirtualFP);
- MachineLocation Src(FPReg, 0);
- Moves.push_back(MachineMove(0, Dst, Src));
-}
-
unsigned HexagonRegisterInfo::getEHExceptionRegister() const {
llvm_unreachable("What is the exception register");
}
diff --git a/lib/Target/Hexagon/HexagonRegisterInfo.h b/lib/Target/Hexagon/HexagonRegisterInfo.h
index 8a3f94a..fec86df 100644
--- a/lib/Target/Hexagon/HexagonRegisterInfo.h
+++ b/lib/Target/Hexagon/HexagonRegisterInfo.h
@@ -44,9 +44,8 @@ class Type;
struct HexagonRegisterInfo : public HexagonGenRegisterInfo {
HexagonSubtarget &Subtarget;
- const HexagonInstrInfo &TII;
- HexagonRegisterInfo(HexagonSubtarget &st, const HexagonInstrInfo &tii);
+ HexagonRegisterInfo(HexagonSubtarget &st);
/// Code Generation virtual methods...
const uint16_t *getCalleeSavedRegs(const MachineFunction *MF = 0) const;
@@ -78,7 +77,6 @@ struct HexagonRegisterInfo : public HexagonGenRegisterInfo {
unsigned getRARegister() const;
unsigned getFrameRegister(const MachineFunction &MF) const;
unsigned getFrameRegister() const;
- void getInitialFrameState(std::vector<MachineMove> &Moves) const;
unsigned getStackRegister() const;
// Exception handling queries.
diff --git a/lib/Target/Hexagon/HexagonRegisterInfo.td b/lib/Target/Hexagon/HexagonRegisterInfo.td
index fe41fc3..8ea1b7e 100644
--- a/lib/Target/Hexagon/HexagonRegisterInfo.td
+++ b/lib/Target/Hexagon/HexagonRegisterInfo.td
@@ -57,8 +57,8 @@ let Namespace = "Hexagon" in {
let Aliases = [R];
}
- def subreg_loreg : SubRegIndex;
- def subreg_hireg : SubRegIndex;
+ def subreg_loreg : SubRegIndex<32>;
+ def subreg_hireg : SubRegIndex<32, 32>;
// Integer registers.
def R0 : Ri< 0, "r0">, DwarfRegNum<[0]>;
diff --git a/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp b/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp
index 34bf4ea..44234e8 100644
--- a/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp
+++ b/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp
@@ -21,11 +21,18 @@
#include "llvm/Transforms/Scalar.h"
using namespace llvm;
+
+namespace llvm {
+ void initializeHexagonRemoveExtendArgsPass(PassRegistry&);
+}
+
namespace {
struct HexagonRemoveExtendArgs : public FunctionPass {
public:
static char ID;
- HexagonRemoveExtendArgs() : FunctionPass(ID) {}
+ HexagonRemoveExtendArgs() : FunctionPass(ID) {
+ initializeHexagonRemoveExtendArgsPass(*PassRegistry::getPassRegistry());
+ }
virtual bool runOnFunction(Function &F);
const char *getPassName() const {
@@ -41,11 +48,9 @@ namespace {
}
char HexagonRemoveExtendArgs::ID = 0;
-RegisterPass<HexagonRemoveExtendArgs> X("reargs",
- "Remove Sign and Zero Extends for Args"
- );
-
+INITIALIZE_PASS(HexagonRemoveExtendArgs, "reargs",
+ "Remove Sign and Zero Extends for Args", false, false)
bool HexagonRemoveExtendArgs::runOnFunction(Function &F) {
unsigned Idx = 1;
@@ -78,6 +83,7 @@ bool HexagonRemoveExtendArgs::runOnFunction(Function &F) {
-FunctionPass *llvm::createHexagonRemoveExtendOps(HexagonTargetMachine &TM) {
+FunctionPass*
+llvm::createHexagonRemoveExtendArgs(const HexagonTargetMachine &TM) {
return new HexagonRemoveExtendArgs();
}
diff --git a/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp b/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
index a52c604..c37bf9f 100644
--- a/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
+++ b/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
@@ -27,7 +27,7 @@ HexagonSelectionDAGInfo::~HexagonSelectionDAGInfo() {
SDValue
HexagonSelectionDAGInfo::
-EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl, SDValue Chain,
+EmitTargetCodeForMemcpy(SelectionDAG &DAG, SDLoc dl, SDValue Chain,
SDValue Dst, SDValue Src, SDValue Size, unsigned Align,
bool isVolatile, bool AlwaysInline,
MachinePointerInfo DstPtrInfo,
diff --git a/lib/Target/Hexagon/HexagonSelectionDAGInfo.h b/lib/Target/Hexagon/HexagonSelectionDAGInfo.h
index 0673e4d..31f278a 100644
--- a/lib/Target/Hexagon/HexagonSelectionDAGInfo.h
+++ b/lib/Target/Hexagon/HexagonSelectionDAGInfo.h
@@ -26,7 +26,7 @@ public:
~HexagonSelectionDAGInfo();
virtual
- SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
+ SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, SDLoc dl,
SDValue Chain,
SDValue Dst, SDValue Src,
SDValue Size, unsigned Align,
diff --git a/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp b/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp
new file mode 100644
index 0000000..3bf2f20
--- /dev/null
+++ b/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp
@@ -0,0 +1,176 @@
+//=== HexagonSplitConst32AndConst64.cpp - split CONST32/Const64 into HI/LO ===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// When the compiler is invoked with no small data, for instance, with the -G0
+// command line option, then all CONST32_* opcodes should be broken down into
+// appropriate LO and HI instructions. This splitting is done by this pass.
+// The only reason this is not done in the DAG lowering itself is that there
+// is no simple way of getting the register allocator to allot the same hard
+// register to the result of LO and HI instructions. This pass is always
+// scheduled after register allocation.
+//
+//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "xfer"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/ScheduleDAGInstrs.h"
+#include "llvm/CodeGen/LatencyPriorityQueue.h"
+#include "llvm/CodeGen/SchedulerRegistry.h"
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "HexagonTargetMachine.h"
+#include "HexagonSubtarget.h"
+#include "HexagonMachineFunctionInfo.h"
+#include <map>
+#include <iostream>
+
+#include "llvm/Support/CommandLine.h"
+#define DEBUG_TYPE "xfer"
+
+
+using namespace llvm;
+
+namespace {
+
+class HexagonSplitConst32AndConst64 : public MachineFunctionPass {
+ const HexagonTargetMachine& QTM;
+ const HexagonSubtarget &QST;
+
+ public:
+ static char ID;
+ HexagonSplitConst32AndConst64(const HexagonTargetMachine& TM)
+ : MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) {}
+
+ const char *getPassName() const {
+ return "Hexagon Split Const32s and Const64s";
+ }
+ bool runOnMachineFunction(MachineFunction &Fn);
+};
+
+
+char HexagonSplitConst32AndConst64::ID = 0;
+
+
+bool HexagonSplitConst32AndConst64::runOnMachineFunction(MachineFunction &Fn) {
+
+ const TargetInstrInfo *TII = QTM.getInstrInfo();
+
+ // Loop over all of the basic blocks
+ for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end();
+ MBBb != MBBe; ++MBBb) {
+ MachineBasicBlock* MBB = MBBb;
+ // Traverse the basic block
+ MachineBasicBlock::iterator MII = MBB->begin();
+ MachineBasicBlock::iterator MIE = MBB->end ();
+ while (MII != MIE) {
+ MachineInstr *MI = MII;
+ int Opc = MI->getOpcode();
+ if (Opc == Hexagon::CONST32_set) {
+ int DestReg = MI->getOperand(0).getReg();
+ MachineOperand &Symbol = MI->getOperand (1);
+
+ BuildMI (*MBB, MII, MI->getDebugLoc(),
+ TII->get(Hexagon::LO), DestReg).addOperand(Symbol);
+ BuildMI (*MBB, MII, MI->getDebugLoc(),
+ TII->get(Hexagon::HI), DestReg).addOperand(Symbol);
+ // MBB->erase returns the iterator to the next instruction, which is the
+ // one we want to process next
+ MII = MBB->erase (MI);
+ continue;
+ }
+ else if (Opc == Hexagon::CONST32_set_jt) {
+ int DestReg = MI->getOperand(0).getReg();
+ MachineOperand &Symbol = MI->getOperand (1);
+
+ BuildMI (*MBB, MII, MI->getDebugLoc(),
+ TII->get(Hexagon::LO_jt), DestReg).addOperand(Symbol);
+ BuildMI (*MBB, MII, MI->getDebugLoc(),
+ TII->get(Hexagon::HI_jt), DestReg).addOperand(Symbol);
+ // MBB->erase returns the iterator to the next instruction, which is the
+ // one we want to process next
+ MII = MBB->erase (MI);
+ continue;
+ }
+ else if (Opc == Hexagon::CONST32_Label) {
+ int DestReg = MI->getOperand(0).getReg();
+ MachineOperand &Symbol = MI->getOperand (1);
+
+ BuildMI (*MBB, MII, MI->getDebugLoc(),
+ TII->get(Hexagon::LO_label), DestReg).addOperand(Symbol);
+ BuildMI (*MBB, MII, MI->getDebugLoc(),
+ TII->get(Hexagon::HI_label), DestReg).addOperand(Symbol);
+ // MBB->erase returns the iterator to the next instruction, which is the
+ // one we want to process next
+ MII = MBB->erase (MI);
+ continue;
+ }
+ else if (Opc == Hexagon::CONST32_Int_Real) {
+ int DestReg = MI->getOperand(0).getReg();
+ int64_t ImmValue = MI->getOperand(1).getImm ();
+
+ BuildMI (*MBB, MII, MI->getDebugLoc(),
+ TII->get(Hexagon::LOi), DestReg).addImm(ImmValue);
+ BuildMI (*MBB, MII, MI->getDebugLoc(),
+ TII->get(Hexagon::HIi), DestReg).addImm(ImmValue);
+ MII = MBB->erase (MI);
+ continue;
+ }
+ else if (Opc == Hexagon::CONST64_Int_Real) {
+ int DestReg = MI->getOperand(0).getReg();
+ int64_t ImmValue = MI->getOperand(1).getImm ();
+ unsigned DestLo =
+ QTM.getRegisterInfo()->getSubReg (DestReg, Hexagon::subreg_loreg);
+ unsigned DestHi =
+ QTM.getRegisterInfo()->getSubReg (DestReg, Hexagon::subreg_hireg);
+
+ int32_t LowWord = (ImmValue & 0xFFFFFFFF);
+ int32_t HighWord = (ImmValue >> 32) & 0xFFFFFFFF;
+
+ // Lower Registers Lower Half
+ BuildMI (*MBB, MII, MI->getDebugLoc(),
+ TII->get(Hexagon::LOi), DestLo).addImm(LowWord);
+ // Lower Registers Higher Half
+ BuildMI (*MBB, MII, MI->getDebugLoc(),
+ TII->get(Hexagon::HIi), DestLo).addImm(LowWord);
+ // Higher Registers Lower Half
+ BuildMI (*MBB, MII, MI->getDebugLoc(),
+ TII->get(Hexagon::LOi), DestHi).addImm(HighWord);
+ // Higher Registers Higher Half.
+ BuildMI (*MBB, MII, MI->getDebugLoc(),
+ TII->get(Hexagon::HIi), DestHi).addImm(HighWord);
+ MII = MBB->erase (MI);
+ continue;
+ }
+ ++MII;
+ }
+ }
+
+ return true;
+}
+
+}
+
+//===----------------------------------------------------------------------===//
+// Public Constructor Functions
+//===----------------------------------------------------------------------===//
+
+FunctionPass *
+llvm::createHexagonSplitConst32AndConst64(const HexagonTargetMachine &TM) {
+ return new HexagonSplitConst32AndConst64(TM);
+}
diff --git a/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp b/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp
index 814249f..8608e08 100644
--- a/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp
+++ b/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp
@@ -49,16 +49,23 @@
using namespace llvm;
+namespace llvm {
+ void initializeHexagonSplitTFRCondSetsPass(PassRegistry&);
+}
+
+
namespace {
class HexagonSplitTFRCondSets : public MachineFunctionPass {
- HexagonTargetMachine& QTM;
+ const HexagonTargetMachine &QTM;
const HexagonSubtarget &QST;
public:
static char ID;
- HexagonSplitTFRCondSets(HexagonTargetMachine& TM) :
- MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) {}
+ HexagonSplitTFRCondSets(const HexagonTargetMachine& TM) :
+ MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) {
+ initializeHexagonSplitTFRCondSetsPass(*PassRegistry::getPassRegistry());
+ }
const char *getPassName() const {
return "Hexagon Split TFRCondSets";
@@ -211,6 +218,18 @@ bool HexagonSplitTFRCondSets::runOnMachineFunction(MachineFunction &Fn) {
// Public Constructor Functions
//===----------------------------------------------------------------------===//
-FunctionPass *llvm::createHexagonSplitTFRCondSets(HexagonTargetMachine &TM) {
+static void initializePassOnce(PassRegistry &Registry) {
+ const char *Name = "Hexagon Split TFRCondSets";
+ PassInfo *PI = new PassInfo(Name, "hexagon-split-tfr",
+ &HexagonSplitTFRCondSets::ID, 0, false, false);
+ Registry.registerPass(*PI, true);
+}
+
+void llvm::initializeHexagonSplitTFRCondSetsPass(PassRegistry &Registry) {
+ CALL_ONCE_INITIALIZATION(initializePassOnce)
+}
+
+FunctionPass*
+llvm::createHexagonSplitTFRCondSets(const HexagonTargetMachine &TM) {
return new HexagonSplitTFRCondSets(TM);
}
diff --git a/lib/Target/Hexagon/HexagonTargetMachine.cpp b/lib/Target/Hexagon/HexagonTargetMachine.cpp
index ce45c62..b113b35 100644
--- a/lib/Target/Hexagon/HexagonTargetMachine.cpp
+++ b/lib/Target/Hexagon/HexagonTargetMachine.cpp
@@ -15,6 +15,7 @@
#include "Hexagon.h"
#include "HexagonISelLowering.h"
#include "HexagonMachineScheduler.h"
+#include "HexagonTargetObjectFile.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/Module.h"
#include "llvm/PassManager.h"
@@ -25,19 +26,17 @@
using namespace llvm;
-static cl::
-opt<bool> DisableHardwareLoops(
- "disable-hexagon-hwloops", cl::Hidden,
- cl::desc("Disable Hardware Loops for Hexagon target"));
+static cl:: opt<bool> DisableHardwareLoops("disable-hexagon-hwloops",
+ cl::Hidden, cl::desc("Disable Hardware Loops for Hexagon target"));
-static cl::
-opt<bool> DisableHexagonMISched("disable-hexagon-misched",
- cl::Hidden, cl::ZeroOrMore, cl::init(false),
- cl::desc("Disable Hexagon MI Scheduling"));
+static cl::opt<bool> DisableHexagonMISched("disable-hexagon-misched",
+ cl::Hidden, cl::ZeroOrMore, cl::init(false),
+ cl::desc("Disable Hexagon MI Scheduling"));
static cl::opt<bool> DisableHexagonCFGOpt("disable-hexagon-cfgopt",
- cl::Hidden, cl::ZeroOrMore, cl::init(false),
- cl::desc("Disable Hexagon CFG Optimization"));
+ cl::Hidden, cl::ZeroOrMore, cl::init(false),
+ cl::desc("Disable Hexagon CFG Optimization"));
+
/// HexagonTargetMachineModule - Note that this is used on hosts that
/// cannot link in a library unless there are references into the
@@ -80,6 +79,7 @@ HexagonTargetMachine::HexagonTargetMachine(const Target &T, StringRef TT,
FrameLowering(Subtarget),
InstrItins(&Subtarget.getInstrItineraryData()) {
setMCUseCFI(false);
+ initAsmInfo();
}
// addPassesForOptimizations - Allow the backend (target) to add Target
@@ -126,55 +126,71 @@ TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) {
}
bool HexagonPassConfig::addInstSelector() {
+ const HexagonTargetMachine &TM = getHexagonTargetMachine();
+ bool NoOpt = (getOptLevel() == CodeGenOpt::None);
- if (getOptLevel() != CodeGenOpt::None)
- addPass(createHexagonRemoveExtendOps(getHexagonTargetMachine()));
+ if (!NoOpt)
+ addPass(createHexagonRemoveExtendArgs(TM));
- addPass(createHexagonISelDag(getHexagonTargetMachine(), getOptLevel()));
+ addPass(createHexagonISelDag(TM, getOptLevel()));
- if (getOptLevel() != CodeGenOpt::None)
+ if (!NoOpt) {
addPass(createHexagonPeephole());
+ printAndVerify("After hexagon peephole pass");
+ }
return false;
}
-
bool HexagonPassConfig::addPreRegAlloc() {
- if (!DisableHardwareLoops && getOptLevel() != CodeGenOpt::None)
- addPass(createHexagonHardwareLoops());
+ if (getOptLevel() != CodeGenOpt::None)
+ if (!DisableHardwareLoops)
+ addPass(createHexagonHardwareLoops());
return false;
}
bool HexagonPassConfig::addPostRegAlloc() {
- if (!DisableHexagonCFGOpt && getOptLevel() != CodeGenOpt::None)
- addPass(createHexagonCFGOptimizer(getHexagonTargetMachine()));
- return true;
+ const HexagonTargetMachine &TM = getHexagonTargetMachine();
+ if (getOptLevel() != CodeGenOpt::None)
+ if (!DisableHexagonCFGOpt)
+ addPass(createHexagonCFGOptimizer(TM));
+ return false;
}
-
bool HexagonPassConfig::addPreSched2() {
+ const HexagonTargetMachine &TM = getHexagonTargetMachine();
+ const HexagonTargetObjectFile &TLOF =
+ (const HexagonTargetObjectFile &)getTargetLowering()->getObjFileLowering();
+
+ addPass(createHexagonCopyToCombine());
if (getOptLevel() != CodeGenOpt::None)
addPass(&IfConverterID);
+ if (!TLOF.IsSmallDataEnabled()) {
+ addPass(createHexagonSplitConst32AndConst64(TM));
+ printAndVerify("After hexagon split const32/64 pass");
+ }
return true;
}
bool HexagonPassConfig::addPreEmitPass() {
+ const HexagonTargetMachine &TM = getHexagonTargetMachine();
+ bool NoOpt = (getOptLevel() == CodeGenOpt::None);
- if (!DisableHardwareLoops && getOptLevel() != CodeGenOpt::None)
- addPass(createHexagonFixupHwLoops());
-
- if (getOptLevel() != CodeGenOpt::None)
+ if (!NoOpt)
addPass(createHexagonNewValueJump());
// Expand Spill code for predicate registers.
- addPass(createHexagonExpandPredSpillCode(getHexagonTargetMachine()));
+ addPass(createHexagonExpandPredSpillCode(TM));
// Split up TFRcondsets into conditional transfers.
- addPass(createHexagonSplitTFRCondSets(getHexagonTargetMachine()));
+ addPass(createHexagonSplitTFRCondSets(TM));
// Create Packets.
- if (getOptLevel() != CodeGenOpt::None)
+ if (!NoOpt) {
+ if (!DisableHardwareLoops)
+ addPass(createHexagonFixupHwLoops());
addPass(createHexagonPacketizer());
+ }
return false;
}
diff --git a/lib/Target/Hexagon/HexagonTargetObjectFile.cpp b/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
index 993fcfa..7773cff 100644
--- a/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
+++ b/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
@@ -25,7 +25,8 @@
using namespace llvm;
static cl::opt<int> SmallDataThreshold("hexagon-small-data-threshold",
- cl::init(8), cl::Hidden);
+ cl::init(8), cl::Hidden,
+ cl::desc("The maximum size of an object in the sdata section"));
void HexagonTargetObjectFile::Initialize(MCContext &Ctx,
const TargetMachine &TM) {
@@ -46,6 +47,11 @@ void HexagonTargetObjectFile::Initialize(MCContext &Ctx,
static bool IsInSmallSection(uint64_t Size) {
return Size > 0 && Size <= (uint64_t)SmallDataThreshold;
}
+
+bool HexagonTargetObjectFile::IsSmallDataEnabled () const {
+ return SmallDataThreshold > 0;
+}
+
/// IsGlobalInSmallSection - Return true if this global value should be
/// placed into small data/bss section.
bool HexagonTargetObjectFile::IsGlobalInSmallSection(const GlobalValue *GV,
diff --git a/lib/Target/Hexagon/HexagonTargetObjectFile.h b/lib/Target/Hexagon/HexagonTargetObjectFile.h
index 6933450..41f6792 100644
--- a/lib/Target/Hexagon/HexagonTargetObjectFile.h
+++ b/lib/Target/Hexagon/HexagonTargetObjectFile.h
@@ -29,6 +29,7 @@ namespace llvm {
bool IsGlobalInSmallSection(const GlobalValue *GV,
const TargetMachine &TM) const;
+ bool IsSmallDataEnabled () const;
const MCSection* SelectSectionForGlobal(const GlobalValue *GV,
SectionKind Kind,
Mangler *Mang,
diff --git a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
index e592df9..41e382d 100644
--- a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
+++ b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
@@ -56,9 +56,6 @@ static cl::opt<bool> PacketizeVolatiles("hexagon-packetize-volatiles",
cl::ZeroOrMore, cl::Hidden, cl::init(true),
cl::desc("Allow non-solo packetization of volatile memory references"));
-extern cl::opt<bool> ScheduleInlineAsm;
-extern cl::opt<bool> CountDeadOutput;
-
namespace llvm {
void initializeHexagonPacketizerPass(PassRegistry&);
}
@@ -167,7 +164,6 @@ namespace {
unsigned, std::map <MachineInstr*, SUnit*>);
bool isNewifiable(MachineInstr* MI);
bool isCondInst(MachineInstr* MI);
- bool IsNewifyStore (MachineInstr* MI);
bool tryAllocateResourcesForConstExt(MachineInstr* MI);
bool canReserveResourcesForConstExt(MachineInstr *MI);
void reserveResourcesForConstExt(MachineInstr* MI);
@@ -180,6 +176,7 @@ INITIALIZE_PASS_BEGIN(HexagonPacketizer, "packets", "Hexagon Packetizer",
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
+INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
INITIALIZE_PASS_END(HexagonPacketizer, "packets", "Hexagon Packetizer",
false, false)
@@ -385,104 +382,6 @@ static bool IsControlFlow(MachineInstr* MI) {
return (MI->getDesc().isTerminator() || MI->getDesc().isCall());
}
-// Function returns true if an instruction can be promoted to the new-value
-// store. It will always return false for v2 and v3.
-// It lists all the conditional and unconditional stores that can be promoted
-// to the new-value stores.
-
-bool HexagonPacketizerList::IsNewifyStore (MachineInstr* MI) {
- const HexagonRegisterInfo* QRI =
- (const HexagonRegisterInfo *) TM.getRegisterInfo();
- switch (MI->getOpcode())
- {
- // store byte
- case Hexagon::STrib:
- case Hexagon::STrib_indexed:
- case Hexagon::STrib_indexed_shl_V4:
- case Hexagon::STrib_shl_V4:
- case Hexagon::STb_GP_V4:
- case Hexagon::POST_STbri:
- case Hexagon::STrib_cPt:
- case Hexagon::STrib_cdnPt_V4:
- case Hexagon::STrib_cNotPt:
- case Hexagon::STrib_cdnNotPt_V4:
- case Hexagon::STrib_indexed_cPt:
- case Hexagon::STrib_indexed_cdnPt_V4:
- case Hexagon::STrib_indexed_cNotPt:
- case Hexagon::STrib_indexed_cdnNotPt_V4:
- case Hexagon::STrib_indexed_shl_cPt_V4:
- case Hexagon::STrib_indexed_shl_cdnPt_V4:
- case Hexagon::STrib_indexed_shl_cNotPt_V4:
- case Hexagon::STrib_indexed_shl_cdnNotPt_V4:
- case Hexagon::POST_STbri_cPt:
- case Hexagon::POST_STbri_cdnPt_V4:
- case Hexagon::POST_STbri_cNotPt:
- case Hexagon::POST_STbri_cdnNotPt_V4:
- case Hexagon::STb_GP_cPt_V4:
- case Hexagon::STb_GP_cNotPt_V4:
- case Hexagon::STb_GP_cdnPt_V4:
- case Hexagon::STb_GP_cdnNotPt_V4:
-
- // store halfword
- case Hexagon::STrih:
- case Hexagon::STrih_indexed:
- case Hexagon::STrih_indexed_shl_V4:
- case Hexagon::STrih_shl_V4:
- case Hexagon::STh_GP_V4:
- case Hexagon::POST_SThri:
- case Hexagon::STrih_cPt:
- case Hexagon::STrih_cdnPt_V4:
- case Hexagon::STrih_cNotPt:
- case Hexagon::STrih_cdnNotPt_V4:
- case Hexagon::STrih_indexed_cPt:
- case Hexagon::STrih_indexed_cdnPt_V4:
- case Hexagon::STrih_indexed_cNotPt:
- case Hexagon::STrih_indexed_cdnNotPt_V4:
- case Hexagon::STrih_indexed_shl_cPt_V4:
- case Hexagon::STrih_indexed_shl_cdnPt_V4:
- case Hexagon::STrih_indexed_shl_cNotPt_V4:
- case Hexagon::STrih_indexed_shl_cdnNotPt_V4:
- case Hexagon::POST_SThri_cPt:
- case Hexagon::POST_SThri_cdnPt_V4:
- case Hexagon::POST_SThri_cNotPt:
- case Hexagon::POST_SThri_cdnNotPt_V4:
- case Hexagon::STh_GP_cPt_V4:
- case Hexagon::STh_GP_cNotPt_V4:
- case Hexagon::STh_GP_cdnPt_V4:
- case Hexagon::STh_GP_cdnNotPt_V4:
-
- // store word
- case Hexagon::STriw:
- case Hexagon::STriw_indexed:
- case Hexagon::STriw_indexed_shl_V4:
- case Hexagon::STriw_shl_V4:
- case Hexagon::STw_GP_V4:
- case Hexagon::POST_STwri:
- case Hexagon::STriw_cPt:
- case Hexagon::STriw_cdnPt_V4:
- case Hexagon::STriw_cNotPt:
- case Hexagon::STriw_cdnNotPt_V4:
- case Hexagon::STriw_indexed_cPt:
- case Hexagon::STriw_indexed_cdnPt_V4:
- case Hexagon::STriw_indexed_cNotPt:
- case Hexagon::STriw_indexed_cdnNotPt_V4:
- case Hexagon::STriw_indexed_shl_cPt_V4:
- case Hexagon::STriw_indexed_shl_cdnPt_V4:
- case Hexagon::STriw_indexed_shl_cNotPt_V4:
- case Hexagon::STriw_indexed_shl_cdnNotPt_V4:
- case Hexagon::POST_STwri_cPt:
- case Hexagon::POST_STwri_cdnPt_V4:
- case Hexagon::POST_STwri_cNotPt:
- case Hexagon::POST_STwri_cdnNotPt_V4:
- case Hexagon::STw_GP_cPt_V4:
- case Hexagon::STw_GP_cNotPt_V4:
- case Hexagon::STw_GP_cdnPt_V4:
- case Hexagon::STw_GP_cdnNotPt_V4:
- return QRI->Subtarget.hasV4TOps();
- }
- return false;
-}
-
static bool IsLoopN(MachineInstr *MI) {
return (MI->getOpcode() == Hexagon::LOOP0_i ||
MI->getOpcode() == Hexagon::LOOP0_r);
@@ -500,769 +399,11 @@ static bool DoesModifyCalleeSavedReg(MachineInstr *MI,
return false;
}
-// Return the new value instruction for a given store.
-static int GetDotNewOp(const int opc) {
- switch (opc) {
- default: llvm_unreachable("Unknown .new type");
- // store new value byte
- case Hexagon::STrib:
- return Hexagon::STrib_nv_V4;
-
- case Hexagon::STrib_indexed:
- return Hexagon::STrib_indexed_nv_V4;
-
- case Hexagon::STrib_indexed_shl_V4:
- return Hexagon::STrib_indexed_shl_nv_V4;
-
- case Hexagon::STrib_shl_V4:
- return Hexagon::STrib_shl_nv_V4;
-
- case Hexagon::STb_GP_V4:
- return Hexagon::STb_GP_nv_V4;
-
- case Hexagon::POST_STbri:
- return Hexagon::POST_STbri_nv_V4;
-
- case Hexagon::STrib_cPt:
- return Hexagon::STrib_cPt_nv_V4;
-
- case Hexagon::STrib_cdnPt_V4:
- return Hexagon::STrib_cdnPt_nv_V4;
-
- case Hexagon::STrib_cNotPt:
- return Hexagon::STrib_cNotPt_nv_V4;
-
- case Hexagon::STrib_cdnNotPt_V4:
- return Hexagon::STrib_cdnNotPt_nv_V4;
-
- case Hexagon::STrib_indexed_cPt:
- return Hexagon::STrib_indexed_cPt_nv_V4;
-
- case Hexagon::STrib_indexed_cdnPt_V4:
- return Hexagon::STrib_indexed_cdnPt_nv_V4;
-
- case Hexagon::STrib_indexed_cNotPt:
- return Hexagon::STrib_indexed_cNotPt_nv_V4;
-
- case Hexagon::STrib_indexed_cdnNotPt_V4:
- return Hexagon::STrib_indexed_cdnNotPt_nv_V4;
-
- case Hexagon::STrib_indexed_shl_cPt_V4:
- return Hexagon::STrib_indexed_shl_cPt_nv_V4;
-
- case Hexagon::STrib_indexed_shl_cdnPt_V4:
- return Hexagon::STrib_indexed_shl_cdnPt_nv_V4;
-
- case Hexagon::STrib_indexed_shl_cNotPt_V4:
- return Hexagon::STrib_indexed_shl_cNotPt_nv_V4;
-
- case Hexagon::STrib_indexed_shl_cdnNotPt_V4:
- return Hexagon::STrib_indexed_shl_cdnNotPt_nv_V4;
-
- case Hexagon::POST_STbri_cPt:
- return Hexagon::POST_STbri_cPt_nv_V4;
-
- case Hexagon::POST_STbri_cdnPt_V4:
- return Hexagon::POST_STbri_cdnPt_nv_V4;
-
- case Hexagon::POST_STbri_cNotPt:
- return Hexagon::POST_STbri_cNotPt_nv_V4;
-
- case Hexagon::POST_STbri_cdnNotPt_V4:
- return Hexagon::POST_STbri_cdnNotPt_nv_V4;
-
- case Hexagon::STb_GP_cPt_V4:
- return Hexagon::STb_GP_cPt_nv_V4;
-
- case Hexagon::STb_GP_cNotPt_V4:
- return Hexagon::STb_GP_cNotPt_nv_V4;
-
- case Hexagon::STb_GP_cdnPt_V4:
- return Hexagon::STb_GP_cdnPt_nv_V4;
-
- case Hexagon::STb_GP_cdnNotPt_V4:
- return Hexagon::STb_GP_cdnNotPt_nv_V4;
-
- // store new value halfword
- case Hexagon::STrih:
- return Hexagon::STrih_nv_V4;
-
- case Hexagon::STrih_indexed:
- return Hexagon::STrih_indexed_nv_V4;
-
- case Hexagon::STrih_indexed_shl_V4:
- return Hexagon::STrih_indexed_shl_nv_V4;
-
- case Hexagon::STrih_shl_V4:
- return Hexagon::STrih_shl_nv_V4;
-
- case Hexagon::STh_GP_V4:
- return Hexagon::STh_GP_nv_V4;
-
- case Hexagon::POST_SThri:
- return Hexagon::POST_SThri_nv_V4;
-
- case Hexagon::STrih_cPt:
- return Hexagon::STrih_cPt_nv_V4;
-
- case Hexagon::STrih_cdnPt_V4:
- return Hexagon::STrih_cdnPt_nv_V4;
-
- case Hexagon::STrih_cNotPt:
- return Hexagon::STrih_cNotPt_nv_V4;
-
- case Hexagon::STrih_cdnNotPt_V4:
- return Hexagon::STrih_cdnNotPt_nv_V4;
-
- case Hexagon::STrih_indexed_cPt:
- return Hexagon::STrih_indexed_cPt_nv_V4;
-
- case Hexagon::STrih_indexed_cdnPt_V4:
- return Hexagon::STrih_indexed_cdnPt_nv_V4;
-
- case Hexagon::STrih_indexed_cNotPt:
- return Hexagon::STrih_indexed_cNotPt_nv_V4;
-
- case Hexagon::STrih_indexed_cdnNotPt_V4:
- return Hexagon::STrih_indexed_cdnNotPt_nv_V4;
-
- case Hexagon::STrih_indexed_shl_cPt_V4:
- return Hexagon::STrih_indexed_shl_cPt_nv_V4;
-
- case Hexagon::STrih_indexed_shl_cdnPt_V4:
- return Hexagon::STrih_indexed_shl_cdnPt_nv_V4;
-
- case Hexagon::STrih_indexed_shl_cNotPt_V4:
- return Hexagon::STrih_indexed_shl_cNotPt_nv_V4;
-
- case Hexagon::STrih_indexed_shl_cdnNotPt_V4:
- return Hexagon::STrih_indexed_shl_cdnNotPt_nv_V4;
-
- case Hexagon::POST_SThri_cPt:
- return Hexagon::POST_SThri_cPt_nv_V4;
-
- case Hexagon::POST_SThri_cdnPt_V4:
- return Hexagon::POST_SThri_cdnPt_nv_V4;
-
- case Hexagon::POST_SThri_cNotPt:
- return Hexagon::POST_SThri_cNotPt_nv_V4;
-
- case Hexagon::POST_SThri_cdnNotPt_V4:
- return Hexagon::POST_SThri_cdnNotPt_nv_V4;
-
- case Hexagon::STh_GP_cPt_V4:
- return Hexagon::STh_GP_cPt_nv_V4;
-
- case Hexagon::STh_GP_cNotPt_V4:
- return Hexagon::STh_GP_cNotPt_nv_V4;
-
- case Hexagon::STh_GP_cdnPt_V4:
- return Hexagon::STh_GP_cdnPt_nv_V4;
-
- case Hexagon::STh_GP_cdnNotPt_V4:
- return Hexagon::STh_GP_cdnNotPt_nv_V4;
-
- // store new value word
- case Hexagon::STriw:
- return Hexagon::STriw_nv_V4;
-
- case Hexagon::STriw_indexed:
- return Hexagon::STriw_indexed_nv_V4;
-
- case Hexagon::STriw_indexed_shl_V4:
- return Hexagon::STriw_indexed_shl_nv_V4;
-
- case Hexagon::STriw_shl_V4:
- return Hexagon::STriw_shl_nv_V4;
-
- case Hexagon::STw_GP_V4:
- return Hexagon::STw_GP_nv_V4;
-
- case Hexagon::POST_STwri:
- return Hexagon::POST_STwri_nv_V4;
-
- case Hexagon::STriw_cPt:
- return Hexagon::STriw_cPt_nv_V4;
-
- case Hexagon::STriw_cdnPt_V4:
- return Hexagon::STriw_cdnPt_nv_V4;
-
- case Hexagon::STriw_cNotPt:
- return Hexagon::STriw_cNotPt_nv_V4;
-
- case Hexagon::STriw_cdnNotPt_V4:
- return Hexagon::STriw_cdnNotPt_nv_V4;
-
- case Hexagon::STriw_indexed_cPt:
- return Hexagon::STriw_indexed_cPt_nv_V4;
-
- case Hexagon::STriw_indexed_cdnPt_V4:
- return Hexagon::STriw_indexed_cdnPt_nv_V4;
-
- case Hexagon::STriw_indexed_cNotPt:
- return Hexagon::STriw_indexed_cNotPt_nv_V4;
-
- case Hexagon::STriw_indexed_cdnNotPt_V4:
- return Hexagon::STriw_indexed_cdnNotPt_nv_V4;
-
- case Hexagon::STriw_indexed_shl_cPt_V4:
- return Hexagon::STriw_indexed_shl_cPt_nv_V4;
-
- case Hexagon::STriw_indexed_shl_cdnPt_V4:
- return Hexagon::STriw_indexed_shl_cdnPt_nv_V4;
-
- case Hexagon::STriw_indexed_shl_cNotPt_V4:
- return Hexagon::STriw_indexed_shl_cNotPt_nv_V4;
-
- case Hexagon::STriw_indexed_shl_cdnNotPt_V4:
- return Hexagon::STriw_indexed_shl_cdnNotPt_nv_V4;
-
- case Hexagon::POST_STwri_cPt:
- return Hexagon::POST_STwri_cPt_nv_V4;
-
- case Hexagon::POST_STwri_cdnPt_V4:
- return Hexagon::POST_STwri_cdnPt_nv_V4;
-
- case Hexagon::POST_STwri_cNotPt:
- return Hexagon::POST_STwri_cNotPt_nv_V4;
-
- case Hexagon::POST_STwri_cdnNotPt_V4:
- return Hexagon::POST_STwri_cdnNotPt_nv_V4;
-
- case Hexagon::STw_GP_cPt_V4:
- return Hexagon::STw_GP_cPt_nv_V4;
-
- case Hexagon::STw_GP_cNotPt_V4:
- return Hexagon::STw_GP_cNotPt_nv_V4;
-
- case Hexagon::STw_GP_cdnPt_V4:
- return Hexagon::STw_GP_cdnPt_nv_V4;
-
- case Hexagon::STw_GP_cdnNotPt_V4:
- return Hexagon::STw_GP_cdnNotPt_nv_V4;
-
- }
-}
-
-// Return .new predicate version for an instruction
-static int GetDotNewPredOp(MachineInstr *MI,
- const MachineBranchProbabilityInfo *MBPI,
- const HexagonInstrInfo *QII) {
- switch (MI->getOpcode()) {
- default: llvm_unreachable("Unknown .new type");
- // Conditional stores
- // Store byte conditionally
- case Hexagon::STrib_cPt :
- return Hexagon::STrib_cdnPt_V4;
-
- case Hexagon::STrib_cNotPt :
- return Hexagon::STrib_cdnNotPt_V4;
-
- case Hexagon::STrib_indexed_cPt :
- return Hexagon::STrib_indexed_cdnPt_V4;
-
- case Hexagon::STrib_indexed_cNotPt :
- return Hexagon::STrib_indexed_cdnNotPt_V4;
-
- case Hexagon::STrib_imm_cPt_V4 :
- return Hexagon::STrib_imm_cdnPt_V4;
-
- case Hexagon::STrib_imm_cNotPt_V4 :
- return Hexagon::STrib_imm_cdnNotPt_V4;
-
- case Hexagon::POST_STbri_cPt :
- return Hexagon::POST_STbri_cdnPt_V4;
-
- case Hexagon::POST_STbri_cNotPt :
- return Hexagon::POST_STbri_cdnNotPt_V4;
-
- case Hexagon::STrib_indexed_shl_cPt_V4 :
- return Hexagon::STrib_indexed_shl_cdnPt_V4;
-
- case Hexagon::STrib_indexed_shl_cNotPt_V4 :
- return Hexagon::STrib_indexed_shl_cdnNotPt_V4;
-
- case Hexagon::STb_GP_cPt_V4 :
- return Hexagon::STb_GP_cdnPt_V4;
-
- case Hexagon::STb_GP_cNotPt_V4 :
- return Hexagon::STb_GP_cdnNotPt_V4;
-
- // Store doubleword conditionally
- case Hexagon::STrid_cPt :
- return Hexagon::STrid_cdnPt_V4;
-
- case Hexagon::STrid_cNotPt :
- return Hexagon::STrid_cdnNotPt_V4;
-
- case Hexagon::STrid_indexed_cPt :
- return Hexagon::STrid_indexed_cdnPt_V4;
-
- case Hexagon::STrid_indexed_cNotPt :
- return Hexagon::STrid_indexed_cdnNotPt_V4;
-
- case Hexagon::STrid_indexed_shl_cPt_V4 :
- return Hexagon::STrid_indexed_shl_cdnPt_V4;
-
- case Hexagon::STrid_indexed_shl_cNotPt_V4 :
- return Hexagon::STrid_indexed_shl_cdnNotPt_V4;
-
- case Hexagon::POST_STdri_cPt :
- return Hexagon::POST_STdri_cdnPt_V4;
-
- case Hexagon::POST_STdri_cNotPt :
- return Hexagon::POST_STdri_cdnNotPt_V4;
-
- case Hexagon::STd_GP_cPt_V4 :
- return Hexagon::STd_GP_cdnPt_V4;
-
- case Hexagon::STd_GP_cNotPt_V4 :
- return Hexagon::STd_GP_cdnNotPt_V4;
-
- // Store halfword conditionally
- case Hexagon::STrih_cPt :
- return Hexagon::STrih_cdnPt_V4;
-
- case Hexagon::STrih_cNotPt :
- return Hexagon::STrih_cdnNotPt_V4;
-
- case Hexagon::STrih_indexed_cPt :
- return Hexagon::STrih_indexed_cdnPt_V4;
-
- case Hexagon::STrih_indexed_cNotPt :
- return Hexagon::STrih_indexed_cdnNotPt_V4;
-
- case Hexagon::STrih_imm_cPt_V4 :
- return Hexagon::STrih_imm_cdnPt_V4;
-
- case Hexagon::STrih_imm_cNotPt_V4 :
- return Hexagon::STrih_imm_cdnNotPt_V4;
-
- case Hexagon::STrih_indexed_shl_cPt_V4 :
- return Hexagon::STrih_indexed_shl_cdnPt_V4;
-
- case Hexagon::STrih_indexed_shl_cNotPt_V4 :
- return Hexagon::STrih_indexed_shl_cdnNotPt_V4;
-
- case Hexagon::POST_SThri_cPt :
- return Hexagon::POST_SThri_cdnPt_V4;
-
- case Hexagon::POST_SThri_cNotPt :
- return Hexagon::POST_SThri_cdnNotPt_V4;
-
- case Hexagon::STh_GP_cPt_V4 :
- return Hexagon::STh_GP_cdnPt_V4;
-
- case Hexagon::STh_GP_cNotPt_V4 :
- return Hexagon::STh_GP_cdnNotPt_V4;
-
- // Store word conditionally
- case Hexagon::STriw_cPt :
- return Hexagon::STriw_cdnPt_V4;
-
- case Hexagon::STriw_cNotPt :
- return Hexagon::STriw_cdnNotPt_V4;
-
- case Hexagon::STriw_indexed_cPt :
- return Hexagon::STriw_indexed_cdnPt_V4;
-
- case Hexagon::STriw_indexed_cNotPt :
- return Hexagon::STriw_indexed_cdnNotPt_V4;
-
- case Hexagon::STriw_imm_cPt_V4 :
- return Hexagon::STriw_imm_cdnPt_V4;
-
- case Hexagon::STriw_imm_cNotPt_V4 :
- return Hexagon::STriw_imm_cdnNotPt_V4;
-
- case Hexagon::STriw_indexed_shl_cPt_V4 :
- return Hexagon::STriw_indexed_shl_cdnPt_V4;
-
- case Hexagon::STriw_indexed_shl_cNotPt_V4 :
- return Hexagon::STriw_indexed_shl_cdnNotPt_V4;
-
- case Hexagon::POST_STwri_cPt :
- return Hexagon::POST_STwri_cdnPt_V4;
-
- case Hexagon::POST_STwri_cNotPt :
- return Hexagon::POST_STwri_cdnNotPt_V4;
-
- case Hexagon::STw_GP_cPt_V4 :
- return Hexagon::STw_GP_cdnPt_V4;
-
- case Hexagon::STw_GP_cNotPt_V4 :
- return Hexagon::STw_GP_cdnNotPt_V4;
-
- // Condtional Jumps
- case Hexagon::JMP_t:
- case Hexagon::JMP_f:
- return QII->getDotNewPredJumpOp(MI, MBPI);
-
- case Hexagon::JMPR_t:
- return Hexagon::JMPR_tnew_tV3;
-
- case Hexagon::JMPR_f:
- return Hexagon::JMPR_fnew_tV3;
-
- // Conditional Transfers
- case Hexagon::TFR_cPt:
- return Hexagon::TFR_cdnPt;
-
- case Hexagon::TFR_cNotPt:
- return Hexagon::TFR_cdnNotPt;
-
- case Hexagon::TFRI_cPt:
- return Hexagon::TFRI_cdnPt;
-
- case Hexagon::TFRI_cNotPt:
- return Hexagon::TFRI_cdnNotPt;
-
- // Load double word
- case Hexagon::LDrid_cPt :
- return Hexagon::LDrid_cdnPt;
-
- case Hexagon::LDrid_cNotPt :
- return Hexagon::LDrid_cdnNotPt;
-
- case Hexagon::LDrid_indexed_cPt :
- return Hexagon::LDrid_indexed_cdnPt;
-
- case Hexagon::LDrid_indexed_cNotPt :
- return Hexagon::LDrid_indexed_cdnNotPt;
-
- case Hexagon::POST_LDrid_cPt :
- return Hexagon::POST_LDrid_cdnPt_V4;
-
- case Hexagon::POST_LDrid_cNotPt :
- return Hexagon::POST_LDrid_cdnNotPt_V4;
-
- // Load word
- case Hexagon::LDriw_cPt :
- return Hexagon::LDriw_cdnPt;
-
- case Hexagon::LDriw_cNotPt :
- return Hexagon::LDriw_cdnNotPt;
-
- case Hexagon::LDriw_indexed_cPt :
- return Hexagon::LDriw_indexed_cdnPt;
-
- case Hexagon::LDriw_indexed_cNotPt :
- return Hexagon::LDriw_indexed_cdnNotPt;
-
- case Hexagon::POST_LDriw_cPt :
- return Hexagon::POST_LDriw_cdnPt_V4;
-
- case Hexagon::POST_LDriw_cNotPt :
- return Hexagon::POST_LDriw_cdnNotPt_V4;
-
- // Load halfword
- case Hexagon::LDrih_cPt :
- return Hexagon::LDrih_cdnPt;
-
- case Hexagon::LDrih_cNotPt :
- return Hexagon::LDrih_cdnNotPt;
-
- case Hexagon::LDrih_indexed_cPt :
- return Hexagon::LDrih_indexed_cdnPt;
-
- case Hexagon::LDrih_indexed_cNotPt :
- return Hexagon::LDrih_indexed_cdnNotPt;
-
- case Hexagon::POST_LDrih_cPt :
- return Hexagon::POST_LDrih_cdnPt_V4;
-
- case Hexagon::POST_LDrih_cNotPt :
- return Hexagon::POST_LDrih_cdnNotPt_V4;
-
- // Load byte
- case Hexagon::LDrib_cPt :
- return Hexagon::LDrib_cdnPt;
-
- case Hexagon::LDrib_cNotPt :
- return Hexagon::LDrib_cdnNotPt;
-
- case Hexagon::LDrib_indexed_cPt :
- return Hexagon::LDrib_indexed_cdnPt;
-
- case Hexagon::LDrib_indexed_cNotPt :
- return Hexagon::LDrib_indexed_cdnNotPt;
-
- case Hexagon::POST_LDrib_cPt :
- return Hexagon::POST_LDrib_cdnPt_V4;
-
- case Hexagon::POST_LDrib_cNotPt :
- return Hexagon::POST_LDrib_cdnNotPt_V4;
-
- // Load unsigned halfword
- case Hexagon::LDriuh_cPt :
- return Hexagon::LDriuh_cdnPt;
-
- case Hexagon::LDriuh_cNotPt :
- return Hexagon::LDriuh_cdnNotPt;
-
- case Hexagon::LDriuh_indexed_cPt :
- return Hexagon::LDriuh_indexed_cdnPt;
-
- case Hexagon::LDriuh_indexed_cNotPt :
- return Hexagon::LDriuh_indexed_cdnNotPt;
-
- case Hexagon::POST_LDriuh_cPt :
- return Hexagon::POST_LDriuh_cdnPt_V4;
-
- case Hexagon::POST_LDriuh_cNotPt :
- return Hexagon::POST_LDriuh_cdnNotPt_V4;
-
- // Load unsigned byte
- case Hexagon::LDriub_cPt :
- return Hexagon::LDriub_cdnPt;
-
- case Hexagon::LDriub_cNotPt :
- return Hexagon::LDriub_cdnNotPt;
-
- case Hexagon::LDriub_indexed_cPt :
- return Hexagon::LDriub_indexed_cdnPt;
-
- case Hexagon::LDriub_indexed_cNotPt :
- return Hexagon::LDriub_indexed_cdnNotPt;
-
- case Hexagon::POST_LDriub_cPt :
- return Hexagon::POST_LDriub_cdnPt_V4;
-
- case Hexagon::POST_LDriub_cNotPt :
- return Hexagon::POST_LDriub_cdnNotPt_V4;
-
- // V4 indexed+scaled load
-
- case Hexagon::LDrid_indexed_shl_cPt_V4 :
- return Hexagon::LDrid_indexed_shl_cdnPt_V4;
-
- case Hexagon::LDrid_indexed_shl_cNotPt_V4 :
- return Hexagon::LDrid_indexed_shl_cdnNotPt_V4;
-
- case Hexagon::LDrib_indexed_shl_cPt_V4 :
- return Hexagon::LDrib_indexed_shl_cdnPt_V4;
-
- case Hexagon::LDrib_indexed_shl_cNotPt_V4 :
- return Hexagon::LDrib_indexed_shl_cdnNotPt_V4;
-
- case Hexagon::LDriub_indexed_shl_cPt_V4 :
- return Hexagon::LDriub_indexed_shl_cdnPt_V4;
-
- case Hexagon::LDriub_indexed_shl_cNotPt_V4 :
- return Hexagon::LDriub_indexed_shl_cdnNotPt_V4;
-
- case Hexagon::LDrih_indexed_shl_cPt_V4 :
- return Hexagon::LDrih_indexed_shl_cdnPt_V4;
-
- case Hexagon::LDrih_indexed_shl_cNotPt_V4 :
- return Hexagon::LDrih_indexed_shl_cdnNotPt_V4;
-
- case Hexagon::LDriuh_indexed_shl_cPt_V4 :
- return Hexagon::LDriuh_indexed_shl_cdnPt_V4;
-
- case Hexagon::LDriuh_indexed_shl_cNotPt_V4 :
- return Hexagon::LDriuh_indexed_shl_cdnNotPt_V4;
-
- case Hexagon::LDriw_indexed_shl_cPt_V4 :
- return Hexagon::LDriw_indexed_shl_cdnPt_V4;
-
- case Hexagon::LDriw_indexed_shl_cNotPt_V4 :
- return Hexagon::LDriw_indexed_shl_cdnNotPt_V4;
-
- // V4 global address load
-
- case Hexagon::LDd_GP_cPt_V4:
- return Hexagon::LDd_GP_cdnPt_V4;
-
- case Hexagon::LDd_GP_cNotPt_V4:
- return Hexagon::LDd_GP_cdnNotPt_V4;
-
- case Hexagon::LDb_GP_cPt_V4:
- return Hexagon::LDb_GP_cdnPt_V4;
-
- case Hexagon::LDb_GP_cNotPt_V4:
- return Hexagon::LDb_GP_cdnNotPt_V4;
-
- case Hexagon::LDub_GP_cPt_V4:
- return Hexagon::LDub_GP_cdnPt_V4;
-
- case Hexagon::LDub_GP_cNotPt_V4:
- return Hexagon::LDub_GP_cdnNotPt_V4;
-
- case Hexagon::LDh_GP_cPt_V4:
- return Hexagon::LDh_GP_cdnPt_V4;
-
- case Hexagon::LDh_GP_cNotPt_V4:
- return Hexagon::LDh_GP_cdnNotPt_V4;
-
- case Hexagon::LDuh_GP_cPt_V4:
- return Hexagon::LDuh_GP_cdnPt_V4;
-
- case Hexagon::LDuh_GP_cNotPt_V4:
- return Hexagon::LDuh_GP_cdnNotPt_V4;
-
- case Hexagon::LDw_GP_cPt_V4:
- return Hexagon::LDw_GP_cdnPt_V4;
-
- case Hexagon::LDw_GP_cNotPt_V4:
- return Hexagon::LDw_GP_cdnNotPt_V4;
-
- // Conditional store new-value byte
- case Hexagon::STrib_cPt_nv_V4 :
- return Hexagon::STrib_cdnPt_nv_V4;
- case Hexagon::STrib_cNotPt_nv_V4 :
- return Hexagon::STrib_cdnNotPt_nv_V4;
-
- case Hexagon::STrib_indexed_cPt_nv_V4 :
- return Hexagon::STrib_indexed_cdnPt_nv_V4;
- case Hexagon::STrib_indexed_cNotPt_nv_V4 :
- return Hexagon::STrib_indexed_cdnNotPt_nv_V4;
-
- case Hexagon::STrib_indexed_shl_cPt_nv_V4 :
- return Hexagon::STrib_indexed_shl_cdnPt_nv_V4;
- case Hexagon::STrib_indexed_shl_cNotPt_nv_V4 :
- return Hexagon::STrib_indexed_shl_cdnNotPt_nv_V4;
-
- case Hexagon::POST_STbri_cPt_nv_V4 :
- return Hexagon::POST_STbri_cdnPt_nv_V4;
- case Hexagon::POST_STbri_cNotPt_nv_V4 :
- return Hexagon::POST_STbri_cdnNotPt_nv_V4;
-
- case Hexagon::STb_GP_cPt_nv_V4 :
- return Hexagon::STb_GP_cdnPt_nv_V4;
-
- case Hexagon::STb_GP_cNotPt_nv_V4 :
- return Hexagon::STb_GP_cdnNotPt_nv_V4;
-
- // Conditional store new-value halfword
- case Hexagon::STrih_cPt_nv_V4 :
- return Hexagon::STrih_cdnPt_nv_V4;
- case Hexagon::STrih_cNotPt_nv_V4 :
- return Hexagon::STrih_cdnNotPt_nv_V4;
-
- case Hexagon::STrih_indexed_cPt_nv_V4 :
- return Hexagon::STrih_indexed_cdnPt_nv_V4;
- case Hexagon::STrih_indexed_cNotPt_nv_V4 :
- return Hexagon::STrih_indexed_cdnNotPt_nv_V4;
-
- case Hexagon::STrih_indexed_shl_cPt_nv_V4 :
- return Hexagon::STrih_indexed_shl_cdnPt_nv_V4;
- case Hexagon::STrih_indexed_shl_cNotPt_nv_V4 :
- return Hexagon::STrih_indexed_shl_cdnNotPt_nv_V4;
-
- case Hexagon::POST_SThri_cPt_nv_V4 :
- return Hexagon::POST_SThri_cdnPt_nv_V4;
- case Hexagon::POST_SThri_cNotPt_nv_V4 :
- return Hexagon::POST_SThri_cdnNotPt_nv_V4;
-
- case Hexagon::STh_GP_cPt_nv_V4 :
- return Hexagon::STh_GP_cdnPt_nv_V4;
-
- case Hexagon::STh_GP_cNotPt_nv_V4 :
- return Hexagon::STh_GP_cdnNotPt_nv_V4;
-
- // Conditional store new-value word
- case Hexagon::STriw_cPt_nv_V4 :
- return Hexagon::STriw_cdnPt_nv_V4;
- case Hexagon::STriw_cNotPt_nv_V4 :
- return Hexagon::STriw_cdnNotPt_nv_V4;
-
- case Hexagon::STriw_indexed_cPt_nv_V4 :
- return Hexagon::STriw_indexed_cdnPt_nv_V4;
- case Hexagon::STriw_indexed_cNotPt_nv_V4 :
- return Hexagon::STriw_indexed_cdnNotPt_nv_V4;
-
- case Hexagon::STriw_indexed_shl_cPt_nv_V4 :
- return Hexagon::STriw_indexed_shl_cdnPt_nv_V4;
- case Hexagon::STriw_indexed_shl_cNotPt_nv_V4 :
- return Hexagon::STriw_indexed_shl_cdnNotPt_nv_V4;
-
- case Hexagon::POST_STwri_cPt_nv_V4 :
- return Hexagon::POST_STwri_cdnPt_nv_V4;
- case Hexagon::POST_STwri_cNotPt_nv_V4:
- return Hexagon::POST_STwri_cdnNotPt_nv_V4;
-
- case Hexagon::STw_GP_cPt_nv_V4 :
- return Hexagon::STw_GP_cdnPt_nv_V4;
-
- case Hexagon::STw_GP_cNotPt_nv_V4 :
- return Hexagon::STw_GP_cdnNotPt_nv_V4;
-
- // Conditional add
- case Hexagon::ADD_ri_cPt :
- return Hexagon::ADD_ri_cdnPt;
- case Hexagon::ADD_ri_cNotPt :
- return Hexagon::ADD_ri_cdnNotPt;
-
- case Hexagon::ADD_rr_cPt :
- return Hexagon::ADD_rr_cdnPt;
- case Hexagon::ADD_rr_cNotPt :
- return Hexagon::ADD_rr_cdnNotPt;
-
- // Conditional logical Operations
- case Hexagon::XOR_rr_cPt :
- return Hexagon::XOR_rr_cdnPt;
- case Hexagon::XOR_rr_cNotPt :
- return Hexagon::XOR_rr_cdnNotPt;
-
- case Hexagon::AND_rr_cPt :
- return Hexagon::AND_rr_cdnPt;
- case Hexagon::AND_rr_cNotPt :
- return Hexagon::AND_rr_cdnNotPt;
-
- case Hexagon::OR_rr_cPt :
- return Hexagon::OR_rr_cdnPt;
- case Hexagon::OR_rr_cNotPt :
- return Hexagon::OR_rr_cdnNotPt;
-
- // Conditional Subtract
- case Hexagon::SUB_rr_cPt :
- return Hexagon::SUB_rr_cdnPt;
- case Hexagon::SUB_rr_cNotPt :
- return Hexagon::SUB_rr_cdnNotPt;
-
- // Conditional combine
- case Hexagon::COMBINE_rr_cPt :
- return Hexagon::COMBINE_rr_cdnPt;
- case Hexagon::COMBINE_rr_cNotPt :
- return Hexagon::COMBINE_rr_cdnNotPt;
-
- case Hexagon::ASLH_cPt_V4 :
- return Hexagon::ASLH_cdnPt_V4;
- case Hexagon::ASLH_cNotPt_V4 :
- return Hexagon::ASLH_cdnNotPt_V4;
-
- case Hexagon::ASRH_cPt_V4 :
- return Hexagon::ASRH_cdnPt_V4;
- case Hexagon::ASRH_cNotPt_V4 :
- return Hexagon::ASRH_cdnNotPt_V4;
-
- case Hexagon::SXTB_cPt_V4 :
- return Hexagon::SXTB_cdnPt_V4;
- case Hexagon::SXTB_cNotPt_V4 :
- return Hexagon::SXTB_cdnNotPt_V4;
-
- case Hexagon::SXTH_cPt_V4 :
- return Hexagon::SXTH_cdnPt_V4;
- case Hexagon::SXTH_cNotPt_V4 :
- return Hexagon::SXTH_cdnNotPt_V4;
-
- case Hexagon::ZXTB_cPt_V4 :
- return Hexagon::ZXTB_cdnPt_V4;
- case Hexagon::ZXTB_cNotPt_V4 :
- return Hexagon::ZXTB_cdnNotPt_V4;
-
- case Hexagon::ZXTH_cPt_V4 :
- return Hexagon::ZXTH_cdnPt_V4;
- case Hexagon::ZXTH_cNotPt_V4 :
- return Hexagon::ZXTH_cdnNotPt_V4;
- }
-}
-
// Returns true if an instruction can be promoted to .new predicate
// or new-value store.
bool HexagonPacketizerList::isNewifiable(MachineInstr* MI) {
- if ( isCondInst(MI) || IsNewifyStore(MI))
+ const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
+ if ( isCondInst(MI) || QII->mayBeNewStore(MI))
return true;
else
return false;
@@ -1296,896 +437,38 @@ bool HexagonPacketizerList::PromoteToDotNew(MachineInstr* MI,
int NewOpcode;
if (RC == &Hexagon::PredRegsRegClass)
- NewOpcode = GetDotNewPredOp(MI, MBPI, QII);
+ NewOpcode = QII->GetDotNewPredOp(MI, MBPI);
else
- NewOpcode = GetDotNewOp(MI->getOpcode());
+ NewOpcode = QII->GetDotNewOp(MI);
MI->setDesc(QII->get(NewOpcode));
return true;
}
-// Returns the most basic instruction for the .new predicated instructions and
-// new-value stores.
-// For example, all of the following instructions will be converted back to the
-// same instruction:
-// 1) if (p0.new) memw(R0+#0) = R1.new --->
-// 2) if (p0) memw(R0+#0)= R1.new -------> if (p0) memw(R0+#0) = R1
-// 3) if (p0.new) memw(R0+#0) = R1 --->
-//
-// To understand the translation of instruction 1 to its original form, consider
-// a packet with 3 instructions.
-// { p0 = cmp.eq(R0,R1)
-// if (p0.new) R2 = add(R3, R4)
-// R5 = add (R3, R1)
-// }
-// if (p0) memw(R5+#0) = R2 <--- trying to include it in the previous packet
-//
-// This instruction can be part of the previous packet only if both p0 and R2
-// are promoted to .new values. This promotion happens in steps, first
-// predicate register is promoted to .new and in the next iteration R2 is
-// promoted. Therefore, in case of dependence check failure (due to R5) during
-// next iteration, it should be converted back to its most basic form.
-
-static int GetDotOldOp(const int opc) {
- switch (opc) {
- default: llvm_unreachable("Unknown .old type");
- case Hexagon::TFR_cdnPt:
- return Hexagon::TFR_cPt;
-
- case Hexagon::TFR_cdnNotPt:
- return Hexagon::TFR_cNotPt;
-
- case Hexagon::TFRI_cdnPt:
- return Hexagon::TFRI_cPt;
-
- case Hexagon::TFRI_cdnNotPt:
- return Hexagon::TFRI_cNotPt;
-
- case Hexagon::JMP_tnew_t:
- return Hexagon::JMP_t;
-
- case Hexagon::JMP_fnew_t:
- return Hexagon::JMP_f;
-
- case Hexagon::JMPR_tnew_tV3:
- return Hexagon::JMPR_t;
-
- case Hexagon::JMPR_fnew_tV3:
- return Hexagon::JMPR_f;
-
- // Load double word
-
- case Hexagon::LDrid_cdnPt :
- return Hexagon::LDrid_cPt;
-
- case Hexagon::LDrid_cdnNotPt :
- return Hexagon::LDrid_cNotPt;
-
- case Hexagon::LDrid_indexed_cdnPt :
- return Hexagon::LDrid_indexed_cPt;
-
- case Hexagon::LDrid_indexed_cdnNotPt :
- return Hexagon::LDrid_indexed_cNotPt;
-
- case Hexagon::POST_LDrid_cdnPt_V4 :
- return Hexagon::POST_LDrid_cPt;
-
- case Hexagon::POST_LDrid_cdnNotPt_V4 :
- return Hexagon::POST_LDrid_cNotPt;
-
- // Load word
-
- case Hexagon::LDriw_cdnPt :
- return Hexagon::LDriw_cPt;
-
- case Hexagon::LDriw_cdnNotPt :
- return Hexagon::LDriw_cNotPt;
-
- case Hexagon::LDriw_indexed_cdnPt :
- return Hexagon::LDriw_indexed_cPt;
-
- case Hexagon::LDriw_indexed_cdnNotPt :
- return Hexagon::LDriw_indexed_cNotPt;
-
- case Hexagon::POST_LDriw_cdnPt_V4 :
- return Hexagon::POST_LDriw_cPt;
-
- case Hexagon::POST_LDriw_cdnNotPt_V4 :
- return Hexagon::POST_LDriw_cNotPt;
-
- // Load half
-
- case Hexagon::LDrih_cdnPt :
- return Hexagon::LDrih_cPt;
-
- case Hexagon::LDrih_cdnNotPt :
- return Hexagon::LDrih_cNotPt;
-
- case Hexagon::LDrih_indexed_cdnPt :
- return Hexagon::LDrih_indexed_cPt;
-
- case Hexagon::LDrih_indexed_cdnNotPt :
- return Hexagon::LDrih_indexed_cNotPt;
-
- case Hexagon::POST_LDrih_cdnPt_V4 :
- return Hexagon::POST_LDrih_cPt;
-
- case Hexagon::POST_LDrih_cdnNotPt_V4 :
- return Hexagon::POST_LDrih_cNotPt;
-
- // Load byte
-
- case Hexagon::LDrib_cdnPt :
- return Hexagon::LDrib_cPt;
-
- case Hexagon::LDrib_cdnNotPt :
- return Hexagon::LDrib_cNotPt;
-
- case Hexagon::LDrib_indexed_cdnPt :
- return Hexagon::LDrib_indexed_cPt;
-
- case Hexagon::LDrib_indexed_cdnNotPt :
- return Hexagon::LDrib_indexed_cNotPt;
-
- case Hexagon::POST_LDrib_cdnPt_V4 :
- return Hexagon::POST_LDrib_cPt;
-
- case Hexagon::POST_LDrib_cdnNotPt_V4 :
- return Hexagon::POST_LDrib_cNotPt;
-
- // Load unsigned half
-
- case Hexagon::LDriuh_cdnPt :
- return Hexagon::LDriuh_cPt;
-
- case Hexagon::LDriuh_cdnNotPt :
- return Hexagon::LDriuh_cNotPt;
-
- case Hexagon::LDriuh_indexed_cdnPt :
- return Hexagon::LDriuh_indexed_cPt;
-
- case Hexagon::LDriuh_indexed_cdnNotPt :
- return Hexagon::LDriuh_indexed_cNotPt;
-
- case Hexagon::POST_LDriuh_cdnPt_V4 :
- return Hexagon::POST_LDriuh_cPt;
-
- case Hexagon::POST_LDriuh_cdnNotPt_V4 :
- return Hexagon::POST_LDriuh_cNotPt;
-
- // Load unsigned byte
- case Hexagon::LDriub_cdnPt :
- return Hexagon::LDriub_cPt;
-
- case Hexagon::LDriub_cdnNotPt :
- return Hexagon::LDriub_cNotPt;
-
- case Hexagon::LDriub_indexed_cdnPt :
- return Hexagon::LDriub_indexed_cPt;
-
- case Hexagon::LDriub_indexed_cdnNotPt :
- return Hexagon::LDriub_indexed_cNotPt;
-
- case Hexagon::POST_LDriub_cdnPt_V4 :
- return Hexagon::POST_LDriub_cPt;
-
- case Hexagon::POST_LDriub_cdnNotPt_V4 :
- return Hexagon::POST_LDriub_cNotPt;
-
- // V4 indexed+scaled Load
-
- case Hexagon::LDrid_indexed_shl_cdnPt_V4 :
- return Hexagon::LDrid_indexed_shl_cPt_V4;
-
- case Hexagon::LDrid_indexed_shl_cdnNotPt_V4 :
- return Hexagon::LDrid_indexed_shl_cNotPt_V4;
-
- case Hexagon::LDrib_indexed_shl_cdnPt_V4 :
- return Hexagon::LDrib_indexed_shl_cPt_V4;
-
- case Hexagon::LDrib_indexed_shl_cdnNotPt_V4 :
- return Hexagon::LDrib_indexed_shl_cNotPt_V4;
-
- case Hexagon::LDriub_indexed_shl_cdnPt_V4 :
- return Hexagon::LDriub_indexed_shl_cPt_V4;
-
- case Hexagon::LDriub_indexed_shl_cdnNotPt_V4 :
- return Hexagon::LDriub_indexed_shl_cNotPt_V4;
-
- case Hexagon::LDrih_indexed_shl_cdnPt_V4 :
- return Hexagon::LDrih_indexed_shl_cPt_V4;
-
- case Hexagon::LDrih_indexed_shl_cdnNotPt_V4 :
- return Hexagon::LDrih_indexed_shl_cNotPt_V4;
-
- case Hexagon::LDriuh_indexed_shl_cdnPt_V4 :
- return Hexagon::LDriuh_indexed_shl_cPt_V4;
-
- case Hexagon::LDriuh_indexed_shl_cdnNotPt_V4 :
- return Hexagon::LDriuh_indexed_shl_cNotPt_V4;
-
- case Hexagon::LDriw_indexed_shl_cdnPt_V4 :
- return Hexagon::LDriw_indexed_shl_cPt_V4;
-
- case Hexagon::LDriw_indexed_shl_cdnNotPt_V4 :
- return Hexagon::LDriw_indexed_shl_cNotPt_V4;
-
- // V4 global address load
-
- case Hexagon::LDd_GP_cdnPt_V4:
- return Hexagon::LDd_GP_cPt_V4;
-
- case Hexagon::LDd_GP_cdnNotPt_V4:
- return Hexagon::LDd_GP_cNotPt_V4;
-
- case Hexagon::LDb_GP_cdnPt_V4:
- return Hexagon::LDb_GP_cPt_V4;
-
- case Hexagon::LDb_GP_cdnNotPt_V4:
- return Hexagon::LDb_GP_cNotPt_V4;
-
- case Hexagon::LDub_GP_cdnPt_V4:
- return Hexagon::LDub_GP_cPt_V4;
-
- case Hexagon::LDub_GP_cdnNotPt_V4:
- return Hexagon::LDub_GP_cNotPt_V4;
-
- case Hexagon::LDh_GP_cdnPt_V4:
- return Hexagon::LDh_GP_cPt_V4;
-
- case Hexagon::LDh_GP_cdnNotPt_V4:
- return Hexagon::LDh_GP_cNotPt_V4;
-
- case Hexagon::LDuh_GP_cdnPt_V4:
- return Hexagon::LDuh_GP_cPt_V4;
-
- case Hexagon::LDuh_GP_cdnNotPt_V4:
- return Hexagon::LDuh_GP_cNotPt_V4;
-
- case Hexagon::LDw_GP_cdnPt_V4:
- return Hexagon::LDw_GP_cPt_V4;
-
- case Hexagon::LDw_GP_cdnNotPt_V4:
- return Hexagon::LDw_GP_cNotPt_V4;
-
- // Conditional add
-
- case Hexagon::ADD_ri_cdnPt :
- return Hexagon::ADD_ri_cPt;
- case Hexagon::ADD_ri_cdnNotPt :
- return Hexagon::ADD_ri_cNotPt;
-
- case Hexagon::ADD_rr_cdnPt :
- return Hexagon::ADD_rr_cPt;
- case Hexagon::ADD_rr_cdnNotPt:
- return Hexagon::ADD_rr_cNotPt;
-
- // Conditional logical Operations
-
- case Hexagon::XOR_rr_cdnPt :
- return Hexagon::XOR_rr_cPt;
- case Hexagon::XOR_rr_cdnNotPt :
- return Hexagon::XOR_rr_cNotPt;
-
- case Hexagon::AND_rr_cdnPt :
- return Hexagon::AND_rr_cPt;
- case Hexagon::AND_rr_cdnNotPt :
- return Hexagon::AND_rr_cNotPt;
-
- case Hexagon::OR_rr_cdnPt :
- return Hexagon::OR_rr_cPt;
- case Hexagon::OR_rr_cdnNotPt :
- return Hexagon::OR_rr_cNotPt;
-
- // Conditional Subtract
-
- case Hexagon::SUB_rr_cdnPt :
- return Hexagon::SUB_rr_cPt;
- case Hexagon::SUB_rr_cdnNotPt :
- return Hexagon::SUB_rr_cNotPt;
-
- // Conditional combine
-
- case Hexagon::COMBINE_rr_cdnPt :
- return Hexagon::COMBINE_rr_cPt;
- case Hexagon::COMBINE_rr_cdnNotPt :
- return Hexagon::COMBINE_rr_cNotPt;
-
-// Conditional shift operations
-
- case Hexagon::ASLH_cdnPt_V4 :
- return Hexagon::ASLH_cPt_V4;
- case Hexagon::ASLH_cdnNotPt_V4 :
- return Hexagon::ASLH_cNotPt_V4;
-
- case Hexagon::ASRH_cdnPt_V4 :
- return Hexagon::ASRH_cPt_V4;
- case Hexagon::ASRH_cdnNotPt_V4 :
- return Hexagon::ASRH_cNotPt_V4;
-
- case Hexagon::SXTB_cdnPt_V4 :
- return Hexagon::SXTB_cPt_V4;
- case Hexagon::SXTB_cdnNotPt_V4 :
- return Hexagon::SXTB_cNotPt_V4;
-
- case Hexagon::SXTH_cdnPt_V4 :
- return Hexagon::SXTH_cPt_V4;
- case Hexagon::SXTH_cdnNotPt_V4 :
- return Hexagon::SXTH_cNotPt_V4;
-
- case Hexagon::ZXTB_cdnPt_V4 :
- return Hexagon::ZXTB_cPt_V4;
- case Hexagon::ZXTB_cdnNotPt_V4 :
- return Hexagon::ZXTB_cNotPt_V4;
-
- case Hexagon::ZXTH_cdnPt_V4 :
- return Hexagon::ZXTH_cPt_V4;
- case Hexagon::ZXTH_cdnNotPt_V4 :
- return Hexagon::ZXTH_cNotPt_V4;
-
- // Store byte
-
- case Hexagon::STrib_imm_cdnPt_V4 :
- return Hexagon::STrib_imm_cPt_V4;
-
- case Hexagon::STrib_imm_cdnNotPt_V4 :
- return Hexagon::STrib_imm_cNotPt_V4;
-
- case Hexagon::STrib_cdnPt_nv_V4 :
- case Hexagon::STrib_cPt_nv_V4 :
- case Hexagon::STrib_cdnPt_V4 :
- return Hexagon::STrib_cPt;
-
- case Hexagon::STrib_cdnNotPt_nv_V4 :
- case Hexagon::STrib_cNotPt_nv_V4 :
- case Hexagon::STrib_cdnNotPt_V4 :
- return Hexagon::STrib_cNotPt;
-
- case Hexagon::STrib_indexed_cdnPt_V4 :
- case Hexagon::STrib_indexed_cPt_nv_V4 :
- case Hexagon::STrib_indexed_cdnPt_nv_V4 :
- return Hexagon::STrib_indexed_cPt;
-
- case Hexagon::STrib_indexed_cdnNotPt_V4 :
- case Hexagon::STrib_indexed_cNotPt_nv_V4 :
- case Hexagon::STrib_indexed_cdnNotPt_nv_V4 :
- return Hexagon::STrib_indexed_cNotPt;
-
- case Hexagon::STrib_indexed_shl_cdnPt_nv_V4:
- case Hexagon::STrib_indexed_shl_cPt_nv_V4 :
- case Hexagon::STrib_indexed_shl_cdnPt_V4 :
- return Hexagon::STrib_indexed_shl_cPt_V4;
-
- case Hexagon::STrib_indexed_shl_cdnNotPt_nv_V4:
- case Hexagon::STrib_indexed_shl_cNotPt_nv_V4 :
- case Hexagon::STrib_indexed_shl_cdnNotPt_V4 :
- return Hexagon::STrib_indexed_shl_cNotPt_V4;
-
- case Hexagon::POST_STbri_cdnPt_nv_V4 :
- case Hexagon::POST_STbri_cPt_nv_V4 :
- case Hexagon::POST_STbri_cdnPt_V4 :
- return Hexagon::POST_STbri_cPt;
-
- case Hexagon::POST_STbri_cdnNotPt_nv_V4 :
- case Hexagon::POST_STbri_cNotPt_nv_V4:
- case Hexagon::POST_STbri_cdnNotPt_V4 :
- return Hexagon::POST_STbri_cNotPt;
-
- case Hexagon::STb_GP_cdnPt_nv_V4:
- case Hexagon::STb_GP_cdnPt_V4:
- case Hexagon::STb_GP_cPt_nv_V4:
- return Hexagon::STb_GP_cPt_V4;
-
- case Hexagon::STb_GP_cdnNotPt_nv_V4:
- case Hexagon::STb_GP_cdnNotPt_V4:
- case Hexagon::STb_GP_cNotPt_nv_V4:
- return Hexagon::STb_GP_cNotPt_V4;
-
- // Store new-value byte - unconditional
- case Hexagon::STrib_nv_V4:
- return Hexagon::STrib;
-
- case Hexagon::STrib_indexed_nv_V4:
- return Hexagon::STrib_indexed;
-
- case Hexagon::STrib_indexed_shl_nv_V4:
- return Hexagon::STrib_indexed_shl_V4;
-
- case Hexagon::STrib_shl_nv_V4:
- return Hexagon::STrib_shl_V4;
-
- case Hexagon::STb_GP_nv_V4:
- return Hexagon::STb_GP_V4;
-
- case Hexagon::POST_STbri_nv_V4:
- return Hexagon::POST_STbri;
-
- // Store halfword
- case Hexagon::STrih_imm_cdnPt_V4 :
- return Hexagon::STrih_imm_cPt_V4;
-
- case Hexagon::STrih_imm_cdnNotPt_V4 :
- return Hexagon::STrih_imm_cNotPt_V4;
-
- case Hexagon::STrih_cdnPt_nv_V4 :
- case Hexagon::STrih_cPt_nv_V4 :
- case Hexagon::STrih_cdnPt_V4 :
- return Hexagon::STrih_cPt;
-
- case Hexagon::STrih_cdnNotPt_nv_V4 :
- case Hexagon::STrih_cNotPt_nv_V4 :
- case Hexagon::STrih_cdnNotPt_V4 :
- return Hexagon::STrih_cNotPt;
-
- case Hexagon::STrih_indexed_cdnPt_nv_V4:
- case Hexagon::STrih_indexed_cPt_nv_V4 :
- case Hexagon::STrih_indexed_cdnPt_V4 :
- return Hexagon::STrih_indexed_cPt;
-
- case Hexagon::STrih_indexed_cdnNotPt_nv_V4:
- case Hexagon::STrih_indexed_cNotPt_nv_V4 :
- case Hexagon::STrih_indexed_cdnNotPt_V4 :
- return Hexagon::STrih_indexed_cNotPt;
-
- case Hexagon::STrih_indexed_shl_cdnPt_nv_V4 :
- case Hexagon::STrih_indexed_shl_cPt_nv_V4 :
- case Hexagon::STrih_indexed_shl_cdnPt_V4 :
- return Hexagon::STrih_indexed_shl_cPt_V4;
-
- case Hexagon::STrih_indexed_shl_cdnNotPt_nv_V4 :
- case Hexagon::STrih_indexed_shl_cNotPt_nv_V4 :
- case Hexagon::STrih_indexed_shl_cdnNotPt_V4 :
- return Hexagon::STrih_indexed_shl_cNotPt_V4;
-
- case Hexagon::POST_SThri_cdnPt_nv_V4 :
- case Hexagon::POST_SThri_cPt_nv_V4 :
- case Hexagon::POST_SThri_cdnPt_V4 :
- return Hexagon::POST_SThri_cPt;
-
- case Hexagon::POST_SThri_cdnNotPt_nv_V4 :
- case Hexagon::POST_SThri_cNotPt_nv_V4 :
- case Hexagon::POST_SThri_cdnNotPt_V4 :
- return Hexagon::POST_SThri_cNotPt;
-
- case Hexagon::STh_GP_cdnPt_nv_V4:
- case Hexagon::STh_GP_cdnPt_V4:
- case Hexagon::STh_GP_cPt_nv_V4:
- return Hexagon::STh_GP_cPt_V4;
-
- case Hexagon::STh_GP_cdnNotPt_nv_V4:
- case Hexagon::STh_GP_cdnNotPt_V4:
- case Hexagon::STh_GP_cNotPt_nv_V4:
- return Hexagon::STh_GP_cNotPt_V4;
-
- // Store new-value halfword - unconditional
-
- case Hexagon::STrih_nv_V4:
- return Hexagon::STrih;
-
- case Hexagon::STrih_indexed_nv_V4:
- return Hexagon::STrih_indexed;
-
- case Hexagon::STrih_indexed_shl_nv_V4:
- return Hexagon::STrih_indexed_shl_V4;
-
- case Hexagon::STrih_shl_nv_V4:
- return Hexagon::STrih_shl_V4;
-
- case Hexagon::STh_GP_nv_V4:
- return Hexagon::STh_GP_V4;
-
- case Hexagon::POST_SThri_nv_V4:
- return Hexagon::POST_SThri;
-
- // Store word
-
- case Hexagon::STriw_imm_cdnPt_V4 :
- return Hexagon::STriw_imm_cPt_V4;
-
- case Hexagon::STriw_imm_cdnNotPt_V4 :
- return Hexagon::STriw_imm_cNotPt_V4;
-
- case Hexagon::STriw_cdnPt_nv_V4 :
- case Hexagon::STriw_cPt_nv_V4 :
- case Hexagon::STriw_cdnPt_V4 :
- return Hexagon::STriw_cPt;
-
- case Hexagon::STriw_cdnNotPt_nv_V4 :
- case Hexagon::STriw_cNotPt_nv_V4 :
- case Hexagon::STriw_cdnNotPt_V4 :
- return Hexagon::STriw_cNotPt;
-
- case Hexagon::STriw_indexed_cdnPt_nv_V4 :
- case Hexagon::STriw_indexed_cPt_nv_V4 :
- case Hexagon::STriw_indexed_cdnPt_V4 :
- return Hexagon::STriw_indexed_cPt;
-
- case Hexagon::STriw_indexed_cdnNotPt_nv_V4 :
- case Hexagon::STriw_indexed_cNotPt_nv_V4 :
- case Hexagon::STriw_indexed_cdnNotPt_V4 :
- return Hexagon::STriw_indexed_cNotPt;
-
- case Hexagon::STriw_indexed_shl_cdnPt_nv_V4 :
- case Hexagon::STriw_indexed_shl_cPt_nv_V4 :
- case Hexagon::STriw_indexed_shl_cdnPt_V4 :
- return Hexagon::STriw_indexed_shl_cPt_V4;
-
- case Hexagon::STriw_indexed_shl_cdnNotPt_nv_V4 :
- case Hexagon::STriw_indexed_shl_cNotPt_nv_V4 :
- case Hexagon::STriw_indexed_shl_cdnNotPt_V4 :
- return Hexagon::STriw_indexed_shl_cNotPt_V4;
-
- case Hexagon::POST_STwri_cdnPt_nv_V4 :
- case Hexagon::POST_STwri_cPt_nv_V4 :
- case Hexagon::POST_STwri_cdnPt_V4 :
- return Hexagon::POST_STwri_cPt;
-
- case Hexagon::POST_STwri_cdnNotPt_nv_V4 :
- case Hexagon::POST_STwri_cNotPt_nv_V4 :
- case Hexagon::POST_STwri_cdnNotPt_V4 :
- return Hexagon::POST_STwri_cNotPt;
-
- case Hexagon::STw_GP_cdnPt_nv_V4:
- case Hexagon::STw_GP_cdnPt_V4:
- case Hexagon::STw_GP_cPt_nv_V4:
- return Hexagon::STw_GP_cPt_V4;
-
- case Hexagon::STw_GP_cdnNotPt_nv_V4:
- case Hexagon::STw_GP_cdnNotPt_V4:
- case Hexagon::STw_GP_cNotPt_nv_V4:
- return Hexagon::STw_GP_cNotPt_V4;
-
- // Store new-value word - unconditional
-
- case Hexagon::STriw_nv_V4:
- return Hexagon::STriw;
-
- case Hexagon::STriw_indexed_nv_V4:
- return Hexagon::STriw_indexed;
-
- case Hexagon::STriw_indexed_shl_nv_V4:
- return Hexagon::STriw_indexed_shl_V4;
-
- case Hexagon::STriw_shl_nv_V4:
- return Hexagon::STriw_shl_V4;
-
- case Hexagon::STw_GP_nv_V4:
- return Hexagon::STw_GP_V4;
-
- case Hexagon::POST_STwri_nv_V4:
- return Hexagon::POST_STwri;
-
- // Store doubleword
-
- case Hexagon::STrid_cdnPt_V4 :
- return Hexagon::STrid_cPt;
-
- case Hexagon::STrid_cdnNotPt_V4 :
- return Hexagon::STrid_cNotPt;
-
- case Hexagon::STrid_indexed_cdnPt_V4 :
- return Hexagon::STrid_indexed_cPt;
-
- case Hexagon::STrid_indexed_cdnNotPt_V4 :
- return Hexagon::STrid_indexed_cNotPt;
-
- case Hexagon::STrid_indexed_shl_cdnPt_V4 :
- return Hexagon::STrid_indexed_shl_cPt_V4;
-
- case Hexagon::STrid_indexed_shl_cdnNotPt_V4 :
- return Hexagon::STrid_indexed_shl_cNotPt_V4;
-
- case Hexagon::POST_STdri_cdnPt_V4 :
- return Hexagon::POST_STdri_cPt;
-
- case Hexagon::POST_STdri_cdnNotPt_V4 :
- return Hexagon::POST_STdri_cNotPt;
-
- case Hexagon::STd_GP_cdnPt_V4 :
- return Hexagon::STd_GP_cPt_V4;
-
- case Hexagon::STd_GP_cdnNotPt_V4 :
- return Hexagon::STd_GP_cNotPt_V4;
-
- }
-}
-
bool HexagonPacketizerList::DemoteToDotOld(MachineInstr* MI) {
const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
- int NewOpcode = GetDotOldOp(MI->getOpcode());
+ int NewOpcode = QII->GetDotOldOp(MI->getOpcode());
MI->setDesc(QII->get(NewOpcode));
return true;
}
-// Returns true if an instruction is predicated on p0 and false if it's
-// predicated on !p0.
+enum PredicateKind {
+ PK_False,
+ PK_True,
+ PK_Unknown
+};
-static bool GetPredicateSense(MachineInstr* MI,
- const HexagonInstrInfo *QII) {
+/// Returns true if an instruction is predicated on p0 and false if it's
+/// predicated on !p0.
+static PredicateKind getPredicateSense(MachineInstr* MI,
+ const HexagonInstrInfo *QII) {
+ if (!QII->isPredicated(MI))
+ return PK_Unknown;
- switch (MI->getOpcode()) {
- default: llvm_unreachable("Unknown predicate sense of the instruction");
- case Hexagon::TFR_cPt:
- case Hexagon::TFR_cdnPt:
- case Hexagon::TFRI_cPt:
- case Hexagon::TFRI_cdnPt:
- case Hexagon::STrib_cPt :
- case Hexagon::STrib_cdnPt_V4 :
- case Hexagon::STrib_indexed_cPt :
- case Hexagon::STrib_indexed_cdnPt_V4 :
- case Hexagon::STrib_indexed_shl_cPt_V4 :
- case Hexagon::STrib_indexed_shl_cdnPt_V4 :
- case Hexagon::POST_STbri_cPt :
- case Hexagon::POST_STbri_cdnPt_V4 :
- case Hexagon::STrih_cPt :
- case Hexagon::STrih_cdnPt_V4 :
- case Hexagon::STrih_indexed_cPt :
- case Hexagon::STrih_indexed_cdnPt_V4 :
- case Hexagon::STrih_indexed_shl_cPt_V4 :
- case Hexagon::STrih_indexed_shl_cdnPt_V4 :
- case Hexagon::POST_SThri_cPt :
- case Hexagon::POST_SThri_cdnPt_V4 :
- case Hexagon::STriw_cPt :
- case Hexagon::STriw_cdnPt_V4 :
- case Hexagon::STriw_indexed_cPt :
- case Hexagon::STriw_indexed_cdnPt_V4 :
- case Hexagon::STriw_indexed_shl_cPt_V4 :
- case Hexagon::STriw_indexed_shl_cdnPt_V4 :
- case Hexagon::POST_STwri_cPt :
- case Hexagon::POST_STwri_cdnPt_V4 :
- case Hexagon::STrib_imm_cPt_V4 :
- case Hexagon::STrib_imm_cdnPt_V4 :
- case Hexagon::STrid_cPt :
- case Hexagon::STrid_cdnPt_V4 :
- case Hexagon::STrid_indexed_cPt :
- case Hexagon::STrid_indexed_cdnPt_V4 :
- case Hexagon::STrid_indexed_shl_cPt_V4 :
- case Hexagon::STrid_indexed_shl_cdnPt_V4 :
- case Hexagon::POST_STdri_cPt :
- case Hexagon::POST_STdri_cdnPt_V4 :
- case Hexagon::STrih_imm_cPt_V4 :
- case Hexagon::STrih_imm_cdnPt_V4 :
- case Hexagon::STriw_imm_cPt_V4 :
- case Hexagon::STriw_imm_cdnPt_V4 :
- case Hexagon::JMP_tnew_t :
- case Hexagon::LDrid_cPt :
- case Hexagon::LDrid_cdnPt :
- case Hexagon::LDrid_indexed_cPt :
- case Hexagon::LDrid_indexed_cdnPt :
- case Hexagon::POST_LDrid_cPt :
- case Hexagon::POST_LDrid_cdnPt_V4 :
- case Hexagon::LDriw_cPt :
- case Hexagon::LDriw_cdnPt :
- case Hexagon::LDriw_indexed_cPt :
- case Hexagon::LDriw_indexed_cdnPt :
- case Hexagon::POST_LDriw_cPt :
- case Hexagon::POST_LDriw_cdnPt_V4 :
- case Hexagon::LDrih_cPt :
- case Hexagon::LDrih_cdnPt :
- case Hexagon::LDrih_indexed_cPt :
- case Hexagon::LDrih_indexed_cdnPt :
- case Hexagon::POST_LDrih_cPt :
- case Hexagon::POST_LDrih_cdnPt_V4 :
- case Hexagon::LDrib_cPt :
- case Hexagon::LDrib_cdnPt :
- case Hexagon::LDrib_indexed_cPt :
- case Hexagon::LDrib_indexed_cdnPt :
- case Hexagon::POST_LDrib_cPt :
- case Hexagon::POST_LDrib_cdnPt_V4 :
- case Hexagon::LDriuh_cPt :
- case Hexagon::LDriuh_cdnPt :
- case Hexagon::LDriuh_indexed_cPt :
- case Hexagon::LDriuh_indexed_cdnPt :
- case Hexagon::POST_LDriuh_cPt :
- case Hexagon::POST_LDriuh_cdnPt_V4 :
- case Hexagon::LDriub_cPt :
- case Hexagon::LDriub_cdnPt :
- case Hexagon::LDriub_indexed_cPt :
- case Hexagon::LDriub_indexed_cdnPt :
- case Hexagon::POST_LDriub_cPt :
- case Hexagon::POST_LDriub_cdnPt_V4 :
- case Hexagon::LDrid_indexed_shl_cPt_V4 :
- case Hexagon::LDrid_indexed_shl_cdnPt_V4 :
- case Hexagon::LDrib_indexed_shl_cPt_V4 :
- case Hexagon::LDrib_indexed_shl_cdnPt_V4 :
- case Hexagon::LDriub_indexed_shl_cPt_V4 :
- case Hexagon::LDriub_indexed_shl_cdnPt_V4 :
- case Hexagon::LDrih_indexed_shl_cPt_V4 :
- case Hexagon::LDrih_indexed_shl_cdnPt_V4 :
- case Hexagon::LDriuh_indexed_shl_cPt_V4 :
- case Hexagon::LDriuh_indexed_shl_cdnPt_V4 :
- case Hexagon::LDriw_indexed_shl_cPt_V4 :
- case Hexagon::LDriw_indexed_shl_cdnPt_V4 :
- case Hexagon::ADD_ri_cPt :
- case Hexagon::ADD_ri_cdnPt :
- case Hexagon::ADD_rr_cPt :
- case Hexagon::ADD_rr_cdnPt :
- case Hexagon::XOR_rr_cPt :
- case Hexagon::XOR_rr_cdnPt :
- case Hexagon::AND_rr_cPt :
- case Hexagon::AND_rr_cdnPt :
- case Hexagon::OR_rr_cPt :
- case Hexagon::OR_rr_cdnPt :
- case Hexagon::SUB_rr_cPt :
- case Hexagon::SUB_rr_cdnPt :
- case Hexagon::COMBINE_rr_cPt :
- case Hexagon::COMBINE_rr_cdnPt :
- case Hexagon::ASLH_cPt_V4 :
- case Hexagon::ASLH_cdnPt_V4 :
- case Hexagon::ASRH_cPt_V4 :
- case Hexagon::ASRH_cdnPt_V4 :
- case Hexagon::SXTB_cPt_V4 :
- case Hexagon::SXTB_cdnPt_V4 :
- case Hexagon::SXTH_cPt_V4 :
- case Hexagon::SXTH_cdnPt_V4 :
- case Hexagon::ZXTB_cPt_V4 :
- case Hexagon::ZXTB_cdnPt_V4 :
- case Hexagon::ZXTH_cPt_V4 :
- case Hexagon::ZXTH_cdnPt_V4 :
- case Hexagon::LDd_GP_cPt_V4 :
- case Hexagon::LDb_GP_cPt_V4 :
- case Hexagon::LDub_GP_cPt_V4 :
- case Hexagon::LDh_GP_cPt_V4 :
- case Hexagon::LDuh_GP_cPt_V4 :
- case Hexagon::LDw_GP_cPt_V4 :
- case Hexagon::STd_GP_cPt_V4 :
- case Hexagon::STb_GP_cPt_V4 :
- case Hexagon::STh_GP_cPt_V4 :
- case Hexagon::STw_GP_cPt_V4 :
- case Hexagon::LDd_GP_cdnPt_V4 :
- case Hexagon::LDb_GP_cdnPt_V4 :
- case Hexagon::LDub_GP_cdnPt_V4 :
- case Hexagon::LDh_GP_cdnPt_V4 :
- case Hexagon::LDuh_GP_cdnPt_V4 :
- case Hexagon::LDw_GP_cdnPt_V4 :
- case Hexagon::STd_GP_cdnPt_V4 :
- case Hexagon::STb_GP_cdnPt_V4 :
- case Hexagon::STh_GP_cdnPt_V4 :
- case Hexagon::STw_GP_cdnPt_V4 :
- return true;
+ if (QII->isPredicatedTrue(MI))
+ return PK_True;
- case Hexagon::TFR_cNotPt:
- case Hexagon::TFR_cdnNotPt:
- case Hexagon::TFRI_cNotPt:
- case Hexagon::TFRI_cdnNotPt:
- case Hexagon::STrib_cNotPt :
- case Hexagon::STrib_cdnNotPt_V4 :
- case Hexagon::STrib_indexed_cNotPt :
- case Hexagon::STrib_indexed_cdnNotPt_V4 :
- case Hexagon::STrib_indexed_shl_cNotPt_V4 :
- case Hexagon::STrib_indexed_shl_cdnNotPt_V4 :
- case Hexagon::POST_STbri_cNotPt :
- case Hexagon::POST_STbri_cdnNotPt_V4 :
- case Hexagon::STrih_cNotPt :
- case Hexagon::STrih_cdnNotPt_V4 :
- case Hexagon::STrih_indexed_cNotPt :
- case Hexagon::STrih_indexed_cdnNotPt_V4 :
- case Hexagon::STrih_indexed_shl_cNotPt_V4 :
- case Hexagon::STrih_indexed_shl_cdnNotPt_V4 :
- case Hexagon::POST_SThri_cNotPt :
- case Hexagon::POST_SThri_cdnNotPt_V4 :
- case Hexagon::STriw_cNotPt :
- case Hexagon::STriw_cdnNotPt_V4 :
- case Hexagon::STriw_indexed_cNotPt :
- case Hexagon::STriw_indexed_cdnNotPt_V4 :
- case Hexagon::STriw_indexed_shl_cNotPt_V4 :
- case Hexagon::STriw_indexed_shl_cdnNotPt_V4 :
- case Hexagon::POST_STwri_cNotPt :
- case Hexagon::POST_STwri_cdnNotPt_V4 :
- case Hexagon::STrib_imm_cNotPt_V4 :
- case Hexagon::STrib_imm_cdnNotPt_V4 :
- case Hexagon::STrid_cNotPt :
- case Hexagon::STrid_cdnNotPt_V4 :
- case Hexagon::STrid_indexed_cdnNotPt_V4 :
- case Hexagon::STrid_indexed_cNotPt :
- case Hexagon::STrid_indexed_shl_cNotPt_V4 :
- case Hexagon::STrid_indexed_shl_cdnNotPt_V4 :
- case Hexagon::POST_STdri_cNotPt :
- case Hexagon::POST_STdri_cdnNotPt_V4 :
- case Hexagon::STrih_imm_cNotPt_V4 :
- case Hexagon::STrih_imm_cdnNotPt_V4 :
- case Hexagon::STriw_imm_cNotPt_V4 :
- case Hexagon::STriw_imm_cdnNotPt_V4 :
- case Hexagon::JMP_fnew_t :
- case Hexagon::LDrid_cNotPt :
- case Hexagon::LDrid_cdnNotPt :
- case Hexagon::LDrid_indexed_cNotPt :
- case Hexagon::LDrid_indexed_cdnNotPt :
- case Hexagon::POST_LDrid_cNotPt :
- case Hexagon::POST_LDrid_cdnNotPt_V4 :
- case Hexagon::LDriw_cNotPt :
- case Hexagon::LDriw_cdnNotPt :
- case Hexagon::LDriw_indexed_cNotPt :
- case Hexagon::LDriw_indexed_cdnNotPt :
- case Hexagon::POST_LDriw_cNotPt :
- case Hexagon::POST_LDriw_cdnNotPt_V4 :
- case Hexagon::LDrih_cNotPt :
- case Hexagon::LDrih_cdnNotPt :
- case Hexagon::LDrih_indexed_cNotPt :
- case Hexagon::LDrih_indexed_cdnNotPt :
- case Hexagon::POST_LDrih_cNotPt :
- case Hexagon::POST_LDrih_cdnNotPt_V4 :
- case Hexagon::LDrib_cNotPt :
- case Hexagon::LDrib_cdnNotPt :
- case Hexagon::LDrib_indexed_cNotPt :
- case Hexagon::LDrib_indexed_cdnNotPt :
- case Hexagon::POST_LDrib_cNotPt :
- case Hexagon::POST_LDrib_cdnNotPt_V4 :
- case Hexagon::LDriuh_cNotPt :
- case Hexagon::LDriuh_cdnNotPt :
- case Hexagon::LDriuh_indexed_cNotPt :
- case Hexagon::LDriuh_indexed_cdnNotPt :
- case Hexagon::POST_LDriuh_cNotPt :
- case Hexagon::POST_LDriuh_cdnNotPt_V4 :
- case Hexagon::LDriub_cNotPt :
- case Hexagon::LDriub_cdnNotPt :
- case Hexagon::LDriub_indexed_cNotPt :
- case Hexagon::LDriub_indexed_cdnNotPt :
- case Hexagon::POST_LDriub_cNotPt :
- case Hexagon::POST_LDriub_cdnNotPt_V4 :
- case Hexagon::LDrid_indexed_shl_cNotPt_V4 :
- case Hexagon::LDrid_indexed_shl_cdnNotPt_V4 :
- case Hexagon::LDrib_indexed_shl_cNotPt_V4 :
- case Hexagon::LDrib_indexed_shl_cdnNotPt_V4 :
- case Hexagon::LDriub_indexed_shl_cNotPt_V4 :
- case Hexagon::LDriub_indexed_shl_cdnNotPt_V4 :
- case Hexagon::LDrih_indexed_shl_cNotPt_V4 :
- case Hexagon::LDrih_indexed_shl_cdnNotPt_V4 :
- case Hexagon::LDriuh_indexed_shl_cNotPt_V4 :
- case Hexagon::LDriuh_indexed_shl_cdnNotPt_V4 :
- case Hexagon::LDriw_indexed_shl_cNotPt_V4 :
- case Hexagon::LDriw_indexed_shl_cdnNotPt_V4 :
- case Hexagon::ADD_ri_cNotPt :
- case Hexagon::ADD_ri_cdnNotPt :
- case Hexagon::ADD_rr_cNotPt :
- case Hexagon::ADD_rr_cdnNotPt :
- case Hexagon::XOR_rr_cNotPt :
- case Hexagon::XOR_rr_cdnNotPt :
- case Hexagon::AND_rr_cNotPt :
- case Hexagon::AND_rr_cdnNotPt :
- case Hexagon::OR_rr_cNotPt :
- case Hexagon::OR_rr_cdnNotPt :
- case Hexagon::SUB_rr_cNotPt :
- case Hexagon::SUB_rr_cdnNotPt :
- case Hexagon::COMBINE_rr_cNotPt :
- case Hexagon::COMBINE_rr_cdnNotPt :
- case Hexagon::ASLH_cNotPt_V4 :
- case Hexagon::ASLH_cdnNotPt_V4 :
- case Hexagon::ASRH_cNotPt_V4 :
- case Hexagon::ASRH_cdnNotPt_V4 :
- case Hexagon::SXTB_cNotPt_V4 :
- case Hexagon::SXTB_cdnNotPt_V4 :
- case Hexagon::SXTH_cNotPt_V4 :
- case Hexagon::SXTH_cdnNotPt_V4 :
- case Hexagon::ZXTB_cNotPt_V4 :
- case Hexagon::ZXTB_cdnNotPt_V4 :
- case Hexagon::ZXTH_cNotPt_V4 :
- case Hexagon::ZXTH_cdnNotPt_V4 :
-
- case Hexagon::LDd_GP_cNotPt_V4 :
- case Hexagon::LDb_GP_cNotPt_V4 :
- case Hexagon::LDub_GP_cNotPt_V4 :
- case Hexagon::LDh_GP_cNotPt_V4 :
- case Hexagon::LDuh_GP_cNotPt_V4 :
- case Hexagon::LDw_GP_cNotPt_V4 :
- case Hexagon::STd_GP_cNotPt_V4 :
- case Hexagon::STb_GP_cNotPt_V4 :
- case Hexagon::STh_GP_cNotPt_V4 :
- case Hexagon::STw_GP_cNotPt_V4 :
- case Hexagon::LDd_GP_cdnNotPt_V4 :
- case Hexagon::LDb_GP_cdnNotPt_V4 :
- case Hexagon::LDub_GP_cdnNotPt_V4 :
- case Hexagon::LDh_GP_cdnNotPt_V4 :
- case Hexagon::LDuh_GP_cdnNotPt_V4 :
- case Hexagon::LDw_GP_cdnNotPt_V4 :
- case Hexagon::STd_GP_cdnNotPt_V4 :
- case Hexagon::STb_GP_cdnNotPt_V4 :
- case Hexagon::STh_GP_cdnNotPt_V4 :
- case Hexagon::STw_GP_cdnNotPt_V4 :
- return false;
- }
- // return *some value* to avoid compiler warning
- return false;
+ return PK_False;
}
static MachineOperand& GetPostIncrementOperand(MachineInstr *MI,
@@ -2254,10 +537,10 @@ static MachineOperand& GetStoreValueOperand(MachineInstr *MI) {
// Arch Spec: 3.4.4.2
bool HexagonPacketizerList::CanPromoteToNewValueStore( MachineInstr *MI,
MachineInstr *PacketMI, unsigned DepReg,
- std::map <MachineInstr*, SUnit*> MIToSUnit)
-{
- // Make sure we are looking at the store
- if (!IsNewifyStore(MI))
+ std::map <MachineInstr*, SUnit*> MIToSUnit) {
+ const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
+ // Make sure we are looking at the store, that can be promoted.
+ if (!QII->mayBeNewStore(MI))
return false;
// Make sure there is dependency and can be new value'ed
@@ -2265,12 +548,11 @@ bool HexagonPacketizerList::CanPromoteToNewValueStore( MachineInstr *MI,
GetStoreValueOperand(MI).getReg() != DepReg)
return false;
- const HexagonRegisterInfo* QRI =
+ const HexagonRegisterInfo* QRI =
(const HexagonRegisterInfo *) TM.getRegisterInfo();
const MCInstrDesc& MCID = PacketMI->getDesc();
// first operand is always the result
- const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
const TargetRegisterClass* PacketRC = QII->getRegClass(MCID, 0, QRI, MF);
// if there is already an store in the packet, no can do new value store
@@ -2313,7 +595,7 @@ bool HexagonPacketizerList::CanPromoteToNewValueStore( MachineInstr *MI,
}
// If the source that feeds the store is predicated, new value store must
- // also be also predicated.
+ // also be predicated.
if (QII->isPredicated(PacketMI)) {
if (!QII->isPredicated(MI))
return false;
@@ -2359,7 +641,7 @@ bool HexagonPacketizerList::CanPromoteToNewValueStore( MachineInstr *MI,
if (( predRegNumDst != predRegNumSrc) ||
QII->isDotNewInst(PacketMI) != QII->isDotNewInst(MI) ||
- GetPredicateSense(MI, QII) != GetPredicateSense(PacketMI, QII)) {
+ getPredicateSense(MI, QII) != getPredicateSense(PacketMI, QII)) {
return false;
}
}
@@ -2440,10 +722,11 @@ bool HexagonPacketizerList::CanPromoteToNewValue( MachineInstr *MI,
MachineBasicBlock::iterator &MII)
{
+ const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
const HexagonRegisterInfo* QRI =
(const HexagonRegisterInfo *) TM.getRegisterInfo();
if (!QRI->Subtarget.hasV4TOps() ||
- !IsNewifyStore(MI))
+ !QII->mayBeNewStore(MI))
return false;
MachineInstr *PacketMI = PacketSU->getInstr();
@@ -2470,7 +753,7 @@ bool HexagonPacketizerList::CanPromoteToDotNew( MachineInstr *MI,
{
const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
// Already a dot new instruction.
- if (QII->isDotNewInst(MI) && !IsNewifyStore(MI))
+ if (QII->isDotNewInst(MI) && !QII->mayBeNewStore(MI))
return false;
if (!isNewifiable(MI))
@@ -2480,12 +763,12 @@ bool HexagonPacketizerList::CanPromoteToDotNew( MachineInstr *MI,
if (RC == &Hexagon::PredRegsRegClass && isCondInst(MI))
return true;
else if (RC != &Hexagon::PredRegsRegClass &&
- !IsNewifyStore(MI)) // MI is not a new-value store
+ !QII->mayBeNewStore(MI)) // MI is not a new-value store
return false;
else {
// Create a dot new machine instruction to see if resources can be
// allocated. If not, bail out now.
- int NewOpcode = GetDotNewOp(MI->getOpcode());
+ int NewOpcode = QII->GetDotNewOp(MI);
const MCInstrDesc &desc = QII->get(NewOpcode);
DebugLoc dl;
MachineInstr *NewMI =
@@ -2554,16 +837,39 @@ bool HexagonPacketizerList::RestrictingDepExistInPacket (MachineInstr* MI,
}
+/// Gets the predicate register of a predicated instruction.
+static unsigned getPredicatedRegister(MachineInstr *MI,
+ const HexagonInstrInfo *QII) {
+ /// We use the following rule: The first predicate register that is a use is
+ /// the predicate register of a predicated instruction.
+
+ assert(QII->isPredicated(MI) && "Must be predicated instruction");
+
+ for (MachineInstr::mop_iterator OI = MI->operands_begin(),
+ OE = MI->operands_end(); OI != OE; ++OI) {
+ MachineOperand &Op = *OI;
+ if (Op.isReg() && Op.getReg() && Op.isUse() &&
+ Hexagon::PredRegsRegClass.contains(Op.getReg()))
+ return Op.getReg();
+ }
+
+ llvm_unreachable("Unknown instruction operand layout");
+
+ return 0;
+}
+
// Given two predicated instructions, this function detects whether
// the predicates are complements
bool HexagonPacketizerList::ArePredicatesComplements (MachineInstr* MI1,
MachineInstr* MI2, std::map <MachineInstr*, SUnit*> MIToSUnit) {
const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
- // Currently can only reason about conditional transfers
- if (!QII->isConditionalTransfer(MI1) || !QII->isConditionalTransfer(MI2)) {
+
+ // If we don't know the predicate sense of the instructions bail out early, we
+ // need it later.
+ if (getPredicateSense(MI1, QII) == PK_Unknown ||
+ getPredicateSense(MI2, QII) == PK_Unknown)
return false;
- }
// Scheduling unit for candidate
SUnit* SU = MIToSUnit[MI1];
@@ -2602,9 +908,9 @@ bool HexagonPacketizerList::ArePredicatesComplements (MachineInstr* MI1,
// there already exist anti dep on the same pred in
// the packet.
if (PacketSU->Succs[i].getSUnit() == SU &&
+ PacketSU->Succs[i].getKind() == SDep::Data &&
Hexagon::PredRegsRegClass.contains(
PacketSU->Succs[i].getReg()) &&
- PacketSU->Succs[i].getKind() == SDep::Data &&
// Here I know that *VIN is predicate setting instruction
// with true data dep to candidate on the register
// we care about - c) in the above example.
@@ -2625,8 +931,12 @@ bool HexagonPacketizerList::ArePredicatesComplements (MachineInstr* MI1,
// that the predicate sense is different
// We also need to differentiate .old vs. .new:
// !p0 is not complimentary to p0.new
- return ((MI1->getOperand(1).getReg() == MI2->getOperand(1).getReg()) &&
- (GetPredicateSense(MI1, QII) != GetPredicateSense(MI2, QII)) &&
+ unsigned PReg1 = getPredicatedRegister(MI1, QII);
+ unsigned PReg2 = getPredicatedRegister(MI2, QII);
+ return ((PReg1 == PReg2) &&
+ Hexagon::PredRegsRegClass.contains(PReg1) &&
+ Hexagon::PredRegsRegClass.contains(PReg2) &&
+ (getPredicateSense(MI1, QII) != getPredicateSense(MI2, QII)) &&
(QII->isDotNewInst(MI1) == QII->isDotNewInst(MI2)));
}
@@ -2724,24 +1034,21 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
}
// A LoopN instruction cannot appear in the same packet as a jump or call.
- if (IsLoopN(I) && ( IsDirectJump(J)
- || MCIDJ.isCall()
- || QII->isDeallocRet(J))) {
+ if (IsLoopN(I) &&
+ (IsDirectJump(J) || MCIDJ.isCall() || QII->isDeallocRet(J))) {
Dependence = true;
return false;
}
- if (IsLoopN(J) && ( IsDirectJump(I)
- || MCIDI.isCall()
- || QII->isDeallocRet(I))) {
+ if (IsLoopN(J) &&
+ (IsDirectJump(I) || MCIDI.isCall() || QII->isDeallocRet(I))) {
Dependence = true;
return false;
}
// dealloc_return cannot appear in the same packet as a conditional or
// unconditional jump.
- if (QII->isDeallocRet(I) && ( MCIDJ.isBranch()
- || MCIDJ.isCall()
- || MCIDJ.isBarrier())) {
+ if (QII->isDeallocRet(I) &&
+ (MCIDJ.isBranch() || MCIDJ.isCall() || MCIDJ.isBarrier())) {
Dependence = true;
return false;
}
@@ -2766,7 +1073,7 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
}
//if dealloc_return
- if (MCIDJ.mayStore() && QII->isDeallocRet(I)){
+ if (MCIDJ.mayStore() && QII->isDeallocRet(I)) {
Dependence = true;
return false;
}
@@ -2774,9 +1081,8 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
// If an instruction feeds new value jump, glue it.
MachineBasicBlock::iterator NextMII = I;
++NextMII;
- MachineInstr *NextMI = NextMII;
-
- if (QII->isNewValueJump(NextMI)) {
+ if (NextMII != I->getParent()->end() && QII->isNewValueJump(NextMII)) {
+ MachineInstr *NextMI = NextMII;
bool secondRegMatch = false;
bool maintainNewValueJump = false;
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h b/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
index d4a93b5..e0f5a27 100644
--- a/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
@@ -65,7 +65,8 @@ namespace HexagonII {
AbsoluteSet = 2, // Absolute set addressing mode
BaseImmOffset = 3, // Indirect with offset
BaseLongOffset = 4, // Indirect with long offset
- BaseRegOffset = 5 // Indirect with register offset
+ BaseRegOffset = 5, // Indirect with register offset
+ PostInc = 6 // Post increment addressing mode
};
enum MemAccessSize {
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
index 3deb8d1..495dbb9 100644
--- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
@@ -15,7 +15,7 @@
using namespace llvm;
-HexagonMCAsmInfo::HexagonMCAsmInfo(const Target &T, StringRef TT) {
+HexagonMCAsmInfo::HexagonMCAsmInfo(StringRef TT) {
Data16bitsDirective = "\t.half\t";
Data32bitsDirective = "\t.word\t";
Data64bitsDirective = 0; // .xword is only supported by V9.
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h
index d336cd5..0b94d21 100644
--- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h
@@ -18,11 +18,9 @@
#include "llvm/MC/MCAsmInfo.h"
namespace llvm {
- class Target;
-
class HexagonMCAsmInfo : public MCAsmInfo {
public:
- explicit HexagonMCAsmInfo(const Target &T, StringRef TT);
+ explicit HexagonMCAsmInfo(StringRef TT);
};
} // namespace llvm
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp
index 6b1d2d1..2f93a52 100644
--- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp
@@ -54,13 +54,14 @@ static MCSubtargetInfo *createHexagonMCSubtargetInfo(StringRef TT,
return X;
}
-static MCAsmInfo *createHexagonMCAsmInfo(const Target &T, StringRef TT) {
- MCAsmInfo *MAI = new HexagonMCAsmInfo(T, TT);
+static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI,
+ StringRef TT) {
+ MCAsmInfo *MAI = new HexagonMCAsmInfo(TT);
// VirtualFP = (R30 + #0).
- MachineLocation Dst(MachineLocation::VirtualFP);
- MachineLocation Src(Hexagon::R30, 0);
- MAI->addInitialFrameState(0, Dst, Src);
+ MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(
+ 0, Hexagon::R30, 0);
+ MAI->addInitialFrameState(Inst);
return MAI;
}