aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/Hexagon
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Hexagon')
-rw-r--r--lib/Target/Hexagon/CMakeLists.txt6
-rw-r--r--lib/Target/Hexagon/Hexagon.h21
-rw-r--r--lib/Target/Hexagon/Hexagon.td56
-rw-r--r--lib/Target/Hexagon/HexagonCFGOptimizer.cpp50
-rw-r--r--lib/Target/Hexagon/HexagonCallingConvLower.cpp8
-rw-r--r--lib/Target/Hexagon/HexagonCallingConvLower.h5
-rw-r--r--lib/Target/Hexagon/HexagonCopyToCombine.cpp677
-rw-r--r--lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp29
-rw-r--r--lib/Target/Hexagon/HexagonFrameLowering.cpp82
-rw-r--r--lib/Target/Hexagon/HexagonHardwareLoops.cpp21
-rw-r--r--lib/Target/Hexagon/HexagonISelDAGToDAG.cpp131
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.cpp107
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.h17
-rw-r--r--lib/Target/Hexagon/HexagonInstrFormats.td3
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.cpp1434
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.h28
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.td1205
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfoV3.td40
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfoV4.td2903
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfoV5.td23
-rw-r--r--lib/Target/Hexagon/HexagonMCInst.h41
-rw-r--r--lib/Target/Hexagon/HexagonMachineFunctionInfo.h9
-rw-r--r--lib/Target/Hexagon/HexagonMachineScheduler.cpp9
-rw-r--r--lib/Target/Hexagon/HexagonMachineScheduler.h3
-rw-r--r--lib/Target/Hexagon/HexagonNewValueJump.cpp184
-rw-r--r--lib/Target/Hexagon/HexagonPeephole.cpp35
-rw-r--r--lib/Target/Hexagon/HexagonRegisterInfo.cpp84
-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/HexagonSubtarget.cpp17
-rw-r--r--lib/Target/Hexagon/HexagonTargetMachine.cpp99
-rw-r--r--lib/Target/Hexagon/HexagonTargetObjectFile.cpp8
-rw-r--r--lib/Target/Hexagon/HexagonTargetObjectFile.h1
-rw-r--r--lib/Target/Hexagon/HexagonVLIWPacketizer.cpp2078
-rw-r--r--lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp14
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h3
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp3
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h4
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp11
44 files changed, 3547 insertions, 6135 deletions
diff --git a/lib/Target/Hexagon/CMakeLists.txt b/lib/Target/Hexagon/CMakeLists.txt
index b5b887e..2b79791 100644
--- a/lib/Target/Hexagon/CMakeLists.txt
+++ b/lib/Target/Hexagon/CMakeLists.txt
@@ -9,8 +9,6 @@ tablegen(LLVM HexagonGenSubtargetInfo.inc -gen-subtarget)
tablegen(LLVM HexagonGenDFAPacketizer.inc -gen-dfa-packetizer)
add_public_tablegen_target(HexagonCommonTableGen)
-set(LLVM_COMMON_DEPENDS intrinsics_gen)
-
add_llvm_target(HexagonCodeGen
HexagonAsmPrinter.cpp
HexagonCallingConvLower.cpp
@@ -28,14 +26,18 @@ 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_dependencies(LLVMHexagonCodeGen HexagonCommonTableGen intrinsics_gen)
+
add_subdirectory(TargetInfo)
add_subdirectory(InstPrinter)
add_subdirectory(MCTargetDesc)
diff --git a/lib/Target/Hexagon/Hexagon.h b/lib/Target/Hexagon/Hexagon.h
index dfbefc8..5467ee3 100644
--- a/lib/Target/Hexagon/Hexagon.h
+++ b/lib/Target/Hexagon/Hexagon.h
@@ -31,24 +31,27 @@ namespace llvm {
FunctionPass *createHexagonISelDag(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 8a5ee40..568798c 100644
--- a/lib/Target/Hexagon/Hexagon.td
+++ b/lib/Target/Hexagon/Hexagon.td
@@ -84,27 +84,75 @@ 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.
//
def getPredNewOpcode : InstrMapping {
let FilterClass = "PredNewRel";
- let RowFields = ["BaseOpcode", "PredSense", "isNVStore"];
+ let RowFields = ["BaseOpcode", "PredSense", "isNVStore", "isBrTaken"];
let ColFields = ["PNewValue"];
let KeyCol = [""];
let ValueCols = [["new"]];
}
//===----------------------------------------------------------------------===//
+// 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 d4078ad..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";
@@ -52,8 +58,8 @@ private:
char HexagonCFGOptimizer::ID = 0;
static bool IsConditionalBranch(int Opc) {
- return (Opc == Hexagon::JMP_c) || (Opc == Hexagon::JMP_cNot)
- || (Opc == Hexagon::JMP_cdnPt) || (Opc == Hexagon::JMP_cdnNotPt);
+ return (Opc == Hexagon::JMP_t) || (Opc == Hexagon::JMP_f)
+ || (Opc == Hexagon::JMP_tnew_t) || (Opc == Hexagon::JMP_fnew_t);
}
@@ -68,20 +74,20 @@ HexagonCFGOptimizer::InvertAndChangeJumpTarget(MachineInstr* MI,
const HexagonInstrInfo *QII = QTM.getInstrInfo();
int NewOpcode = 0;
switch(MI->getOpcode()) {
- case Hexagon::JMP_c:
- NewOpcode = Hexagon::JMP_cNot;
+ case Hexagon::JMP_t:
+ NewOpcode = Hexagon::JMP_f;
break;
- case Hexagon::JMP_cNot:
- NewOpcode = Hexagon::JMP_c;
+ case Hexagon::JMP_f:
+ NewOpcode = Hexagon::JMP_t;
break;
- case Hexagon::JMP_cdnPt:
- NewOpcode = Hexagon::JMP_cdnNotPt;
+ case Hexagon::JMP_tnew_t:
+ NewOpcode = Hexagon::JMP_fnew_t;
break;
- case Hexagon::JMP_cdnNotPt:
- NewOpcode = Hexagon::JMP_cdnPt;
+ case Hexagon::JMP_fnew_t:
+ NewOpcode = Hexagon::JMP_tnew_t;
break;
default:
@@ -156,8 +162,8 @@ bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {
// The target of the unconditional branch must be JumpAroundTarget.
// TODO: If not, we should not invert the unconditional branch.
MachineBasicBlock* CondBranchTarget = NULL;
- if ((MI->getOpcode() == Hexagon::JMP_c) ||
- (MI->getOpcode() == Hexagon::JMP_cNot)) {
+ if ((MI->getOpcode() == Hexagon::JMP_t) ||
+ (MI->getOpcode() == Hexagon::JMP_f)) {
CondBranchTarget = MI->getOperand(1).getMBB();
}
@@ -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..f5f958c 100644
--- a/lib/Target/Hexagon/HexagonCallingConvLower.cpp
+++ b/lib/Target/Hexagon/HexagonCallingConvLower.cpp
@@ -25,14 +25,13 @@ using namespace llvm;
Hexagon_CCState::Hexagon_CCState(CallingConv::ID CC, bool isVarArg,
const TargetMachine &tm,
- SmallVector<CCValAssign, 16> &locs,
+ SmallVectorImpl<CCValAssign> &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..33c8306 100644
--- a/lib/Target/Hexagon/HexagonCallingConvLower.h
+++ b/lib/Target/Hexagon/HexagonCallingConvLower.h
@@ -48,15 +48,14 @@ class Hexagon_CCState {
CallingConv::ID CallingConv;
bool IsVarArg;
const TargetMachine &TM;
- const TargetRegisterInfo &TRI;
- SmallVector<CCValAssign, 16> &Locs;
+ SmallVectorImpl<CCValAssign> &Locs;
LLVMContext &Context;
unsigned StackOffset;
SmallVector<uint32_t, 16> UsedRegs;
public:
Hexagon_CCState(CallingConv::ID CC, bool isVarArg, const TargetMachine &TM,
- SmallVector<CCValAssign, 16> &locs, LLVMContext &c);
+ SmallVectorImpl<CCValAssign> &locs, LLVMContext &c);
void addLoc(const CCValAssign &V) {
Locs.push_back(V);
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 d6a9329..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::JMPR
+ 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/HexagonHardwareLoops.cpp b/lib/Target/Hexagon/HexagonHardwareLoops.cpp
index 62aed13..3c4ca0f 100644
--- a/lib/Target/Hexagon/HexagonHardwareLoops.cpp
+++ b/lib/Target/Hexagon/HexagonHardwareLoops.cpp
@@ -134,7 +134,7 @@ namespace {
/// has a computable trip count and, if so, return a value that represents
/// the trip count expression.
CountValue *getLoopTripCount(MachineLoop *L,
- SmallVector<MachineInstr*, 2> &OldInsts);
+ SmallVectorImpl<MachineInstr *> &OldInsts);
/// \brief Return the expression that represents the number of times
/// a loop iterates. The function takes the operands that represent the
@@ -164,7 +164,7 @@ namespace {
/// \brief Return true if the instruction is now dead.
bool isDead(const MachineInstr *MI,
- SmallVector<MachineInstr*, 1> &DeadPhis) const;
+ SmallVectorImpl<MachineInstr *> &DeadPhis) const;
/// \brief Remove the instruction if it is now dead.
void removeIfDead(MachineInstr *MI);
@@ -428,7 +428,7 @@ bool HexagonHardwareLoops::findInductionRegister(MachineLoop *L,
/// induction variable patterns that are used in the calculation for
/// the number of time the loop is executed.
CountValue *HexagonHardwareLoops::getLoopTripCount(MachineLoop *L,
- SmallVector<MachineInstr*, 2> &OldInsts) {
+ SmallVectorImpl<MachineInstr *> &OldInsts) {
MachineBasicBlock *TopMBB = L->getTopBlock();
MachineBasicBlock::pred_iterator PI = TopMBB->pred_begin();
assert(PI != TopMBB->pred_end() &&
@@ -541,12 +541,6 @@ CountValue *HexagonHardwareLoops::getLoopTripCount(MachineLoop *L,
case Hexagon::CMPEQrr:
Cmp = !Negated ? Comparison::EQ : Comparison::NE;
break;
- case Hexagon::CMPLTrr:
- Cmp = !Negated ? Comparison::LTs : Comparison::GEs;
- break;
- case Hexagon::CMPLTUrr:
- Cmp = !Negated ? Comparison::LTu : Comparison::GEu;
- break;
case Hexagon::CMPGTUri:
case Hexagon::CMPGTUrr:
Cmp = !Negated ? Comparison::GTu : Comparison::LEu;
@@ -701,7 +695,7 @@ CountValue *HexagonHardwareLoops::computeCount(MachineLoop *Loop,
// If the induction variable bump is not a power of 2, quit.
// Othwerise we'd need a general integer division.
- if (!isPowerOf2_64(abs(IVBump)))
+ if (!isPowerOf2_64(abs64(IVBump)))
return 0;
MachineBasicBlock *PH = Loop->getLoopPreheader();
@@ -896,7 +890,7 @@ bool HexagonHardwareLoops::containsInvalidInstruction(MachineLoop *L) const {
/// for inline asm, physical registers and instructions with side effects
/// removed.
bool HexagonHardwareLoops::isDead(const MachineInstr *MI,
- SmallVector<MachineInstr*, 1> &DeadPhis) const {
+ SmallVectorImpl<MachineInstr *> &DeadPhis) const {
// Examine each operand.
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
@@ -1125,8 +1119,8 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L) {
// The loop ends with either:
// - a conditional branch followed by an unconditional branch, or
// - a conditional branch to the loop start.
- if (LastI->getOpcode() == Hexagon::JMP_c ||
- LastI->getOpcode() == Hexagon::JMP_cNot) {
+ if (LastI->getOpcode() == Hexagon::JMP_t ||
+ LastI->getOpcode() == Hexagon::JMP_f) {
// Delete one and change/add an uncond. branch to out of the loop.
MachineBasicBlock *BranchTarget = LastI->getOperand(1).getMBB();
LastI = LastMBB->erase(LastI);
@@ -1430,7 +1424,6 @@ MachineBasicBlock *HexagonHardwareLoops::createPreheaderForLoop(
return 0;
typedef MachineBasicBlock::instr_iterator instr_iterator;
- typedef MachineBasicBlock::pred_iterator pred_iterator;
// Verify that all existing predecessors have analyzable branches
// (or no branches at all).
diff --git a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
index 3a1c48b..9e78e51 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,
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);
@@ -113,6 +111,46 @@ public:
SDNode *SelectAdd(SDNode *N);
bool isConstExtProfitable(SDNode *N) const;
+// XformMskToBitPosU5Imm - Returns the bit position which
+// the single bit 32 bit mask represents.
+// Used in Clr and Set bit immediate memops.
+SDValue XformMskToBitPosU5Imm(uint32_t Imm) {
+ int32_t bitPos;
+ bitPos = Log2_32(Imm);
+ assert(bitPos >= 0 && bitPos < 32 &&
+ "Constant out of range for 32 BitPos Memops");
+ return CurDAG->getTargetConstant(bitPos, MVT::i32);
+}
+
+// XformMskToBitPosU4Imm - Returns the bit position which the single bit 16 bit
+// mask represents. Used in Clr and Set bit immediate memops.
+SDValue XformMskToBitPosU4Imm(uint16_t Imm) {
+ return XformMskToBitPosU5Imm(Imm);
+}
+
+// XformMskToBitPosU3Imm - Returns the bit position which the single bit 8 bit
+// mask represents. Used in Clr and Set bit immediate memops.
+SDValue XformMskToBitPosU3Imm(uint8_t Imm) {
+ return XformMskToBitPosU5Imm(Imm);
+}
+
+// Return true if there is exactly one bit set in V, i.e., if V is one of the
+// following integers: 2^0, 2^1, ..., 2^31.
+bool ImmIsSingleBit(uint32_t v) const {
+ uint32_t c = CountPopulation_64(v);
+ // Only return true if we counted 1 bit.
+ return c == 1;
+}
+
+// XformM5ToU5Imm - Return a target constant with the specified value, of type
+// i32 where the negative literal is transformed into a positive literal for
+// use in -= memops.
+inline SDValue XformM5ToU5Imm(signed Imm) {
+ assert( (Imm >= -31 && Imm <= -1) && "Constant out of range for Memops");
+ return CurDAG->getTargetConstant( - Imm, MVT::i32);
+}
+
+
// XformU7ToU7M1Imm - Return a target constant decremented by 1, in range
// [1..128], used in cmpb.gtu instructions.
inline SDValue XformU7ToU7M1Imm(signed Imm) {
@@ -120,6 +158,17 @@ inline SDValue XformU7ToU7M1Imm(signed Imm) {
return CurDAG->getTargetConstant(Imm - 1, MVT::i8);
}
+// XformS8ToS8M1Imm - Return a target constant decremented by 1.
+inline SDValue XformSToSM1Imm(signed Imm) {
+ return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
+}
+
+// XformU8ToU8M1Imm - Return a target constant decremented by 1.
+inline SDValue XformUToUM1Imm(unsigned Imm) {
+ assert((Imm >= 1) && "Cannot decrement unsigned int less than 1");
+ return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
+}
+
// Include the pieces autogenerated from the target description.
#include "HexagonGenDAGISel.inc"
};
@@ -334,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;
@@ -345,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 = getTargetLowering()->getPointerTy();
const GlobalValue* GV =
cast<GlobalAddressSDNode>(Base)->getGlobal();
SDValue TargAddr =
@@ -382,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();
@@ -393,8 +442,11 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
SDValue N1 = LD->getOperand(1);
SDValue CPTmpN1_0;
SDValue CPTmpN1_1;
+
if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
N1.getNode()->getValueType(0) == MVT::i32) {
+ const HexagonInstrInfo *TII =
+ static_cast<const HexagonInstrInfo*>(TM.getInstrInfo());
if (TII->isValidAutoIncImm(LoadedVT, Val)) {
SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
@@ -446,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();
@@ -457,8 +509,11 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
SDValue N1 = LD->getOperand(1);
SDValue CPTmpN1_0;
SDValue CPTmpN1_1;
+
if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
N1.getNode()->getValueType(0) == MVT::i32) {
+ const HexagonInstrInfo *TII =
+ static_cast<const HexagonInstrInfo*>(TM.getInstrInfo());
if (TII->isValidAutoIncImm(LoadedVT, Val)) {
SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
@@ -521,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();
@@ -535,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;
@@ -616,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();
@@ -631,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();
@@ -643,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};
@@ -657,7 +716,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) {
// Build post increment store.
SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
- MVT::Other, Ops, 4);
+ MVT::Other, Ops);
MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
MemOp[0] = ST->getMemOperand();
cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
@@ -683,8 +742,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) {
// Build regular store.
SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
- SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops,
- 4);
+ SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
// Build splitted incriment instruction.
SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
Base,
@@ -701,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();
@@ -719,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 = getTargetLowering()->getPointerTy();
const GlobalValue* GV =
cast<GlobalAddressSDNode>(Base)->getGlobal();
SDValue TargAddr =
@@ -740,7 +798,7 @@ SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
Value, Chain};
// build indexed store
SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
- MVT::Other, Ops, 4);
+ MVT::Other, Ops);
MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
MemOp[0] = ST->getMemOperand();
cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
@@ -755,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();
@@ -768,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
@@ -852,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);
@@ -919,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);
//
@@ -1032,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);
@@ -1108,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 =
@@ -1151,7 +1209,7 @@ 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);
@@ -1159,6 +1217,8 @@ SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
// as at least one of the operands.
if (IntrinsicWithPred) {
SmallVector<SDValue, 8> Ops;
+ const HexagonInstrInfo *TII =
+ static_cast<const HexagonInstrInfo*>(TM.getInstrInfo());
const MCInstrDesc &MCID = TII->get(IntrinsicWithPred);
const TargetRegisterInfo *TRI = TM.getRegisterInfo();
@@ -1190,8 +1250,7 @@ SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
}
EVT ReturnValueVT = N->getValueType(0);
SDNode *Result = CurDAG->getMachineNode(IntrinsicWithPred, dl,
- ReturnValueVT,
- Ops.data(), Ops.size());
+ ReturnValueVT, Ops);
ReplaceUses(N, Result);
return Result;
}
@@ -1202,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) {
@@ -1222,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();
@@ -1261,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);
}
@@ -1611,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 0a8b1af..567faca 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,10 +382,10 @@ SDValue
HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
- DebugLoc &dl = CLI.DL;
- SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs;
- SmallVector<SDValue, 32> &OutVals = CLI.OutVals;
- SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins;
+ SDLoc &dl = CLI.DL;
+ SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
+ SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
SDValue Callee = CLI.Callee;
bool &isTailCall = CLI.IsTailCall;
@@ -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);
@@ -1002,17 +1002,9 @@ HexagonTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
return FrameAddr;
}
-
-SDValue HexagonTargetLowering::LowerMEMBARRIER(SDValue Op,
- SelectionDAG& DAG) const {
- DebugLoc dl = Op.getDebugLoc();
- return DAG.getNode(HexagonISD::BARRIER, dl, MVT::Other, Op.getOperand(0));
-}
-
-
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));
}
@@ -1022,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 =
@@ -1038,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 +1353,6 @@ HexagonTargetLowering::HexagonTargetLowering(HexagonTargetMachine
}
- setOperationAction(ISD::BRIND, MVT::Other, Expand);
if (EmitJumpTables) {
setOperationAction(ISD::BR_JT, MVT::Other, Custom);
} else {
@@ -1374,8 +1365,8 @@ HexagonTargetLowering::HexagonTargetLowering(HexagonTargetMachine
setOperationAction(ISD::BR_CC, MVT::f64, Expand);
setOperationAction(ISD::BR_CC, MVT::i1, Expand);
setOperationAction(ISD::BR_CC, MVT::i32, Expand);
+ setOperationAction(ISD::BR_CC, MVT::i64, Expand);
- setOperationAction(ISD::MEMBARRIER, MVT::Other, Custom);
setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
setOperationAction(ISD::FSIN , MVT::f64, Expand);
@@ -1437,12 +1428,7 @@ HexagonTargetLowering::HexagonTargetLowering(HexagonTargetMachine
setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
- setOperationAction(ISD::EXCEPTIONADDR, MVT::i64, Expand);
- setOperationAction(ISD::EHSELECTION, MVT::i64, Expand);
- setOperationAction(ISD::EXCEPTIONADDR, MVT::i32, Expand);
- setOperationAction(ISD::EHSELECTION, MVT::i32, Expand);
-
- setOperationAction(ISD::EH_RETURN, MVT::Other, Expand);
+ setOperationAction(ISD::EH_RETURN, MVT::Other, Custom);
if (TM.getSubtargetImpl()->isSubtargetV2()) {
setExceptionPointerRegister(Hexagon::R20);
@@ -1497,6 +1483,7 @@ HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const {
case HexagonISD::RET_FLAG: return "HexagonISD::RET_FLAG";
case HexagonISD::BR_JT: return "HexagonISD::BR_JT";
case HexagonISD::TC_RETURN: return "HexagonISD::TC_RETURN";
+ case HexagonISD::EH_RETURN: return "HexagonISD::EH_RETURN";
}
}
@@ -1517,17 +1504,57 @@ bool HexagonTargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
return ((VT1.getSimpleVT() == MVT::i64) && (VT2.getSimpleVT() == MVT::i32));
}
+bool
+HexagonTargetLowering::allowTruncateForTailCall(Type *Ty1, Type *Ty2) const {
+ // Assuming the caller does not have either a signext or zeroext modifier, and
+ // only one value is accepted, any reasonable truncation is allowed.
+ if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
+ return false;
+
+ // FIXME: in principle up to 64-bit could be made safe, but it would be very
+ // fragile at the moment: any support for multiple value returns would be
+ // liable to disallow tail calls involving i64 -> iN truncation in many cases.
+ return Ty1->getPrimitiveSizeInBits() <= 32;
+}
+
+SDValue
+HexagonTargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const {
+ SDValue Chain = Op.getOperand(0);
+ SDValue Offset = Op.getOperand(1);
+ SDValue Handler = Op.getOperand(2);
+ SDLoc dl(Op);
+
+ // Mark function as containing a call to EH_RETURN.
+ HexagonMachineFunctionInfo *FuncInfo =
+ DAG.getMachineFunction().getInfo<HexagonMachineFunctionInfo>();
+ FuncInfo->setHasEHReturn();
+
+ unsigned OffsetReg = Hexagon::R28;
+
+ SDValue StoreAddr = DAG.getNode(ISD::ADD, dl, getPointerTy(),
+ DAG.getRegister(Hexagon::R30, getPointerTy()),
+ DAG.getIntPtrConstant(4));
+ Chain = DAG.getStore(Chain, dl, Handler, StoreAddr, MachinePointerInfo(),
+ false, false, 0);
+ Chain = DAG.getCopyToReg(Chain, dl, OffsetReg, Offset);
+
+ // Not needed we already use it as explict input to EH_RETURN.
+ // MF.getRegInfo().addLiveOut(OffsetReg);
+
+ return DAG.getNode(HexagonISD::EH_RETURN, dl, MVT::Other, Chain);
+}
+
SDValue
HexagonTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
switch (Op.getOpcode()) {
default: llvm_unreachable("Should not custom lower this!");
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
+ case ISD::EH_RETURN: return LowerEH_RETURN(Op, DAG);
// Frame & Return address. Currently unimplemented.
case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
case ISD::GlobalTLSAddress:
llvm_unreachable("TLS not implemented for Hexagon.");
- case ISD::MEMBARRIER: return LowerMEMBARRIER(Op, DAG);
case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG);
case ISD::GlobalAddress: return LowerGLOBALADDRESS(Op, DAG);
case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
@@ -1571,11 +1598,11 @@ const {
std::pair<unsigned, const TargetRegisterClass*>
HexagonTargetLowering::getRegForInlineAsmConstraint(const
std::string &Constraint,
- EVT VT) const {
+ MVT VT) const {
if (Constraint.size() == 1) {
switch (Constraint[0]) {
case 'r': // R0-R31
- switch (VT.getSimpleVT().SimpleTy) {
+ switch (VT.SimpleTy) {
default:
llvm_unreachable("getRegForInlineAsmConstraint Unhandled data type");
case MVT::i32:
diff --git a/lib/Target/Hexagon/HexagonISelLowering.h b/lib/Target/Hexagon/HexagonISelLowering.h
index 3279cc6..4fe0107 100644
--- a/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/lib/Target/Hexagon/HexagonISelLowering.h
@@ -62,7 +62,8 @@ namespace llvm {
WrapperShuffEH,
WrapperShuffOB,
WrapperShuffOH,
- TC_RETURN
+ TC_RETURN,
+ EH_RETURN
};
}
@@ -94,6 +95,8 @@ namespace llvm {
virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const;
virtual bool isTruncateFree(EVT VT1, EVT VT2) const;
+ virtual bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const;
+
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
virtual const char *getTargetNodeName(unsigned Opcode) const;
@@ -101,10 +104,11 @@ namespace llvm {
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerEH_LABEL(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
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;
@@ -115,14 +119,13 @@ 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;
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerMEMBARRIER(SDValue Op, SelectionDAG& DAG) const;
SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
@@ -130,7 +133,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,
@@ -138,7 +141,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;
}
@@ -149,7 +152,7 @@ namespace llvm {
std::pair<unsigned, const TargetRegisterClass*>
getRegForInlineAsmConstraint(const std::string &Constraint,
- EVT VT) const;
+ MVT VT) const;
// Intrinsics
virtual SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op,
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 96a252e..5af645c 100644
--- a/lib/Target/Hexagon/HexagonInstrInfo.cpp
+++ b/lib/Target/Hexagon/HexagonInstrInfo.cpp
@@ -23,7 +23,9 @@
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#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"
@@ -56,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) {
}
@@ -118,16 +120,16 @@ HexagonInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
DebugLoc DL) const{
int BOpc = Hexagon::JMP;
- int BccOpc = Hexagon::JMP_c;
+ int BccOpc = Hexagon::JMP_t;
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
int regPos = 0;
// Check if ReverseBranchCondition has asked to reverse this branch
// If we want to reverse the branch an odd number of times, we want
- // JMP_cNot.
+ // JMP_f.
if (!Cond.empty() && Cond[0].isImm() && Cond[0].getImm() == 0) {
- BccOpc = Hexagon::JMP_cNot;
+ BccOpc = Hexagon::JMP_f;
regPos = 1;
}
@@ -174,8 +176,8 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
FBB = NULL;
// If the block has no terminators, it just falls into the block after it.
- MachineBasicBlock::iterator I = MBB.end();
- if (I == MBB.begin())
+ MachineBasicBlock::instr_iterator I = MBB.instr_end();
+ if (I == MBB.instr_begin())
return false;
// A basic block may looks like this:
@@ -194,13 +196,24 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
--I;
if (I->isEHLabel())
return true;
- } while (I != MBB.begin());
+ } while (I != MBB.instr_begin());
- I = MBB.end();
+ I = MBB.instr_end();
--I;
while (I->isDebugValue()) {
- if (I == MBB.begin())
+ if (I == MBB.instr_begin())
+ return false;
+ --I;
+ }
+
+ // Delete the JMP if it's equivalent to a fall-through.
+ if (AllowModify && I->getOpcode() == Hexagon::JMP &&
+ MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
+ DEBUG(dbgs()<< "\nErasing the jump to successor block\n";);
+ I->eraseFromParent();
+ I = MBB.instr_end();
+ if (I == MBB.instr_begin())
return false;
--I;
}
@@ -209,23 +222,42 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
// Get the last instruction in the block.
MachineInstr *LastInst = I;
+ MachineInstr *SecondLastInst = NULL;
+ // Find one more terminator if present.
+ do {
+ if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(I)) {
+ if (!SecondLastInst)
+ SecondLastInst = I;
+ else
+ // This is a third branch.
+ return true;
+ }
+ if (I == MBB.instr_begin())
+ break;
+ --I;
+ } while(I);
+
+ int LastOpcode = LastInst->getOpcode();
+
+ bool LastOpcodeHasJMP_c = PredOpcodeHasJMP_c(LastOpcode);
+ bool LastOpcodeHasNot = PredOpcodeHasNot(LastOpcode);
// If there is only one terminator instruction, process it.
- if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
- if (LastInst->getOpcode() == Hexagon::JMP) {
+ if (LastInst && !SecondLastInst) {
+ if (LastOpcode == Hexagon::JMP) {
TBB = LastInst->getOperand(0).getMBB();
return false;
}
- if (LastInst->getOpcode() == Hexagon::JMP_c) {
- // Block ends with fall-through true condbranch.
- TBB = LastInst->getOperand(1).getMBB();
+ if (LastOpcode == Hexagon::ENDLOOP0) {
+ TBB = LastInst->getOperand(0).getMBB();
Cond.push_back(LastInst->getOperand(0));
return false;
}
- if (LastInst->getOpcode() == Hexagon::JMP_cNot) {
- // Block ends with fall-through false condbranch.
+ if (LastOpcodeHasJMP_c) {
TBB = LastInst->getOperand(1).getMBB();
- Cond.push_back(MachineOperand::CreateImm(0));
+ if (LastOpcodeHasNot) {
+ Cond.push_back(MachineOperand::CreateImm(0));
+ }
Cond.push_back(LastInst->getOperand(0));
return false;
}
@@ -233,29 +265,14 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
return true;
}
- // Get the instruction before it if it's a terminator.
- MachineInstr *SecondLastInst = I;
-
- // If there are three terminators, we don't know what sort of block this is.
- if (SecondLastInst && I != MBB.begin() &&
- isUnpredicatedTerminator(--I))
- return true;
+ int SecLastOpcode = SecondLastInst->getOpcode();
- // If the block ends with Hexagon::BRCOND and Hexagon:JMP, handle it.
- if (((SecondLastInst->getOpcode() == Hexagon::BRCOND) ||
- (SecondLastInst->getOpcode() == Hexagon::JMP_c)) &&
- LastInst->getOpcode() == Hexagon::JMP) {
+ bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);
+ bool SecLastOpcodeHasNot = PredOpcodeHasNot(SecLastOpcode);
+ if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::JMP)) {
TBB = SecondLastInst->getOperand(1).getMBB();
- Cond.push_back(SecondLastInst->getOperand(0));
- FBB = LastInst->getOperand(0).getMBB();
- return false;
- }
-
- // If the block ends with Hexagon::JMP_cNot and Hexagon:JMP, handle it.
- if ((SecondLastInst->getOpcode() == Hexagon::JMP_cNot) &&
- LastInst->getOpcode() == Hexagon::JMP) {
- TBB = SecondLastInst->getOperand(1).getMBB();
- Cond.push_back(MachineOperand::CreateImm(0));
+ if (SecLastOpcodeHasNot)
+ Cond.push_back(MachineOperand::CreateImm(0));
Cond.push_back(SecondLastInst->getOperand(0));
FBB = LastInst->getOperand(0).getMBB();
return false;
@@ -263,8 +280,7 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
// If the block ends with two Hexagon:JMPs, handle it. The second one is not
// executed, so remove it.
- if (SecondLastInst->getOpcode() == Hexagon::JMP &&
- LastInst->getOpcode() == Hexagon::JMP) {
+ if (SecLastOpcode == Hexagon::JMP && LastOpcode == Hexagon::JMP) {
TBB = SecondLastInst->getOperand(0).getMBB();
I = LastInst;
if (AllowModify)
@@ -272,6 +288,15 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
return false;
}
+ // If the block ends with an ENDLOOP, and JMP, handle it.
+ if (SecLastOpcode == Hexagon::ENDLOOP0 &&
+ LastOpcode == Hexagon::JMP) {
+ TBB = SecondLastInst->getOperand(0).getMBB();
+ Cond.push_back(SecondLastInst->getOperand(0));
+ FBB = LastInst->getOperand(0).getMBB();
+ return false;
+ }
+
// Otherwise, can't handle this.
return true;
}
@@ -279,8 +304,8 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
unsigned HexagonInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
int BOpc = Hexagon::JMP;
- int BccOpc = Hexagon::JMP_c;
- int BccOpcNot = Hexagon::JMP_cNot;
+ int BccOpc = Hexagon::JMP_t;
+ int BccOpcNot = Hexagon::JMP_f;
MachineBasicBlock::iterator I = MBB.end();
if (I == MBB.begin()) return 0;
@@ -325,8 +350,6 @@ bool HexagonInstrInfo::analyzeCompare(const MachineInstr *MI,
case Hexagon::CMPGTUrr:
case Hexagon::CMPGTri:
case Hexagon::CMPGTrr:
- case Hexagon::CMPLTUrr:
- case Hexagon::CMPLTrr:
SrcReg = MI->getOperand(1).getReg();
Mask = ~0;
break;
@@ -366,8 +389,6 @@ bool HexagonInstrInfo::analyzeCompare(const MachineInstr *MI,
case Hexagon::CMPhEQrr_xor_V4:
case Hexagon::CMPhGTUrr_V4:
case Hexagon::CMPhGTrr_shl_V4:
- case Hexagon::CMPLTUrr:
- case Hexagon::CMPLTrr:
SrcReg2 = MI->getOperand(2).getReg();
return true;
@@ -537,7 +558,6 @@ MachineInstr *HexagonInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
return(0);
}
-
unsigned HexagonInstrInfo::createVR(MachineFunction* MF, MVT VT) const {
MachineRegisterInfo &RegInfo = MF->getRegInfo();
@@ -596,307 +616,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:
- case Hexagon::STrib_imm_abs_nv_V4:
- case Hexagon::STrib_imm_abs_cPt_nv_V4:
- case Hexagon::STrib_imm_abs_cdnPt_nv_V4:
- case Hexagon::STrib_imm_abs_cNotPt_nv_V4:
- case Hexagon::STrib_imm_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:
- case Hexagon::STrih_imm_abs_nv_V4:
- case Hexagon::STrih_imm_abs_cPt_nv_V4:
- case Hexagon::STrih_imm_abs_cdnPt_nv_V4:
- case Hexagon::STrih_imm_abs_cNotPt_nv_V4:
- case Hexagon::STrih_imm_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:
- case Hexagon::STriw_imm_abs_nv_V4:
- case Hexagon::STriw_imm_abs_cPt_nv_V4:
- case Hexagon::STriw_imm_abs_cdnPt_nv_V4:
- case Hexagon::STriw_imm_abs_cNotPt_nv_V4:
- case Hexagon::STriw_imm_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 {
@@ -994,9 +715,6 @@ bool HexagonInstrInfo::isPredicable(MachineInstr *MI) const {
case Hexagon::ZXTB:
case Hexagon::ZXTH:
return Subtarget.hasV4TOps();
-
- case Hexagon::JMPR:
- return false;
}
return true;
@@ -1007,466 +725,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_c:
- return Hexagon::JMP_cNot;
- case Hexagon::JMP_cNot:
- return Hexagon::JMP_c;
-
- 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_cPt:
- return Hexagon::JMPR_cNotPt;
- case Hexagon::JMPR_cNotPt:
- return Hexagon::JMPR_cPt;
-
- // 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 {
@@ -1480,223 +772,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_c :
- Hexagon::JMP_cNot;
- 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_cPt :
- Hexagon::JMPR_cNotPt;
-
- // 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 :
@@ -1821,11 +911,15 @@ PredicateInstruction(MachineInstr *MI,
// It is better to have an assert here to check this. But I don't know how
// to write this assert because findFirstPredOperandIdx() would return -1
if (oper < -1) oper = -1;
+
MI->getOperand(oper+1).ChangeToRegister(PredMO.getReg(), PredMO.isDef(),
- PredMO.isImplicit(), PredMO.isKill(),
+ PredMO.isImplicit(), false,
PredMO.isDead(), PredMO.isUndef(),
PredMO.isDebug());
+ MachineRegisterInfo &RegInfo = MI->getParent()->getParent()->getRegInfo();
+ RegInfo.clearKillFlags(PredMO.getReg());
+
if (hasGAOpnd)
{
unsigned int i;
@@ -1874,13 +968,65 @@ 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;
+
+ assert(isPredicated(MI));
+ 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 {
@@ -1991,46 +1137,28 @@ isValidOffset(const int Opcode, const int Offset) const {
return (Offset >= Hexagon_ADDI_OFFSET_MIN) &&
(Offset <= Hexagon_ADDI_OFFSET_MAX);
- case Hexagon::MEMw_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMw_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMw_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMw_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMw_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMw_ORr_indexed_MEM_V4 :
- case Hexagon::MEMw_ADDi_MEM_V4 :
- case Hexagon::MEMw_SUBi_MEM_V4 :
- case Hexagon::MEMw_ADDr_MEM_V4 :
- case Hexagon::MEMw_SUBr_MEM_V4 :
- case Hexagon::MEMw_ANDr_MEM_V4 :
- case Hexagon::MEMw_ORr_MEM_V4 :
+ case Hexagon::MemOPw_ADDi_V4 :
+ case Hexagon::MemOPw_SUBi_V4 :
+ case Hexagon::MemOPw_ADDr_V4 :
+ case Hexagon::MemOPw_SUBr_V4 :
+ case Hexagon::MemOPw_ANDr_V4 :
+ case Hexagon::MemOPw_ORr_V4 :
return (0 <= Offset && Offset <= 255);
- case Hexagon::MEMh_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMh_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMh_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMh_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMh_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMh_ORr_indexed_MEM_V4 :
- case Hexagon::MEMh_ADDi_MEM_V4 :
- case Hexagon::MEMh_SUBi_MEM_V4 :
- case Hexagon::MEMh_ADDr_MEM_V4 :
- case Hexagon::MEMh_SUBr_MEM_V4 :
- case Hexagon::MEMh_ANDr_MEM_V4 :
- case Hexagon::MEMh_ORr_MEM_V4 :
+ case Hexagon::MemOPh_ADDi_V4 :
+ case Hexagon::MemOPh_SUBi_V4 :
+ case Hexagon::MemOPh_ADDr_V4 :
+ case Hexagon::MemOPh_SUBr_V4 :
+ case Hexagon::MemOPh_ANDr_V4 :
+ case Hexagon::MemOPh_ORr_V4 :
return (0 <= Offset && Offset <= 127);
- case Hexagon::MEMb_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMb_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMb_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMb_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMb_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMb_ORr_indexed_MEM_V4 :
- case Hexagon::MEMb_ADDi_MEM_V4 :
- case Hexagon::MEMb_SUBi_MEM_V4 :
- case Hexagon::MEMb_ADDr_MEM_V4 :
- case Hexagon::MEMb_SUBr_MEM_V4 :
- case Hexagon::MEMb_ANDr_MEM_V4 :
- case Hexagon::MEMb_ORr_MEM_V4 :
+ case Hexagon::MemOPb_ADDi_V4 :
+ case Hexagon::MemOPb_SUBi_V4 :
+ case Hexagon::MemOPb_ADDr_V4 :
+ case Hexagon::MemOPb_SUBr_V4 :
+ case Hexagon::MemOPb_ANDr_V4 :
+ case Hexagon::MemOPb_ORr_V4 :
return (0 <= Offset && Offset <= 63);
// LDri_pred and STriw_pred are pseudo operations, so it has to take offset of
@@ -2083,47 +1211,38 @@ 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;
- case Hexagon::MEMw_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMw_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMw_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMw_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMw_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMw_ORr_indexed_MEM_V4 :
- case Hexagon::MEMw_ADDi_MEM_V4 :
- case Hexagon::MEMw_SUBi_MEM_V4 :
- case Hexagon::MEMw_ADDr_MEM_V4 :
- case Hexagon::MEMw_SUBr_MEM_V4 :
- case Hexagon::MEMw_ANDr_MEM_V4 :
- case Hexagon::MEMw_ORr_MEM_V4 :
- case Hexagon::MEMh_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMh_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMh_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMh_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMh_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMh_ORr_indexed_MEM_V4 :
- case Hexagon::MEMh_ADDi_MEM_V4 :
- case Hexagon::MEMh_SUBi_MEM_V4 :
- case Hexagon::MEMh_ADDr_MEM_V4 :
- case Hexagon::MEMh_SUBr_MEM_V4 :
- case Hexagon::MEMh_ANDr_MEM_V4 :
- case Hexagon::MEMh_ORr_MEM_V4 :
- case Hexagon::MEMb_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMb_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMb_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMb_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMb_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMb_ORr_indexed_MEM_V4 :
- case Hexagon::MEMb_ADDi_MEM_V4 :
- case Hexagon::MEMb_SUBi_MEM_V4 :
- case Hexagon::MEMb_ADDr_MEM_V4 :
- case Hexagon::MEMb_SUBr_MEM_V4 :
- case Hexagon::MEMb_ANDr_MEM_V4 :
- case Hexagon::MEMb_ORr_MEM_V4 :
- return true;
+ case Hexagon::MemOPw_ADDi_V4 :
+ case Hexagon::MemOPw_SUBi_V4 :
+ case Hexagon::MemOPw_ADDr_V4 :
+ case Hexagon::MemOPw_SUBr_V4 :
+ case Hexagon::MemOPw_ANDr_V4 :
+ case Hexagon::MemOPw_ORr_V4 :
+ case Hexagon::MemOPh_ADDi_V4 :
+ case Hexagon::MemOPh_SUBi_V4 :
+ case Hexagon::MemOPh_ADDr_V4 :
+ case Hexagon::MemOPh_SUBr_V4 :
+ case Hexagon::MemOPh_ANDr_V4 :
+ case Hexagon::MemOPh_ORr_V4 :
+ case Hexagon::MemOPb_ADDi_V4 :
+ case Hexagon::MemOPb_SUBi_V4 :
+ case Hexagon::MemOPb_ADDr_V4 :
+ case Hexagon::MemOPb_SUBr_V4 :
+ case Hexagon::MemOPb_ANDr_V4 :
+ case Hexagon::MemOPb_ORr_V4 :
+ case Hexagon::MemOPb_SETBITi_V4:
+ case Hexagon::MemOPh_SETBITi_V4:
+ case Hexagon::MemOPw_SETBITi_V4:
+ case Hexagon::MemOPb_CLRBITi_V4:
+ case Hexagon::MemOPh_CLRBITi_V4:
+ case Hexagon::MemOPw_CLRBITi_V4:
+ return true;
}
+ return false;
}
@@ -2142,14 +1261,10 @@ bool HexagonInstrInfo::isNewValueJumpCandidate(const MachineInstr *MI) const {
default: return false;
case Hexagon::CMPEQrr:
case Hexagon::CMPEQri:
- case Hexagon::CMPLTrr:
case Hexagon::CMPGTrr:
case Hexagon::CMPGTri:
- case Hexagon::CMPLTUrr:
case Hexagon::CMPGTUrr:
case Hexagon::CMPGTUri:
- case Hexagon::CMPGEri:
- case Hexagon::CMPGEUri:
return true;
}
}
@@ -2382,6 +1497,120 @@ 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 {
+ return (isNewValueInst(MI) ||
+ (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;
@@ -2476,6 +1705,34 @@ bool HexagonInstrInfo::isConstExtended(MachineInstr *MI) const {
return (ImmValue < MinValue || ImmValue > MaxValue);
}
+// Returns the opcode to use when converting MI, which is a conditional jump,
+// into a conditional instruction which uses the .new value of the predicate.
+// We also use branch probabilities to add a hint to the jump.
+int
+HexagonInstrInfo::getDotNewPredJumpOp(MachineInstr *MI,
+ const
+ MachineBranchProbabilityInfo *MBPI) const {
+
+ // We assume that block can have at most two successors.
+ bool taken = false;
+ MachineBasicBlock *Src = MI->getParent();
+ MachineOperand *BrTarget = &MI->getOperand(1);
+ MachineBasicBlock *Dst = BrTarget->getMBB();
+
+ const BranchProbability Prediction = MBPI->getEdgeProbability(Src, Dst);
+ if (Prediction >= BranchProbability(1,2))
+ taken = true;
+
+ switch (MI->getOpcode()) {
+ case Hexagon::JMP_t:
+ return taken ? Hexagon::JMP_tnew_t : Hexagon::JMP_tnew_nt;
+ case Hexagon::JMP_f:
+ return taken ? Hexagon::JMP_fnew_t : Hexagon::JMP_fnew_nt;
+
+ default:
+ llvm_unreachable("Unexpected jump instruction.");
+ }
+}
// Returns true if a particular operand is extendable for an instruction.
bool HexagonInstrInfo::isOperandExtended(const MachineInstr *MI,
unsigned short OperandNum) const {
@@ -2580,3 +1837,18 @@ short HexagonInstrInfo::getNonExtOpcode (const MachineInstr *MI) const {
}
return -1;
}
+
+bool HexagonInstrInfo::PredOpcodeHasJMP_c(Opcode_t Opcode) const {
+ return (Opcode == Hexagon::JMP_t) ||
+ (Opcode == Hexagon::JMP_f) ||
+ (Opcode == Hexagon::JMP_tnew_t) ||
+ (Opcode == Hexagon::JMP_fnew_t) ||
+ (Opcode == Hexagon::JMP_tnew_nt) ||
+ (Opcode == Hexagon::JMP_fnew_nt);
+}
+
+bool HexagonInstrInfo::PredOpcodeHasNot(Opcode_t Opcode) const {
+ return (Opcode == Hexagon::JMP_f) ||
+ (Opcode == Hexagon::JMP_fnew_t) ||
+ (Opcode == Hexagon::JMP_fnew_nt);
+}
diff --git a/lib/Target/Hexagon/HexagonInstrInfo.h b/lib/Target/Hexagon/HexagonInstrInfo.h
index d2f059a..3c28df4 100644
--- a/lib/Target/Hexagon/HexagonInstrInfo.h
+++ b/lib/Target/Hexagon/HexagonInstrInfo.h
@@ -16,9 +16,9 @@
#include "HexagonRegisterInfo.h"
#include "MCTargetDesc/HexagonBaseInfo.h"
-#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetInstrInfo.h"
-
+#include "llvm/Target/TargetFrameLowering.h"
+#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
#define GET_INSTRINFO_HEADER
#include "HexagonGenInstrInfo.inc"
@@ -27,7 +27,9 @@ namespace llvm {
class HexagonInstrInfo : public HexagonGenInstrInfo {
const HexagonRegisterInfo RI;
- const HexagonSubtarget& Subtarget;
+ const HexagonSubtarget &Subtarget;
+ typedef unsigned Opcode_t;
+
public:
explicit HexagonInstrInfo(HexagonSubtarget &ST);
@@ -111,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,
@@ -127,6 +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
@@ -170,18 +178,29 @@ 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;
void immediateExtend(MachineInstr *MI) const;
bool isConstExtended(MachineInstr *MI) const;
+ int getDotNewPredJumpOp(MachineInstr *MI,
+ const MachineBranchProbabilityInfo *MBPI) const;
unsigned getAddrMode(const MachineInstr* MI) const;
bool isOperandExtended(const MachineInstr *MI,
unsigned short OperandNum) const;
@@ -190,6 +209,9 @@ public:
int getMaxValue(const MachineInstr *MI) const;
bool NonExtEquivalentExists (const MachineInstr *MI) const;
short getNonExtOpcode(const MachineInstr *MI) const;
+ bool PredOpcodeHasJMP_c(Opcode_t Opcode) const;
+ bool PredOpcodeHasNot(Opcode_t Opcode) const;
+
private:
int getMatchingCondBranchOpcode(int Opc, bool sense) const;
diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td
index d7bab20..c96aaca 100644
--- a/lib/Target/Hexagon/HexagonInstrInfo.td
+++ b/lib/Target/Hexagon/HexagonInstrInfo.td
@@ -14,6 +14,8 @@
include "HexagonInstrFormats.td"
include "HexagonOperands.td"
+//===----------------------------------------------------------------------===//
+
// Multi-class for logical operators.
multiclass ALU32_rr_ri<string OpcStr, SDNode OpNode> {
def rr : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
@@ -34,12 +36,6 @@ multiclass CMP64_rr<string OpcStr, PatFrag OpNode> {
[(set (i1 PredRegs:$dst),
(OpNode (i64 DoubleRegs:$b), (i64 DoubleRegs:$c)))]>;
}
-multiclass CMP32_rr<string OpcStr, PatFrag OpNode> {
- def rr : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
- !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
- [(set (i1 PredRegs:$dst),
- (OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>;
-}
multiclass CMP32_rr_ri_s10<string OpcStr, string CextOp, PatFrag OpNode> {
let CextOpcode = CextOp in {
@@ -75,14 +71,6 @@ multiclass CMP32_rr_ri_u9<string OpcStr, string CextOp, PatFrag OpNode> {
}
}
-multiclass CMP32_ri_u8<string OpcStr, PatFrag OpNode> {
-let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 8 in
- def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, u8Ext:$c),
- !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")),
- [(set (i1 PredRegs:$dst), (OpNode (i32 IntRegs:$b),
- u8ExtPred:$c))]>;
-}
-
multiclass CMP32_ri_s8<string OpcStr, PatFrag OpNode> {
let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8 in
def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s8Ext:$c),
@@ -95,22 +83,30 @@ let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8 in
//===----------------------------------------------------------------------===//
// ALU32/ALU (Instructions with register-register form)
//===----------------------------------------------------------------------===//
-multiclass ALU32_Pbase<string mnemonic, bit isNot,
- bit isPredNew> {
+def SDTHexagonI64I32I32 : SDTypeProfile<1, 2,
+ [SDTCisVT<0, i64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
+
+def HexagonWrapperCombineII :
+ SDNode<"HexagonISD::WrapperCombineII", SDTHexagonI64I32I32>;
- let PNewValue = !if(isPredNew, "new", "") in
- def NAME : ALU32_rr<(outs IntRegs:$dst),
+def HexagonWrapperCombineRR :
+ SDNode<"HexagonISD::WrapperCombineRR", SDTHexagonI64I32I32>;
+
+multiclass ALU32_Pbase<string mnemonic, RegisterClass RC, bit isNot,
+ bit isPredNew> {
+ let isPredicatedNew = isPredNew in
+ def NAME : ALU32_rr<(outs RC:$dst),
(ins PredRegs:$src1, IntRegs:$src2, IntRegs: $src3),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ",
") $dst = ")#mnemonic#"($src2, $src3)",
[]>;
}
-multiclass ALU32_Pred<string mnemonic, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
- defm _c#NAME : ALU32_Pbase<mnemonic, PredNot, 0>;
+multiclass ALU32_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
+ let isPredicatedFalse = PredNot in {
+ defm _c#NAME : ALU32_Pbase<mnemonic, RC, PredNot, 0>;
// Predicate new
- defm _cdn#NAME : ALU32_Pbase<mnemonic, PredNot, 1>;
+ defm _cdn#NAME : ALU32_Pbase<mnemonic, RC, PredNot, 1>;
}
}
@@ -125,8 +121,8 @@ multiclass ALU32_base<string mnemonic, string CextOp, SDNode OpNode> {
(i32 IntRegs:$src2)))]>;
let neverHasSideEffects = 1, isPredicated = 1 in {
- defm Pt : ALU32_Pred<mnemonic, 0>;
- defm NotPt : ALU32_Pred<mnemonic, 1>;
+ defm Pt : ALU32_Pred<mnemonic, IntRegs, 0>;
+ defm NotPt : ALU32_Pred<mnemonic, IntRegs, 1>;
}
}
}
@@ -140,11 +136,42 @@ let isCommutable = 1 in {
defm SUB_rr : ALU32_base<"sub", "SUB", sub>, ImmRegRel, PredNewRel;
+// Combines the two integer registers SRC1 and SRC2 into a double register.
+let isPredicable = 1 in
+class T_Combine : ALU32_rr<(outs DoubleRegs:$dst),
+ (ins IntRegs:$src1, IntRegs:$src2),
+ "$dst = combine($src1, $src2)",
+ [(set (i64 DoubleRegs:$dst),
+ (i64 (HexagonWrapperCombineRR (i32 IntRegs:$src1),
+ (i32 IntRegs:$src2))))]>;
+
+multiclass Combine_base {
+ let BaseOpcode = "combine" in {
+ def NAME : T_Combine;
+ let neverHasSideEffects = 1, isPredicated = 1 in {
+ defm Pt : ALU32_Pred<"combine", DoubleRegs, 0>;
+ defm NotPt : ALU32_Pred<"combine", DoubleRegs, 1>;
+ }
+ }
+}
+
+defm COMBINE_rr : Combine_base, PredNewRel;
+
+// Combines the two immediates SRC1 and SRC2 into a double register.
+class COMBINE_imm<Operand imm1, Operand imm2, PatLeaf pat1, PatLeaf pat2> :
+ ALU32_ii<(outs DoubleRegs:$dst), (ins imm1:$src1, imm2:$src2),
+ "$dst = combine(#$src1, #$src2)",
+ [(set (i64 DoubleRegs:$dst),
+ (i64 (HexagonWrapperCombineII (i32 pat1:$src1), (i32 pat2:$src2))))]>;
+
+let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 8 in
+def COMBINE_Ii : COMBINE_imm<s8Ext, s8Imm, s8ExtPred, s8ImmPred>;
+
//===----------------------------------------------------------------------===//
// ALU32/ALU (ADD with register-immediate form)
//===----------------------------------------------------------------------===//
multiclass ALU32ri_Pbase<string mnemonic, bit isNot, bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : ALU32_ri<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, s8Ext: $src3),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ",
@@ -153,7 +180,7 @@ multiclass ALU32ri_Pbase<string mnemonic, bit isNot, bit isPredNew> {
}
multiclass ALU32ri_Pred<string mnemonic, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ALU32ri_Pbase<mnemonic, PredNot, 0>;
// Predicate new
defm _cdn#NAME : ALU32ri_Pbase<mnemonic, PredNot, 1>;
@@ -189,11 +216,6 @@ def OR_ri : ALU32_ri<(outs IntRegs:$dst),
[(set (i32 IntRegs:$dst), (or (i32 IntRegs:$src1),
s10ExtPred:$src2))]>, ImmRegRel;
-def NOT_rr : ALU32_rr<(outs IntRegs:$dst),
- (ins IntRegs:$src1),
- "$dst = not($src1)",
- [(set (i32 IntRegs:$dst), (not (i32 IntRegs:$src1)))]>;
-
let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 10,
InputType = "imm", CextOpcode = "AND" in
def AND_ri : ALU32_ri<(outs IntRegs:$dst),
@@ -201,10 +223,7 @@ def AND_ri : ALU32_ri<(outs IntRegs:$dst),
"$dst = and($src1, #$src2)",
[(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1),
s10ExtPred:$src2))]>, ImmRegRel;
-// Negate.
-def NEG : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
- "$dst = neg($src1)",
- [(set (i32 IntRegs:$dst), (ineg (i32 IntRegs:$src1)))]>;
+
// Nop.
let neverHasSideEffects = 1 in
def NOP : ALU32_rr<(outs), (ins),
@@ -220,15 +239,21 @@ def SUB_ri : ALU32_ri<(outs IntRegs:$dst),
[(set IntRegs:$dst, (sub s10ExtPred:$src1, IntRegs:$src2))]>,
ImmRegRel;
+// Rd = not(Rs) gets mapped to Rd=sub(#-1, Rs).
+def : Pat<(not (i32 IntRegs:$src1)),
+ (SUB_ri -1, (i32 IntRegs:$src1))>;
+
+// Rd = neg(Rs) gets mapped to Rd=sub(#0, Rs).
+// Pattern definition for 'neg' was not necessary.
multiclass TFR_Pred<bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
def _c#NAME : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
!if(PredNot, "if (!$src1", "if ($src1")#") $dst = $src2",
[]>;
// Predicate new
- let PNewValue = "new" in
+ let isPredicatedNew = 1 in
def _cdn#NAME : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
!if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = $src2",
@@ -274,10 +299,10 @@ class T_TFR64_Pred<bit PredNot, bit isPredNew>
}
multiclass TFR64_Pred<bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
def _c#NAME : T_TFR64_Pred<PredNot, 0>;
- let PNewValue = "new" in
+ let isPredicatedNew = 1 in
def _cdn#NAME : T_TFR64_Pred<PredNot, 1>; // Predicate new
}
}
@@ -309,14 +334,14 @@ multiclass TFR64_base<string BaseName> {
}
multiclass TFRI_Pred<bit PredNot> {
- let isMoveImm = 1, PredSense = !if(PredNot, "false", "true") in {
+ let isMoveImm = 1, isPredicatedFalse = PredNot in {
def _c#NAME : ALU32_ri<(outs IntRegs:$dst),
(ins PredRegs:$src1, s12Ext:$src2),
!if(PredNot, "if (!$src1", "if ($src1")#") $dst = #$src2",
[]>;
// Predicate new
- let PNewValue = "new" in
+ let isPredicatedNew = 1 in
def _cdn#NAME : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, s12Ext:$src2),
!if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = #$src2",
@@ -359,51 +384,11 @@ def TFCR : CRInst<(outs CRRegs:$dst), (ins IntRegs:$src1),
// ALU32/PERM +
//===----------------------------------------------------------------------===//
-// Combine.
-
-def SDTHexagonI64I32I32 : SDTypeProfile<1, 2,
- [SDTCisVT<0, i64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
-
-def HexagonWrapperCombineII :
- SDNode<"HexagonISD::WrapperCombineII", SDTHexagonI64I32I32>;
-def HexagonWrapperCombineRR :
- SDNode<"HexagonISD::WrapperCombineRR", SDTHexagonI64I32I32>;
-
-// Combines the two integer registers SRC1 and SRC2 into a double register.
-let isPredicable = 1 in
-def COMBINE_rr : ALU32_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src1,
- IntRegs:$src2),
- "$dst = combine($src1, $src2)",
- [(set (i64 DoubleRegs:$dst),
- (i64 (HexagonWrapperCombineRR (i32 IntRegs:$src1),
- (i32 IntRegs:$src2))))]>;
-
-// Rd=combine(Rt.[HL], Rs.[HL])
-class COMBINE_halves<string A, string B>: ALU32_rr<(outs IntRegs:$dst),
- (ins IntRegs:$src1,
- IntRegs:$src2),
- "$dst = combine($src1."# A #", $src2."# B #")", []>;
-
-let isPredicable = 1 in {
- def COMBINE_hh : COMBINE_halves<"H", "H">;
- def COMBINE_hl : COMBINE_halves<"H", "L">;
- def COMBINE_lh : COMBINE_halves<"L", "H">;
- def COMBINE_ll : COMBINE_halves<"L", "L">;
-}
-
-def : Pat<(i32 (trunc (i64 (srl (i64 DoubleRegs:$a), (i32 16))))),
- (COMBINE_lh (EXTRACT_SUBREG (i64 DoubleRegs:$a), subreg_hireg),
- (EXTRACT_SUBREG (i64 DoubleRegs:$a), subreg_loreg))>;
-
-// Combines the two immediates SRC1 and SRC2 into a double register.
-class COMBINE_imm<Operand imm1, Operand imm2, PatLeaf pat1, PatLeaf pat2> :
- ALU32_ii<(outs DoubleRegs:$dst), (ins imm1:$src1, imm2:$src2),
- "$dst = combine(#$src1, #$src2)",
- [(set (i64 DoubleRegs:$dst),
- (i64 (HexagonWrapperCombineII (i32 pat1:$src1), (i32 pat2:$src2))))]>;
-
-let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 8 in
-def COMBINE_Ii : COMBINE_imm<s8Ext, s8Imm, s8ExtPred, s8ImmPred>;
+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,
@@ -446,38 +431,58 @@ def MUX_ii : ALU32_ii<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Ext:$src2,
s8ExtPred:$src2,
s8ImmPred:$src3)))]>;
-// Shift halfword.
-let isPredicable = 1 in
-def ASLH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
- "$dst = aslh($src1)",
- [(set (i32 IntRegs:$dst), (shl 16, (i32 IntRegs:$src1)))]>;
+// ALU32 - aslh, asrh, sxtb, sxth, zxtb, zxth
+multiclass ALU32_2op_Pbase<string mnemonic, bit isNot, bit isPredNew> {
+ let isPredicatedNew = isPredNew in
+ def NAME : ALU32Inst<(outs IntRegs:$dst),
+ (ins PredRegs:$src1, IntRegs:$src2),
+ !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ",
+ ") $dst = ")#mnemonic#"($src2)">,
+ Requires<[HasV4T]>;
+}
-let isPredicable = 1 in
-def ASRH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
- "$dst = asrh($src1)",
- [(set (i32 IntRegs:$dst), (sra 16, (i32 IntRegs:$src1)))]>;
+multiclass ALU32_2op_Pred<string mnemonic, bit PredNot> {
+ let isPredicatedFalse = PredNot in {
+ defm _c#NAME : ALU32_2op_Pbase<mnemonic, PredNot, 0>;
+ // Predicate new
+ defm _cdn#NAME : ALU32_2op_Pbase<mnemonic, PredNot, 1>;
+ }
+}
-// Sign extend.
-let isPredicable = 1 in
-def SXTB : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
- "$dst = sxtb($src1)",
- [(set (i32 IntRegs:$dst), (sext_inreg (i32 IntRegs:$src1), i8))]>;
+multiclass ALU32_2op_base<string mnemonic> {
+ let BaseOpcode = mnemonic in {
+ let isPredicable = 1, neverHasSideEffects = 1 in
+ def NAME : ALU32Inst<(outs IntRegs:$dst),
+ (ins IntRegs:$src1),
+ "$dst = "#mnemonic#"($src1)">;
-let isPredicable = 1 in
-def SXTH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
- "$dst = sxth($src1)",
- [(set (i32 IntRegs:$dst), (sext_inreg (i32 IntRegs:$src1), i16))]>;
-
-// Zero extend.
-let isPredicable = 1, neverHasSideEffects = 1 in
-def ZXTB : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
- "$dst = zxtb($src1)",
- []>;
+ let Predicates = [HasV4T], validSubTargets = HasV4SubT, isPredicated = 1,
+ neverHasSideEffects = 1 in {
+ defm Pt_V4 : ALU32_2op_Pred<mnemonic, 0>;
+ defm NotPt_V4 : ALU32_2op_Pred<mnemonic, 1>;
+ }
+ }
+}
+
+defm ASLH : ALU32_2op_base<"aslh">, PredNewRel;
+defm ASRH : ALU32_2op_base<"asrh">, PredNewRel;
+defm SXTB : ALU32_2op_base<"sxtb">, PredNewRel;
+defm SXTH : ALU32_2op_base<"sxth">, PredNewRel;
+defm ZXTB : ALU32_2op_base<"zxtb">, PredNewRel;
+defm ZXTH : ALU32_2op_base<"zxth">, PredNewRel;
+
+def : Pat <(shl (i32 IntRegs:$src1), (i32 16)),
+ (ASLH IntRegs:$src1)>;
+
+def : Pat <(sra (i32 IntRegs:$src1), (i32 16)),
+ (ASRH IntRegs:$src1)>;
+
+def : Pat <(sext_inreg (i32 IntRegs:$src1), i8),
+ (SXTB IntRegs:$src1)>;
+
+def : Pat <(sext_inreg (i32 IntRegs:$src1), i16),
+ (SXTH IntRegs:$src1)>;
-let isPredicable = 1, neverHasSideEffects = 1 in
-def ZXTH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
- "$dst = zxth($src1)",
- []>;
//===----------------------------------------------------------------------===//
// ALU32/PERM -
//===----------------------------------------------------------------------===//
@@ -487,39 +492,24 @@ def ZXTH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
// ALU32/PRED +
//===----------------------------------------------------------------------===//
-// Conditional combine.
-let neverHasSideEffects = 1, isPredicated = 1 in
-def COMBINE_rr_cPt : ALU32_rr<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if ($src1) $dst = combine($src2, $src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def COMBINE_rr_cNotPt : ALU32_rr<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if (!$src1) $dst = combine($src2, $src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def COMBINE_rr_cdnPt : ALU32_rr<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if ($src1.new) $dst = combine($src2, $src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def COMBINE_rr_cdnNotPt : ALU32_rr<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if (!$src1.new) $dst = combine($src2, $src3)",
- []>;
-
// Compare.
defm CMPGTU : CMP32_rr_ri_u9<"cmp.gtu", "CMPGTU", setugt>, ImmRegRel;
defm CMPGT : CMP32_rr_ri_s10<"cmp.gt", "CMPGT", setgt>, ImmRegRel;
-defm CMPLT : CMP32_rr<"cmp.lt", setlt>;
-defm CMPLTU : CMP32_rr<"cmp.ltu", setult>;
defm CMPEQ : CMP32_rr_ri_s10<"cmp.eq", "CMPEQ", seteq>, ImmRegRel;
-defm CMPGE : CMP32_ri_s8<"cmp.ge", setge>;
-defm CMPGEU : CMP32_ri_u8<"cmp.geu", setuge>;
+
+// SDNode for converting immediate C to C-1.
+def DEC_CONST_SIGNED : SDNodeXForm<imm, [{
+ // Return the byte immediate const-1 as an SDNode.
+ int32_t imm = N->getSExtValue();
+ return XformSToSM1Imm(imm);
+}]>;
+
+// SDNode for converting immediate C to C-1.
+def DEC_CONST_UNSIGNED : SDNodeXForm<imm, [{
+ // Return the byte immediate const-1 as an SDNode.
+ uint32_t imm = N->getZExtValue();
+ return XformUToUM1Imm(imm);
+}]>;
def CTLZ_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1),
"$dst = cl0($src1)",
@@ -753,112 +743,153 @@ def XOR_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, PredRegs:$src2),
// CR -
//===----------------------------------------------------------------------===//
+def retflag : SDNode<"HexagonISD::RET_FLAG", SDTNone,
+ [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
+def eh_return: SDNode<"HexagonISD::EH_RETURN", SDTNone,
+ [SDNPHasChain]>;
-//===----------------------------------------------------------------------===//
-// J +
-//===----------------------------------------------------------------------===//
-// Jump to address.
-let isBranch = 1, isTerminator=1, isBarrier = 1, isPredicable = 1 in {
- def JMP : JInst< (outs),
- (ins brtarget:$offset),
- "jump $offset",
- [(br bb:$offset)]>;
-}
+def SDHexagonBR_JT: SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
+def HexagonBR_JT: SDNode<"HexagonISD::BR_JT", SDHexagonBR_JT, [SDNPHasChain]>;
-// if (p0) jump
-let isBranch = 1, isTerminator=1, Defs = [PC],
- isPredicated = 1 in {
- def JMP_c : JInst< (outs),
- (ins PredRegs:$src, brtarget:$offset),
- "if ($src) jump $offset",
- [(brcond (i1 PredRegs:$src), bb:$offset)]>;
-}
+let InputType = "imm", isBarrier = 1, isPredicable = 1,
+Defs = [PC], isExtendable = 1, opExtendable = 0, isExtentSigned = 1,
+opExtentBits = 24 in
+class T_JMP <dag InsDag, list<dag> JumpList = []>
+ : JInst<(outs), InsDag,
+ "jump $dst" , JumpList> {
+ bits<24> dst;
+
+ let IClass = 0b0101;
+
+ let Inst{27-25} = 0b100;
+ let Inst{24-16} = dst{23-15};
+ let Inst{13-1} = dst{14-2};
+}
+
+let InputType = "imm", isExtendable = 1, opExtendable = 1, isExtentSigned = 1,
+Defs = [PC], isPredicated = 1, opExtentBits = 17 in
+class T_JMP_c <bit PredNot, bit isPredNew, bit isTaken>:
+ JInst<(outs ), (ins PredRegs:$src, brtarget:$dst),
+ !if(PredNot, "if (!$src", "if ($src")#
+ !if(isPredNew, ".new) ", ") ")#"jump"#
+ !if(isPredNew, !if(isTaken, ":t ", ":nt "), " ")#"$dst"> {
+
+ let isBrTaken = !if(isPredNew, !if(isTaken, "true", "false"), "");
+ let isPredicatedFalse = PredNot;
+ let isPredicatedNew = isPredNew;
+ bits<2> src;
+ bits<17> dst;
+
+ let IClass = 0b0101;
+
+ let Inst{27-24} = 0b1100;
+ let Inst{21} = PredNot;
+ let Inst{12} = !if(isPredNew, isTaken, zero);
+ let Inst{11} = isPredNew;
+ let Inst{9-8} = src;
+ let Inst{23-22} = dst{16-15};
+ let Inst{20-16} = dst{14-10};
+ let Inst{13} = dst{9};
+ let Inst{7-1} = dst{8-2};
+ }
-// if (!p0) jump
-let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC],
- isPredicated = 1 in {
- def JMP_cNot : JInst< (outs),
- (ins PredRegs:$src, brtarget:$offset),
- "if (!$src) jump $offset",
- []>;
+let isBarrier = 1, Defs = [PC], isPredicable = 1, InputType = "reg" in
+class T_JMPr<dag InsDag = (ins IntRegs:$dst)>
+ : JRInst<(outs ), InsDag,
+ "jumpr $dst" ,
+ []> {
+ bits<5> dst;
+
+ let IClass = 0b0101;
+ let Inst{27-21} = 0b0010100;
+ let Inst{20-16} = dst;
}
-let isTerminator = 1, isBranch = 1, neverHasSideEffects = 1, Defs = [PC],
- isPredicated = 1 in {
- def BRCOND : JInst < (outs), (ins PredRegs:$pred, brtarget:$dst),
- "if ($pred) jump $dst",
- []>;
+let Defs = [PC], isPredicated = 1, InputType = "reg" in
+class T_JMPr_c <bit PredNot, bit isPredNew, bit isTaken>:
+ JRInst <(outs ), (ins PredRegs:$src, IntRegs:$dst),
+ !if(PredNot, "if (!$src", "if ($src")#
+ !if(isPredNew, ".new) ", ") ")#"jumpr"#
+ !if(isPredNew, !if(isTaken, ":t ", ":nt "), " ")#"$dst"> {
+
+ let isBrTaken = !if(isPredNew, !if(isTaken, "true", "false"), "");
+ let isPredicatedFalse = PredNot;
+ let isPredicatedNew = isPredNew;
+ bits<2> src;
+ bits<5> dst;
+
+ let IClass = 0b0101;
+
+ let Inst{27-22} = 0b001101;
+ let Inst{21} = PredNot;
+ let Inst{20-16} = dst;
+ let Inst{12} = !if(isPredNew, isTaken, zero);
+ let Inst{11} = isPredNew;
+ let Inst{9-8} = src;
+ let Predicates = !if(isPredNew, [HasV3T], [HasV2T]);
+ let validSubTargets = !if(isPredNew, HasV3SubT, HasV2SubT);
}
-// Jump to address conditioned on new predicate.
-// if (p0) jump:t
-let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC],
- isPredicated = 1 in {
- def JMP_cdnPt : JInst< (outs),
- (ins PredRegs:$src, brtarget:$offset),
- "if ($src.new) jump:t $offset",
- []>;
+multiclass JMP_Pred<bit PredNot> {
+ def _#NAME : T_JMP_c<PredNot, 0, 0>;
+ // Predicate new
+ def _#NAME#new_t : T_JMP_c<PredNot, 1, 1>; // taken
+ def _#NAME#new_nt : T_JMP_c<PredNot, 1, 0>; // not taken
}
-// if (!p0) jump:t
-let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC],
- isPredicated = 1 in {
- def JMP_cdnNotPt : JInst< (outs),
- (ins PredRegs:$src, brtarget:$offset),
- "if (!$src.new) jump:t $offset",
- []>;
+multiclass JMP_base<string BaseOp> {
+ let BaseOpcode = BaseOp in {
+ def NAME : T_JMP<(ins brtarget:$dst), [(br bb:$dst)]>;
+ defm t : JMP_Pred<0>;
+ defm f : JMP_Pred<1>;
+ }
}
-// Not taken.
-let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC],
- isPredicated = 1 in {
- def JMP_cdnPnt : JInst< (outs),
- (ins PredRegs:$src, brtarget:$offset),
- "if ($src.new) jump:nt $offset",
- []>;
+multiclass JMPR_Pred<bit PredNot> {
+ def NAME: T_JMPr_c<PredNot, 0, 0>;
+ // Predicate new
+ def NAME#new_tV3 : T_JMPr_c<PredNot, 1, 1>; // taken
+ def NAME#new_ntV3 : T_JMPr_c<PredNot, 1, 0>; // not taken
}
-// Not taken.
-let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC],
- isPredicated = 1 in {
- def JMP_cdnNotPnt : JInst< (outs),
- (ins PredRegs:$src, brtarget:$offset),
- "if (!$src.new) jump:nt $offset",
- []>;
+multiclass JMPR_base<string BaseOp> {
+ let BaseOpcode = BaseOp in {
+ def NAME : T_JMPr;
+ defm _t : JMPR_Pred<0>;
+ defm _f : JMPR_Pred<1>;
+ }
}
-//===----------------------------------------------------------------------===//
-// J -
-//===----------------------------------------------------------------------===//
-//===----------------------------------------------------------------------===//
-// JR +
-//===----------------------------------------------------------------------===//
-def retflag : SDNode<"HexagonISD::RET_FLAG", SDTNone,
- [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
+let isTerminator = 1, neverHasSideEffects = 1 in {
+let isBranch = 1 in
+defm JMP : JMP_base<"JMP">, PredNewRel;
-// Jump to address from register.
-let isPredicable =1, isReturn = 1, isTerminator = 1, isBarrier = 1,
- Defs = [PC], Uses = [R31] in {
- def JMPR: JRInst<(outs), (ins),
- "jumpr r31",
- [(retflag)]>;
-}
+let isBranch = 1, isIndirectBranch = 1 in
+defm JMPR : JMPR_base<"JMPr">, PredNewRel;
-// Jump to address from register.
-let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicated = 1,
- Defs = [PC], Uses = [R31] in {
- def JMPR_cPt: JRInst<(outs), (ins PredRegs:$src1),
- "if ($src1) jumpr r31",
- []>;
+let isReturn = 1, isCodeGenOnly = 1 in
+defm JMPret : JMPR_base<"JMPret">, PredNewRel;
}
-// Jump to address from register.
-let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicated = 1,
- Defs = [PC], Uses = [R31] in {
- def JMPR_cNotPt: JRInst<(outs), (ins PredRegs:$src1),
- "if (!$src1) jumpr r31",
- []>;
-}
+def : Pat<(retflag),
+ (JMPret (i32 R31))>;
+
+def : Pat <(brcond (i1 PredRegs:$src1), bb:$offset),
+ (JMP_t (i1 PredRegs:$src1), bb:$offset)>;
+
+// A return through builtin_eh_return.
+let isReturn = 1, isTerminator = 1, isBarrier = 1, neverHasSideEffects = 1,
+isCodeGenOnly = 1, Defs = [PC], Uses = [R28], isPredicable = 0 in
+def EH_RETURN_JMPR : T_JMPr;
+
+def : Pat<(eh_return),
+ (EH_RETURN_JMPR (i32 R31))>;
+
+def : Pat<(HexagonBR_JT (i32 IntRegs:$dst)),
+ (JMPR (i32 IntRegs:$dst))>;
+
+def : Pat<(brind (i32 IntRegs:$dst)),
+ (JMPR (i32 IntRegs:$dst))>;
//===----------------------------------------------------------------------===//
// JR -
@@ -871,7 +902,7 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicated = 1,
// Load -- MEMri operand
multiclass LD_MEMri_Pbase<string mnemonic, RegisterClass RC,
bit isNot, bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : LDInst2<(outs RC:$dst),
(ins PredRegs:$src1, MEMri:$addr),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -880,7 +911,7 @@ multiclass LD_MEMri_Pbase<string mnemonic, RegisterClass RC,
}
multiclass LD_MEMri_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : LD_MEMri_Pbase<mnemonic, RC, PredNot, 0>;
// Predicate new
defm _cdn#NAME : LD_MEMri_Pbase<mnemonic, RC, PredNot, 1>;
@@ -907,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)),
@@ -937,7 +977,7 @@ def : Pat < (i64 (load ADDRriS11_3:$addr)),
// Load - Base with Immediate offset addressing mode
multiclass LD_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp,
bit isNot, bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : LDInst2<(outs RC:$dst),
(ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -947,7 +987,7 @@ multiclass LD_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp,
multiclass LD_Idxd_Pred<string mnemonic, RegisterClass RC, Operand predImmOp,
bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : LD_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 0>;
// Predicate new
defm _cdn#NAME : LD_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 1>;
@@ -975,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 {
@@ -1009,29 +1056,13 @@ def : Pat < (i64 (load (add IntRegs:$src1, s11_3ExtPred:$offset))),
(LDrid_indexed IntRegs:$src1, s11_3ExtPred:$offset) >;
}
-let neverHasSideEffects = 1 in
-def LDrid_GP : LDInst2<(outs DoubleRegs:$dst),
- (ins globaladdress:$global, u16Imm:$offset),
- "$dst = memd(#$global+$offset)",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def LDd_GP : LDInst2<(outs DoubleRegs:$dst),
- (ins globaladdress:$global),
- "$dst = memd(#$global)",
- []>,
- Requires<[NoV4T]>;
-
//===----------------------------------------------------------------------===//
// 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,
bit isNot, bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : LDInst2PI<(outs RC:$dst, IntRegs:$dst2),
(ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -1042,7 +1073,7 @@ multiclass LD_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp,
multiclass LD_PostInc_Pred<string mnemonic, RegisterClass RC,
Operand ImmOp, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : LD_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>;
// Predicate new
let Predicates = [HasV4T], validSubTargets = HasV4SubT in
@@ -1068,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>,
@@ -1095,27 +1126,6 @@ let AddedComplexity = 20 in
def : Pat < (i32 (extloadi8 (add IntRegs:$src1, s11_0ImmPred:$offset))),
(i32 (LDrib_indexed IntRegs:$src1, s11_0ImmPred:$offset)) >;
-let neverHasSideEffects = 1 in
-def LDrib_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global, u16Imm:$offset),
- "$dst = memb(#$global+$offset)",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def LDb_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst = memb(#$global)",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def LDub_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst = memub(#$global)",
- []>,
- Requires<[NoV4T]>;
-
def : Pat < (i32 (extloadi16 ADDRriS11_1:$addr)),
(i32 (LDrih ADDRriS11_1:$addr))>;
@@ -1123,27 +1133,6 @@ let AddedComplexity = 20 in
def : Pat < (i32 (extloadi16 (add IntRegs:$src1, s11_1ImmPred:$offset))),
(i32 (LDrih_indexed IntRegs:$src1, s11_1ImmPred:$offset)) >;
-let neverHasSideEffects = 1 in
-def LDrih_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global, u16Imm:$offset),
- "$dst = memh(#$global+$offset)",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def LDh_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst = memh(#$global)",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def LDuh_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst = memuh(#$global)",
- []>,
- Requires<[NoV4T]>;
-
let AddedComplexity = 10 in
def : Pat < (i32 (zextloadi1 ADDRriS11_0:$addr)),
(i32 (LDriub ADDRriS11_0:$addr))>;
@@ -1152,21 +1141,6 @@ let AddedComplexity = 20 in
def : Pat < (i32 (zextloadi1 (add IntRegs:$src1, s11_0ImmPred:$offset))),
(i32 (LDriub_indexed IntRegs:$src1, s11_0ImmPred:$offset))>;
-let neverHasSideEffects = 1 in
-def LDriub_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global, u16Imm:$offset),
- "$dst = memub(#$global+$offset)",
- []>,
- Requires<[NoV4T]>;
-
-// Load unsigned halfword.
-let neverHasSideEffects = 1 in
-def LDriuh_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global, u16Imm:$offset),
- "$dst = memuh(#$global+$offset)",
- []>,
- Requires<[NoV4T]>;
-
// Load predicate.
let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13,
isPseudo = 1, Defs = [R10,R11,D5], neverHasSideEffects = 1 in
@@ -1175,21 +1149,6 @@ def LDriw_pred : LDInst2<(outs PredRegs:$dst),
"Error; should not emit",
[]>;
-// Indexed load.
-let neverHasSideEffects = 1 in
-def LDriw_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global, u16Imm:$offset),
- "$dst = memw(#$global+$offset)",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def LDw_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst = memw(#$global)",
- []>,
- Requires<[NoV4T]>;
-
// Deallocate stack frame.
let Defs = [R29, R30, R31], Uses = [R29], neverHasSideEffects = 1 in {
def DEALLOCFRAME : LDInst2<(outs), (ins),
@@ -1423,35 +1382,15 @@ def SUBri_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1,
// ST +
//===----------------------------------------------------------------------===//
///
-/// Assumptions::: ****** DO NOT IGNORE ********
-/// 1. Make sure that in post increment store, the zero'th operand is always the
-/// post increment operand.
-/// 2. Make sure that the store value operand(Rt/Rtt) in a store is always the
-/// last operand.
-///
// Store doubleword.
-let neverHasSideEffects = 1 in
-def STrid_GP : STInst2<(outs),
- (ins globaladdress:$global, u16Imm:$offset, DoubleRegs:$src),
- "memd(#$global+$offset) = $src",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def STd_GP : STInst2<(outs),
- (ins globaladdress:$global, DoubleRegs:$src),
- "memd(#$global) = $src",
- []>,
- Requires<[NoV4T]>;
-
//===----------------------------------------------------------------------===//
// Post increment store
//===----------------------------------------------------------------------===//
multiclass ST_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp,
bit isNot, bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : STInst2PI<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset, RC:$src3),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -1462,8 +1401,8 @@ multiclass ST_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp,
multiclass ST_PostInc_Pred<string mnemonic, RegisterClass RC,
Operand ImmOp, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
- defm _c#NAME# : ST_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>;
+ let isPredicatedFalse = PredNot in {
+ 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>;
@@ -1478,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">;
@@ -1516,7 +1455,7 @@ def : Pat<(post_store (i64 DoubleRegs:$src1), IntRegs:$src2,
//===----------------------------------------------------------------------===//
multiclass ST_MEMri_Pbase<string mnemonic, RegisterClass RC, bit isNot,
bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : STInst2<(outs),
(ins PredRegs:$src1, MEMri:$addr, RC: $src2),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -1525,7 +1464,7 @@ multiclass ST_MEMri_Pbase<string mnemonic, RegisterClass RC, bit isNot,
}
multiclass ST_MEMri_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ST_MEMri_Pbase<mnemonic, RC, PredNot, 0>;
// Predicate new
@@ -1555,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 isNVStorable = 0 in
- defm STrid: ST_MEMri < "memd", "STrid", DoubleRegs, 14, 9>, AddrModeRel;
+ let accessSize = HalfWordAccess in
+ defm STrih: ST_MEMri < "memh", "STrih", IntRegs, 12, 7>, 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),
@@ -1582,7 +1526,7 @@ def : Pat<(store (i64 DoubleRegs:$src1), ADDRriS11_3:$addr),
//===----------------------------------------------------------------------===//
multiclass ST_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp,
bit isNot, bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : STInst2<(outs),
(ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -1592,7 +1536,7 @@ multiclass ST_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp,
multiclass ST_Idxd_Pred<string mnemonic, RegisterClass RC, Operand predImmOp,
bit PredNot> {
- let PredSense = !if(PredNot, "false", "true"), isPredicated = 1 in {
+ let isPredicatedFalse = PredNot, isPredicated = 1 in {
defm _c#NAME : ST_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 0>;
// Predicate new
@@ -1622,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 {
@@ -1655,36 +1605,6 @@ def : Pat<(store (i64 DoubleRegs:$src1), (add IntRegs:$src2,
(i64 DoubleRegs:$src1))>;
}
-// memb(gp+#u16:0)=Rt
-let neverHasSideEffects = 1 in
-def STrib_GP : STInst2<(outs),
- (ins globaladdress:$global, u16Imm:$offset, IntRegs:$src),
- "memb(#$global+$offset) = $src",
- []>,
- Requires<[NoV4T]>;
-
-// memb(#global)=Rt
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def STb_GP : STInst2<(outs),
- (ins globaladdress:$global, IntRegs:$src),
- "memb(#$global) = $src",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1 in
-def STrih_GP : STInst2<(outs),
- (ins globaladdress:$global, u16Imm:$offset, IntRegs:$src),
- "memh(#$global+$offset) = $src",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def STh_GP : STInst2<(outs),
- (ins globaladdress:$global, IntRegs:$src),
- "memh(#$global) = $src",
- []>,
- Requires<[NoV4T]>;
-
// memh(Rx++#s4:1)=Rt.H
// Store word.
@@ -1695,20 +1615,6 @@ def STriw_pred : STInst2<(outs),
"Error; should not emit",
[]>;
-let neverHasSideEffects = 1 in
-def STriw_GP : STInst2<(outs),
- (ins globaladdress:$global, u16Imm:$offset, IntRegs:$src),
- "memw(#$global+$offset) = $src",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def STw_GP : STInst2<(outs),
- (ins globaladdress:$global, IntRegs:$src),
- "memw(#$global) = $src",
- []>,
- Requires<[NoV4T]>;
-
// Allocate stack frame.
let Defs = [R29, R30], Uses = [R31, R30], neverHasSideEffects = 1 in {
def ALLOCFRAME : STInst2<(outs),
@@ -2152,20 +2058,18 @@ let isCall = 1, neverHasSideEffects = 1,
[]>;
}
-// Tail Calls.
-let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1 in {
- def TCRETURNtg : JInst<(outs), (ins calltarget:$dst),
- "jump $dst // TAILCALL", []>;
-}
-let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1 in {
- def TCRETURNtext : JInst<(outs), (ins calltarget:$dst),
- "jump $dst // TAILCALL", []>;
-}
-let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1 in {
- def TCRETURNR : JInst<(outs), (ins IntRegs:$dst),
- "jumpr $dst // TAILCALL", []>;
+// Indirect tail-call.
+let isCodeGenOnly = 1, isCall = 1, isReturn = 1 in
+def TCRETURNR : T_JMPr;
+
+// Direct tail-calls.
+let isCall = 1, isReturn = 1, isBarrier = 1, isPredicable = 0,
+isTerminator = 1, isCodeGenOnly = 1 in {
+ def TCRETURNtg : T_JMP<(ins calltarget:$dst)>;
+ def TCRETURNtext : T_JMP<(ins calltarget:$dst)>;
}
+
// Map call instruction.
def : Pat<(call (i32 IntRegs:$dst)),
(CALLR (i32 IntRegs:$dst))>, Requires<[HasV2TOnly]>;
@@ -2183,68 +2087,26 @@ def : Pat<(HexagonTCRet (i32 IntRegs:$dst)),
// Atomic load and store support
// 8 bit atomic load
-def : Pat<(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)),
- (i32 (LDub_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-def : Pat<(atomic_load_8 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset)),
- (i32 (LDriub_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
def : Pat<(atomic_load_8 ADDRriS11_0:$src1),
(i32 (LDriub ADDRriS11_0:$src1))>;
def : Pat<(atomic_load_8 (add (i32 IntRegs:$src1), s11_0ImmPred:$offset)),
(i32 (LDriub_indexed (i32 IntRegs:$src1), s11_0ImmPred:$offset))>;
-
-
// 16 bit atomic load
-def : Pat<(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)),
- (i32 (LDuh_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-def : Pat<(atomic_load_16 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset)),
- (i32 (LDriuh_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
def : Pat<(atomic_load_16 ADDRriS11_1:$src1),
(i32 (LDriuh ADDRriS11_1:$src1))>;
def : Pat<(atomic_load_16 (add (i32 IntRegs:$src1), s11_1ImmPred:$offset)),
(i32 (LDriuh_indexed (i32 IntRegs:$src1), s11_1ImmPred:$offset))>;
-
-
-// 32 bit atomic load
-def : Pat<(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)),
- (i32 (LDw_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-def : Pat<(atomic_load_32 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset)),
- (i32 (LDriw_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
def : Pat<(atomic_load_32 ADDRriS11_2:$src1),
(i32 (LDriw ADDRriS11_2:$src1))>;
def : Pat<(atomic_load_32 (add (i32 IntRegs:$src1), s11_2ImmPred:$offset)),
(i32 (LDriw_indexed (i32 IntRegs:$src1), s11_2ImmPred:$offset))>;
-
// 64 bit atomic load
-def : Pat<(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)),
- (i64 (LDd_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-def : Pat<(atomic_load_64 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset)),
- (i64 (LDrid_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
def : Pat<(atomic_load_64 ADDRriS11_3:$src1),
(i64 (LDrid ADDRriS11_3:$src1))>;
@@ -2252,30 +2114,6 @@ def : Pat<(atomic_load_64 (add (i32 IntRegs:$src1), s11_3ImmPred:$offset)),
(i64 (LDrid_indexed (i32 IntRegs:$src1), s11_3ImmPred:$offset))>;
-// 64 bit atomic store
-def : Pat<(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global),
- (i64 DoubleRegs:$src1)),
- (STd_GP tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
- Requires<[NoV4T]>;
-
-def : Pat<(atomic_store_64 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset),
- (i64 DoubleRegs:$src1)),
- (STrid_GP tglobaladdr:$global, u16ImmPred:$offset,
- (i64 DoubleRegs:$src1))>, Requires<[NoV4T]>;
-
-// 8 bit atomic store
-def : Pat<(atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global),
- (i32 IntRegs:$src1)),
- (STb_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
-def : Pat<(atomic_store_8 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset),
- (i32 IntRegs:$src1)),
- (STrib_GP tglobaladdr:$global, u16ImmPred:$offset,
- (i32 IntRegs:$src1))>, Requires<[NoV4T]>;
-
def : Pat<(atomic_store_8 ADDRriS11_0:$src2, (i32 IntRegs:$src1)),
(STrib ADDRriS11_0:$src2, (i32 IntRegs:$src1))>;
@@ -2285,18 +2123,6 @@ def : Pat<(atomic_store_8 (add (i32 IntRegs:$src2), s11_0ImmPred:$offset),
(i32 IntRegs:$src1))>;
-// 16 bit atomic store
-def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
- (i32 IntRegs:$src1)),
- (STh_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
-def : Pat<(atomic_store_16 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset),
- (i32 IntRegs:$src1)),
- (STrih_GP tglobaladdr:$global, u16ImmPred:$offset,
- (i32 IntRegs:$src1))>, Requires<[NoV4T]>;
-
def : Pat<(atomic_store_16 ADDRriS11_1:$src2, (i32 IntRegs:$src1)),
(STrih ADDRriS11_1:$src2, (i32 IntRegs:$src1))>;
@@ -2305,20 +2131,6 @@ def : Pat<(atomic_store_16 (i32 IntRegs:$src1),
(STrih_indexed (i32 IntRegs:$src2), s11_1ImmPred:$offset,
(i32 IntRegs:$src1))>;
-
-// 32 bit atomic store
-def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global),
- (i32 IntRegs:$src1)),
- (STw_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
-def : Pat<(atomic_store_32 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset),
- (i32 IntRegs:$src1)),
- (STriw_GP tglobaladdr:$global, u16ImmPred:$offset,
- (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
def : Pat<(atomic_store_32 ADDRriS11_2:$src2, (i32 IntRegs:$src1)),
(STriw ADDRriS11_2:$src2, (i32 IntRegs:$src1))>;
@@ -2354,10 +2166,11 @@ def : Pat <(add (i1 PredRegs:$src1), -1),
// Map from p0 = setlt(r0, r1) r2 = mux(p0, r3, r4) =>
// p0 = cmp.lt(r0, r1), r0 = mux(p0, r2, r1).
+// cmp.lt(r0, r1) -> cmp.gt(r1, r0)
def : Pat <(select (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
(i32 IntRegs:$src3),
(i32 IntRegs:$src4)),
- (i32 (TFR_condset_rr (CMPLTrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
+ (i32 (TFR_condset_rr (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)),
(i32 IntRegs:$src4), (i32 IntRegs:$src3)))>,
Requires<[HasV2TOnly]>;
@@ -2375,210 +2188,27 @@ def : Pat <(select (not (i1 PredRegs:$src1)), s12ImmPred:$src2,
// Map from p0 = pnot(p0); r0 = mux(p0, r1, #i)
// => r0 = TFR_condset_ir(p0, #i, r1)
-def : Pat <(select (not PredRegs:$src1), IntRegs:$src2, s12ImmPred:$src3),
+def : Pat <(select (not (i1 PredRegs:$src1)), IntRegs:$src2, s12ImmPred:$src3),
(i32 (TFR_condset_ir (i1 PredRegs:$src1), s12ImmPred:$src3,
(i32 IntRegs:$src2)))>;
// Map from p0 = pnot(p0); if (p0) jump => if (!p0) jump.
-def : Pat <(brcond (not PredRegs:$src1), bb:$offset),
- (JMP_cNot (i1 PredRegs:$src1), bb:$offset)>;
+def : Pat <(brcond (not (i1 PredRegs:$src1)), bb:$offset),
+ (JMP_f (i1 PredRegs:$src1), bb:$offset)>;
// Map from p2 = pnot(p2); p1 = and(p0, p2) => p1 = and(p0, !p2).
-def : Pat <(and PredRegs:$src1, (not PredRegs:$src2)),
+def : Pat <(and (i1 PredRegs:$src1), (not (i1 PredRegs:$src2))),
(i1 (AND_pnotp (i1 PredRegs:$src1), (i1 PredRegs:$src2)))>;
-// Map from store(globaladdress + x) -> memd(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(store (i64 DoubleRegs:$src1),
- (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset)),
- (STrid_GP tglobaladdr:$global, u16ImmPred:$offset,
- (i64 DoubleRegs:$src1))>, Requires<[NoV4T]>;
-
-// Map from store(globaladdress) -> memd(#foo).
-let AddedComplexity = 100 in
-def : Pat <(store (i64 DoubleRegs:$src1),
- (HexagonCONST32_GP tglobaladdr:$global)),
- (STd_GP tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
- Requires<[NoV4T]>;
-// Map from store(globaladdress + x) -> memw(#foo + x).
let AddedComplexity = 100 in
-def : Pat <(store (i32 IntRegs:$src1),
- (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset)),
- (STriw_GP tglobaladdr:$global, u16ImmPred:$offset, (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
-// Map from store(globaladdress) -> memw(#foo + 0).
-let AddedComplexity = 100 in
-def : Pat <(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
- (STriw_GP tglobaladdr:$global, 0, (i32 IntRegs:$src1))>;
-
-// Map from store(globaladdress) -> memw(#foo).
-let AddedComplexity = 100 in
-def : Pat <(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
- (STriw_GP tglobaladdr:$global, 0, (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
-// Map from store(globaladdress + x) -> memh(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(truncstorei16 (i32 IntRegs:$src1),
- (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset)),
- (STrih_GP tglobaladdr:$global, u16ImmPred:$offset, (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
-// Map from store(globaladdress) -> memh(#foo).
-let AddedComplexity = 100 in
-def : Pat <(truncstorei16 (i32 IntRegs:$src1),
- (HexagonCONST32_GP tglobaladdr:$global)),
- (STh_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
-// Map from store(globaladdress + x) -> memb(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(truncstorei8 (i32 IntRegs:$src1),
- (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset)),
- (STrib_GP tglobaladdr:$global, u16ImmPred:$offset, (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
-// Map from store(globaladdress) -> memb(#foo).
-let AddedComplexity = 100 in
-def : Pat <(truncstorei8 (i32 IntRegs:$src1),
- (HexagonCONST32_GP tglobaladdr:$global)),
- (STb_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress + x) -> memw(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(i32 (load (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset))),
- (i32 (LDriw_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress) -> memw(#foo).
-let AddedComplexity = 100 in
-def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDw_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress + x) -> memd(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(i64 (load (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset))),
- (i64 (LDrid_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress) -> memw(#foo + 0).
-let AddedComplexity = 100 in
-def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))),
- (i64 (LDd_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-// Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd.
-let AddedComplexity = 100 in
-def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))),
- (i1 (TFR_PdRs (i32 (LDb_GP tglobaladdr:$global))))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress + x) -> memh(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(i32 (extloadi16 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset))),
- (i32 (LDrih_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress + x) -> memh(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDrih_GP tglobaladdr:$global, 0))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress + x) -> memuh(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(i32 (zextloadi16 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset))),
- (i32 (LDriuh_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress) -> memuh(#foo).
-let AddedComplexity = 100 in
-def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDriuh_GP tglobaladdr:$global, 0))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress) -> memh(#foo).
-let AddedComplexity = 100 in
-def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDh_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress) -> memuh(#foo).
-let AddedComplexity = 100 in
-def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDuh_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress + x) -> memb(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(i32 (extloadi8 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset))),
- (i32 (LDrib_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress + x) -> memb(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(i32 (sextloadi8 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset))),
- (i32 (LDrib_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress + x) -> memub(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(i32 (zextloadi8 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset))),
- (i32 (LDriub_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress) -> memb(#foo).
-let AddedComplexity = 100 in
-def : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress) -> memb(#foo).
-let AddedComplexity = 100 in
-def : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress) -> memub(#foo).
-let AddedComplexity = 100 in
-def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDub_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-// When the Interprocedural Global Variable optimizer realizes that a
-// certain global variable takes only two constant values, it shrinks the
-// global to a boolean. Catch those loads here in the following 3 patterns.
-let AddedComplexity = 100 in
-def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-let AddedComplexity = 100 in
-def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-let AddedComplexity = 100 in
-def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDub_GP tglobaladdr:$global))>,
+def : Pat <(i64 (zextloadi1 (HexagonCONST32 tglobaladdr:$global))),
+ (i64 (COMBINE_rr (TFRI 0),
+ (LDriub_indexed (CONST32_set tglobaladdr:$global), 0)))>,
Requires<[NoV4T]>;
// Map from i1 loads to 32 bits. This assumes that the i1* is byte aligned.
+let AddedComplexity = 10 in
def : Pat <(i32 (zextloadi1 ADDRriS11_0:$addr)),
(i32 (AND_rr (i32 (LDrib ADDRriS11_0:$addr)), (TFRI 0x1)))>;
@@ -2597,43 +2227,46 @@ def : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i8)),
subreg_loreg))))))>;
// We want to prevent emitting pnot's as much as possible.
-// Map brcond with an unsupported setcc to a JMP_cNot.
+// Map brcond with an unsupported setcc to a JMP_f.
def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
bb:$offset),
- (JMP_cNot (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
+ (JMP_f (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
bb:$offset)>;
def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), s10ImmPred:$src2)),
bb:$offset),
- (JMP_cNot (CMPEQri (i32 IntRegs:$src1), s10ImmPred:$src2), bb:$offset)>;
+ (JMP_f (CMPEQri (i32 IntRegs:$src1), s10ImmPred:$src2), bb:$offset)>;
def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 -1))), bb:$offset),
- (JMP_cNot (i1 PredRegs:$src1), bb:$offset)>;
+ (JMP_f (i1 PredRegs:$src1), bb:$offset)>;
def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 0))), bb:$offset),
- (JMP_c (i1 PredRegs:$src1), bb:$offset)>;
+ (JMP_t (i1 PredRegs:$src1), bb:$offset)>;
+// cmp.lt(Rs, Imm) -> !cmp.ge(Rs, Imm) -> !cmp.gt(Rs, Imm-1)
def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), s8ImmPred:$src2)),
bb:$offset),
- (JMP_cNot (CMPGEri (i32 IntRegs:$src1), s8ImmPred:$src2), bb:$offset)>;
+ (JMP_f (CMPGTri (i32 IntRegs:$src1),
+ (DEC_CONST_SIGNED s8ImmPred:$src2)), bb:$offset)>;
+// cmp.lt(r0, r1) -> cmp.gt(r1, r0)
def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
bb:$offset),
- (JMP_c (CMPLTrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)), bb:$offset)>;
+ (JMP_t (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)), bb:$offset)>;
def : Pat <(brcond (i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
bb:$offset),
- (JMP_cNot (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)),
+ (JMP_f (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)),
bb:$offset)>;
def : Pat <(brcond (i1 (setule (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
bb:$offset),
- (JMP_cNot (CMPGTUrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
+ (JMP_f (CMPGTUrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
bb:$offset)>;
def : Pat <(brcond (i1 (setule (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
bb:$offset),
- (JMP_cNot (CMPGTU64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
+ (JMP_f (CMPGTU64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
bb:$offset)>;
// Map from a 64-bit select to an emulated 64-bit mux.
@@ -2694,12 +2327,6 @@ def : Pat<(truncstorei32 (i64 DoubleRegs:$src), ADDRriS11_0:$addr),
def : Pat<(store (i1 -1), ADDRriS11_2:$addr),
(STrib ADDRriS11_2:$addr, (TFRI 1))>;
-let AddedComplexity = 100 in
-// Map from i1 = constant<-1>; memw(CONST32(#foo)) = i1 -> r0 = 1;
-// memw(#foo) = r0
-def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
- (STb_GP tglobaladdr:$global, (TFRI 1))>,
- Requires<[NoV4T]>;
// Map from i1 = constant<-1>; store i1 -> r0 = 1; store r0.
def : Pat<(store (i1 -1), ADDRriS11_2:$addr),
@@ -2717,8 +2344,8 @@ def : Pat<(i64 (anyext (i32 IntRegs:$src1))),
// Map cmple -> cmpgt.
// rs <= rt -> !(rs > rt).
-def : Pat<(i1 (setle (i32 IntRegs:$src1), s10ImmPred:$src2)),
- (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), s10ImmPred:$src2)))>;
+def : Pat<(i1 (setle (i32 IntRegs:$src1), s10ExtPred:$src2)),
+ (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), s10ExtPred:$src2)))>;
// rs <= rt -> !(rs > rt).
def : Pat<(i1 (setle (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
@@ -2731,8 +2358,8 @@ def : Pat<(i1 (setle (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
// Map cmpne -> cmpeq.
// Hexagon_TODO: We should improve on this.
// rs != rt -> !(rs == rt).
-def : Pat <(i1 (setne (i32 IntRegs:$src1), s10ImmPred:$src2)),
- (i1 (NOT_p(i1 (CMPEQri (i32 IntRegs:$src1), s10ImmPred:$src2))))>;
+def : Pat <(i1 (setne (i32 IntRegs:$src1), s10ExtPred:$src2)),
+ (i1 (NOT_p(i1 (CMPEQri (i32 IntRegs:$src1), s10ExtPred:$src2))))>;
// Map cmpne(Rs) -> !cmpeqe(Rs).
// rs != rt -> !(rs == rt).
@@ -2754,8 +2381,9 @@ def : Pat <(i1 (setne (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
def : Pat <(i1 (setge (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
(i1 (NOT_p (i1 (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))))>;
-def : Pat <(i1 (setge (i32 IntRegs:$src1), s8ImmPred:$src2)),
- (i1 (CMPGEri (i32 IntRegs:$src1), s8ImmPred:$src2))>;
+// cmpge(Rs, Imm) -> cmpgt(Rs, Imm-1)
+def : Pat <(i1 (setge (i32 IntRegs:$src1), s8ExtPred:$src2)),
+ (i1 (CMPGTri (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2)))>;
// Map cmpge(Rss, Rtt) -> !cmpgt(Rtt, Rss).
// rss >= rtt -> !(rtt > rss).
@@ -2764,9 +2392,10 @@ def : Pat <(i1 (setge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
(i64 DoubleRegs:$src1)))))>;
// Map cmplt(Rs, Imm) -> !cmpge(Rs, Imm).
+// !cmpge(Rs, Imm) -> !cmpgt(Rs, Imm-1).
// rs < rt -> !(rs >= rt).
-def : Pat <(i1 (setlt (i32 IntRegs:$src1), s8ImmPred:$src2)),
- (i1 (NOT_p (CMPGEri (i32 IntRegs:$src1), s8ImmPred:$src2)))>;
+def : Pat <(i1 (setlt (i32 IntRegs:$src1), s8ExtPred:$src2)),
+ (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2))))>;
// Map cmplt(Rs, Rt) -> cmpgt(Rt, Rs).
// rs < rt -> rt > rs.
@@ -2790,13 +2419,17 @@ def : Pat <(i1 (setult (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
def : Pat <(i1 (setult (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
(i1 (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)))>;
-// Generate cmpgeu(Rs, #u8)
-def : Pat <(i1 (setuge (i32 IntRegs:$src1), u8ImmPred:$src2)),
- (i1 (CMPGEUri (i32 IntRegs:$src1), u8ImmPred:$src2))>;
+// Generate cmpgeu(Rs, #0) -> cmpeq(Rs, Rs)
+def : Pat <(i1 (setuge (i32 IntRegs:$src1), 0)),
+ (i1 (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src1)))>;
+
+// Generate cmpgeu(Rs, #u8) -> cmpgtu(Rs, #u8 -1)
+def : Pat <(i1 (setuge (i32 IntRegs:$src1), u8ExtPred:$src2)),
+ (i1 (CMPGTUri (i32 IntRegs:$src1), (DEC_CONST_UNSIGNED u8ExtPred:$src2)))>;
// Generate cmpgtu(Rs, #u9)
-def : Pat <(i1 (setugt (i32 IntRegs:$src1), u9ImmPred:$src2)),
- (i1 (CMPGTUri (i32 IntRegs:$src1), u9ImmPred:$src2))>;
+def : Pat <(i1 (setugt (i32 IntRegs:$src1), u9ExtPred:$src2)),
+ (i1 (CMPGTUri (i32 IntRegs:$src1), u9ExtPred:$src2))>;
// Map from Rs >= Rt -> !(Rt > Rs).
// rs >= rt -> !(rt > rs).
@@ -2808,7 +2441,7 @@ def : Pat <(i1 (setuge (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
def : Pat <(i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
(i1 (NOT_p (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1))))>;
-// Map from cmpleu(Rs, Rs) -> !cmpgtu(Rs, Rs).
+// Map from cmpleu(Rs, Rt) -> !cmpgtu(Rs, Rt).
// Map from (Rs <= Rt) -> !(Rs > Rt).
def : Pat <(i1 (setule (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
(i1 (NOT_p (CMPGTUrr (i32 IntRegs:$src1), (i32 IntRegs:$src2))))>;
@@ -2904,6 +2537,13 @@ def: Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)),
(i64 (COMBINE_rr (TFRI 0), (LDriw ADDRriS11_2:$src1)))>,
Requires<[NoV4T]>;
+let AddedComplexity = 100 in
+def: Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
+ (i64 (COMBINE_rr (TFRI 0), (LDriw_indexed IntRegs:$src1,
+ s11_2ExtPred:$offset)))>,
+ Requires<[NoV4T]>;
+
+let AddedComplexity = 10 in
def: Pat <(i32 (zextloadi1 ADDRriS11_0:$src1)),
(i32 (LDriw ADDRriS11_0:$src1))>;
@@ -2920,6 +2560,48 @@ def : Pat <(i64 (anyext (i1 PredRegs:$src1))),
(i64 (SXTW (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))))>;
+let AddedComplexity = 100 in
+def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
+ (i32 32))),
+ (i64 (zextloadi32 (i32 (add IntRegs:$src2,
+ s11_2ExtPred:$offset2)))))),
+ (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
+ (LDriw_indexed IntRegs:$src2,
+ s11_2ExtPred:$offset2)))>;
+
+def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
+ (i32 32))),
+ (i64 (zextloadi32 ADDRriS11_2:$srcLow)))),
+ (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
+ (LDriw ADDRriS11_2:$srcLow)))>;
+
+def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
+ (i32 32))),
+ (i64 (zext (i32 IntRegs:$srcLow))))),
+ (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
+ IntRegs:$srcLow))>;
+
+let AddedComplexity = 100 in
+def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
+ (i32 32))),
+ (i64 (zextloadi32 (i32 (add IntRegs:$src2,
+ s11_2ExtPred:$offset2)))))),
+ (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
+ (LDriw_indexed IntRegs:$src2,
+ s11_2ExtPred:$offset2)))>;
+
+def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
+ (i32 32))),
+ (i64 (zextloadi32 ADDRriS11_2:$srcLow)))),
+ (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
+ (LDriw ADDRriS11_2:$srcLow)))>;
+
+def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
+ (i32 32))),
+ (i64 (zext (i32 IntRegs:$srcLow))))),
+ (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
+ IntRegs:$srcLow))>;
+
// Any extended 64-bit load.
// anyext i32 -> i64
def: Pat <(i64 (extloadi32 ADDRriS11_2:$src1)),
@@ -3054,19 +2736,6 @@ let AddedComplexity = 100 in
def : Pat<(i32 (sext_inreg (Hexagon_ARGEXTEND (i32 IntRegs:$src1)), i16)),
(COPY (i32 IntRegs:$src1))>;
-def SDHexagonBR_JT: SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
-def HexagonBR_JT: SDNode<"HexagonISD::BR_JT", SDHexagonBR_JT, [SDNPHasChain]>;
-
-let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in
-def BR_JT : JRInst<(outs), (ins IntRegs:$src),
- "jumpr $src",
- [(HexagonBR_JT (i32 IntRegs:$src))]>;
-
-let isBranch=1, isIndirectBranch=1, isTerminator=1 in
-def BRIND : JRInst<(outs), (ins IntRegs:$src),
- "jumpr $src",
- [(brind (i32 IntRegs:$src))]>;
-
def HexagonWrapperJT: SDNode<"HexagonISD::WrapperJT", SDTIntUnaryOp>;
def : Pat<(HexagonWrapperJT tjumptable:$dst),
diff --git a/lib/Target/Hexagon/HexagonInstrInfoV3.td b/lib/Target/Hexagon/HexagonInstrInfoV3.td
index 157ab3d..7e75554 100644
--- a/lib/Target/Hexagon/HexagonInstrInfoV3.td
+++ b/lib/Target/Hexagon/HexagonInstrInfoV3.td
@@ -11,6 +11,11 @@
//
//===----------------------------------------------------------------------===//
+def callv3 : SDNode<"HexagonISD::CALLv3", SDT_SPCall,
+ [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;
+
+def callv3nr : SDNode<"HexagonISD::CALLv3nr", SDT_SPCall,
+ [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;
//===----------------------------------------------------------------------===//
// J +
@@ -40,41 +45,6 @@ let isCall = 1, neverHasSideEffects = 1,
[]>, Requires<[HasV3TOnly]>;
}
-
-// Jump to address from register
-// if(p?.new) jumpr:t r?
-let isReturn = 1, isTerminator = 1, isBarrier = 1,
- Defs = [PC], Uses = [R31] in {
- def JMPR_cdnPt_V3: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1.new) jumpr:t $src2",
- []>, Requires<[HasV3T]>;
-}
-
-// if (!p?.new) jumpr:t r?
-let isReturn = 1, isTerminator = 1, isBarrier = 1,
- Defs = [PC], Uses = [R31] in {
- def JMPR_cdnNotPt_V3: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1.new) jumpr:t $src2",
- []>, Requires<[HasV3T]>;
-}
-
-// Not taken.
-// if(p?.new) jumpr:nt r?
-let isReturn = 1, isTerminator = 1, isBarrier = 1,
- Defs = [PC], Uses = [R31] in {
- def JMPR_cdnPnt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1.new) jumpr:nt $src2",
- []>, Requires<[HasV3T]>;
-}
-
-// if (!p?.new) jumpr:nt r?
-let isReturn = 1, isTerminator = 1, isBarrier = 1,
- Defs = [PC], Uses = [R31] in {
- def JMPR_cdnNotPnt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1.new) jumpr:nt $src2",
- []>, Requires<[HasV3T]>;
-}
-
//===----------------------------------------------------------------------===//
// JR -
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/Hexagon/HexagonInstrInfoV4.td b/lib/Target/Hexagon/HexagonInstrInfoV4.td
index 1d0643d..fee83fb 100644
--- a/lib/Target/Hexagon/HexagonInstrInfoV4.td
+++ b/lib/Target/Hexagon/HexagonInstrInfoV4.td
@@ -95,164 +95,6 @@ def NumUsesBelowThresCONST32 : PatFrag<(ops node:$addr),
//===----------------------------------------------------------------------===//
// ALU32 +
//===----------------------------------------------------------------------===//
-
-// Shift halfword.
-
-let isPredicated = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in {
-def ASLH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1) $dst = aslh($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ASLH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1) $dst = aslh($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ASLH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1.new) $dst = aslh($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ASLH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1.new) $dst = aslh($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ASRH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1) $dst = asrh($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ASRH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1) $dst = asrh($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ASRH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1.new) $dst = asrh($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ASRH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1.new) $dst = asrh($src2)",
- []>,
- Requires<[HasV4T]>;
-}
-
-// Sign extend.
-
-let isPredicated = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in {
-def SXTB_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1) $dst = sxtb($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def SXTB_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1) $dst = sxtb($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def SXTB_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1.new) $dst = sxtb($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def SXTB_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1.new) $dst = sxtb($src2)",
- []>,
- Requires<[HasV4T]>;
-
-
-def SXTH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1) $dst = sxth($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def SXTH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1) $dst = sxth($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def SXTH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1.new) $dst = sxth($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def SXTH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1.new) $dst = sxth($src2)",
- []>,
- Requires<[HasV4T]>;
-}
-
-// Zero exten.
-
-let neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in {
-def ZXTB_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1) $dst = zxtb($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ZXTB_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1) $dst = zxtb($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ZXTB_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1.new) $dst = zxtb($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ZXTB_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1.new) $dst = zxtb($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ZXTH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1) $dst = zxth($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ZXTH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1) $dst = zxth($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ZXTH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1.new) $dst = zxth($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ZXTH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1.new) $dst = zxth($src2)",
- []>,
- Requires<[HasV4T]>;
-}
-
// Generate frame index addresses.
let neverHasSideEffects = 1, isReMaterializable = 1,
isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in
@@ -367,105 +209,31 @@ def COMBINE_iI_V4 : ALU32_ii<(outs DoubleRegs:$dst),
//===----------------------------------------------------------------------===//
// LD +
//===----------------------------------------------------------------------===//
-//
-// These absolute set addressing mode instructions accept immediate as
-// an operand. We have duplicated these patterns to take global address.
-
+//===----------------------------------------------------------------------===//
+// Template class for load instructions with Absolute set addressing mode.
+//===----------------------------------------------------------------------===//
let isExtended = 1, opExtendable = 2, neverHasSideEffects = 1,
-validSubTargets = HasV4SubT in {
-def LDrid_abs_setimm_V4 : LDInst2<(outs DoubleRegs:$dst1, IntRegs:$dst2),
+validSubTargets = HasV4SubT, addrMode = AbsoluteSet in
+class T_LD_abs_set<string mnemonic, RegisterClass RC>:
+ LDInst2<(outs RC:$dst1, IntRegs:$dst2),
(ins u0AlwaysExt:$addr),
- "$dst1 = memd($dst2=##$addr)",
+ "$dst1 = "#mnemonic#"($dst2=##$addr)",
[]>,
Requires<[HasV4T]>;
-// Rd=memb(Re=#U6)
-def LDrib_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins u0AlwaysExt:$addr),
- "$dst1 = memb($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-
-// Rd=memh(Re=#U6)
-def LDrih_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins u0AlwaysExt:$addr),
- "$dst1 = memh($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-
-// Rd=memub(Re=#U6)
-def LDriub_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins u0AlwaysExt:$addr),
- "$dst1 = memub($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-
-// Rd=memuh(Re=#U6)
-def LDriuh_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins u0AlwaysExt:$addr),
- "$dst1 = memuh($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-
-// Rd=memw(Re=#U6)
-def LDriw_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins u0AlwaysExt:$addr),
- "$dst1 = memw($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-}
-
-// Following patterns are defined for absolute set addressing mode
-// instruction which take global address as operand.
-let isExtended = 1, opExtendable = 2, neverHasSideEffects = 1,
-validSubTargets = HasV4SubT in {
-def LDrid_abs_set_V4 : LDInst2<(outs DoubleRegs:$dst1, IntRegs:$dst2),
- (ins globaladdressExt:$addr),
- "$dst1 = memd($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
+def LDrid_abs_set_V4 : T_LD_abs_set <"memd", DoubleRegs>;
+def LDrib_abs_set_V4 : T_LD_abs_set <"memb", IntRegs>;
+def LDriub_abs_set_V4 : T_LD_abs_set <"memub", IntRegs>;
+def LDrih_abs_set_V4 : T_LD_abs_set <"memh", IntRegs>;
+def LDriw_abs_set_V4 : T_LD_abs_set <"memw", IntRegs>;
+def LDriuh_abs_set_V4 : T_LD_abs_set <"memuh", IntRegs>;
-// Rd=memb(Re=#U6)
-def LDrib_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins globaladdressExt:$addr),
- "$dst1 = memb($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-
-// Rd=memh(Re=#U6)
-def LDrih_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins globaladdressExt:$addr),
- "$dst1 = memh($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-
-// Rd=memub(Re=#U6)
-def LDriub_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins globaladdressExt:$addr),
- "$dst1 = memub($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-
-// Rd=memuh(Re=#U6)
-def LDriuh_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins globaladdressExt:$addr),
- "$dst1 = memuh($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-
-// Rd=memw(Re=#U6)
-def LDriw_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins globaladdressExt:$addr),
- "$dst1 = memw($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-}
// multiclass for load instructions with base + register offset
// addressing mode
multiclass ld_idxd_shl_pbase<string mnemonic, RegisterClass RC, bit isNot,
bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : LDInst2<(outs RC:$dst),
(ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -474,7 +242,7 @@ multiclass ld_idxd_shl_pbase<string mnemonic, RegisterClass RC, bit isNot,
}
multiclass ld_idxd_shl_pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ld_idxd_shl_pbase<mnemonic, RC, PredNot, 0>;
// Predicate new
defm _cdn#NAME : ld_idxd_shl_pbase<mnemonic, RC, PredNot, 1>;
@@ -498,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
@@ -596,329 +375,6 @@ def : Pat <(i32 (load (add IntRegs:$src1, IntRegs:$src2))),
Requires<[HasV4T]>;
}
-let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
-def LDd_GP_V4 : LDInst2<(outs DoubleRegs:$dst),
- (ins globaladdress:$global),
- "$dst=memd(#$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rtt=memd(##global)
-let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
-validSubTargets = HasV4SubT in {
-def LDd_GP_cPt_V4 : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1) $dst=memd(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-
-// if (!Pv) Rtt=memd(##global)
-def LDd_GP_cNotPt_V4 : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1) $dst=memd(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rtt=memd(##global)
-def LDd_GP_cdnPt_V4 : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1.new) $dst=memd(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-
-// if (!Pv) Rtt=memd(##global)
-def LDd_GP_cdnNotPt_V4 : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1.new) $dst=memd(##$global)",
- []>,
- Requires<[HasV4T]>;
-}
-
-let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
-def LDb_GP_V4 : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst=memb(#$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memb(##global)
-let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
-validSubTargets = HasV4SubT in {
-def LDb_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1) $dst=memb(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) Rt=memb(##global)
-def LDb_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1) $dst=memb(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memb(##global)
-def LDb_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1.new) $dst=memb(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) Rt=memb(##global)
-def LDb_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1.new) $dst=memb(##$global)",
- []>,
- Requires<[HasV4T]>;
-}
-
-let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
-def LDub_GP_V4 : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst=memub(#$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memub(##global)
-let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
-validSubTargets = HasV4SubT in {
-def LDub_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1) $dst=memub(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-
-// if (!Pv) Rt=memub(##global)
-def LDub_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1) $dst=memub(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memub(##global)
-def LDub_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1.new) $dst=memub(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-
-// if (!Pv) Rt=memub(##global)
-def LDub_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1.new) $dst=memub(##$global)",
- []>,
- Requires<[HasV4T]>;
-}
-
-let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
-def LDh_GP_V4 : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst=memh(#$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memh(##global)
-let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
-validSubTargets = HasV4SubT in {
-def LDh_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1) $dst=memh(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) Rt=memh(##global)
-def LDh_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1) $dst=memh(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memh(##global)
-def LDh_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1.new) $dst=memh(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) Rt=memh(##global)
-def LDh_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1.new) $dst=memh(##$global)",
- []>,
- Requires<[HasV4T]>;
-}
-
-let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
-def LDuh_GP_V4 : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst=memuh(#$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memuh(##global)
-let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
-validSubTargets = HasV4SubT in {
-def LDuh_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1) $dst=memuh(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) Rt=memuh(##global)
-def LDuh_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1) $dst=memuh(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memuh(##global)
-def LDuh_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1.new) $dst=memuh(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) Rt=memuh(##global)
-def LDuh_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1.new) $dst=memuh(##$global)",
- []>,
- Requires<[HasV4T]>;
-}
-
-let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
-def LDw_GP_V4 : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst=memw(#$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memw(##global)
-let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
-validSubTargets = HasV4SubT in {
-def LDw_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1) $dst=memw(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-
-// if (!Pv) Rt=memw(##global)
-def LDw_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1) $dst=memw(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memw(##global)
-def LDw_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1.new) $dst=memw(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-
-// if (!Pv) Rt=memw(##global)
-def LDw_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1.new) $dst=memw(##$global)",
- []>,
- Requires<[HasV4T]>;
-}
-
-
-def : Pat <(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)),
- (i64 (LDd_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-def : Pat <(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)),
- (i32 (LDw_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-def : Pat <(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)),
- (i32 (LDuh_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-def : Pat <(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)),
- (i32 (LDub_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-// Map from load(globaladdress) -> memw(#foo + 0)
-let AddedComplexity = 100 in
-def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))),
- (i64 (LDd_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-// Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd
-let AddedComplexity = 100 in
-def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))),
- (i1 (TFR_PdRs (i32 (LDb_GP_V4 tglobaladdr:$global))))>,
- Requires<[HasV4T]>;
-
-// When the Interprocedural Global Variable optimizer realizes that a certain
-// global variable takes only two constant values, it shrinks the global to
-// a boolean. Catch those loads here in the following 3 patterns.
-let AddedComplexity = 100 in
-def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-let AddedComplexity = 100 in
-def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-// Map from load(globaladdress) -> memb(#foo)
-let AddedComplexity = 100 in
-def : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-// Map from load(globaladdress) -> memb(#foo)
-let AddedComplexity = 100 in
-def : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-let AddedComplexity = 100 in
-def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDub_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-// Map from load(globaladdress) -> memub(#foo)
-let AddedComplexity = 100 in
-def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDub_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-// Map from load(globaladdress) -> memh(#foo)
-let AddedComplexity = 100 in
-def : Pat <(i32 (extloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDh_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-// Map from load(globaladdress) -> memh(#foo)
-let AddedComplexity = 100 in
-def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDh_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-// Map from load(globaladdress) -> memuh(#foo)
-let AddedComplexity = 100 in
-def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDuh_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-// Map from load(globaladdress) -> memw(#foo)
-let AddedComplexity = 100 in
-def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDw_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
// zext i1->i64
def : Pat <(i64 (zext (i1 PredRegs:$src1))),
(i64 (COMBINE_Ir_V4 0, (MUX_ii (i1 PredRegs:$src1), 1, 0)))>,
@@ -1008,78 +464,30 @@ def: Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
// ST +
//===----------------------------------------------------------------------===//
///
-/// Assumptions::: ****** DO NOT IGNORE ********
-/// 1. Make sure that in post increment store, the zero'th operand is always the
-/// post increment operand.
-/// 2. Make sure that the store value operand(Rt/Rtt) in a store is always the
-/// last operand.
-///
-
-// memd(Re=#U)=Rtt
-let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in {
-def STrid_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
- (ins DoubleRegs:$src1, u0AlwaysExt:$src2),
- "memd($dst1=##$src2) = $src1",
- []>,
- Requires<[HasV4T]>;
-
-// memb(Re=#U)=Rs
-def STrib_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
- (ins IntRegs:$src1, u0AlwaysExt:$src2),
- "memb($dst1=##$src2) = $src1",
- []>,
- Requires<[HasV4T]>;
-
-// memh(Re=#U)=Rs
-def STrih_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
- (ins IntRegs:$src1, u0AlwaysExt:$src2),
- "memh($dst1=##$src2) = $src1",
- []>,
- Requires<[HasV4T]>;
-
-// memw(Re=#U)=Rs
-def STriw_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
- (ins IntRegs:$src1, u0AlwaysExt:$src2),
- "memw($dst1=##$src2) = $src1",
- []>,
- Requires<[HasV4T]>;
-}
-
-// memd(Re=#U)=Rtt
-let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in {
-def STrid_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
- (ins DoubleRegs:$src1, globaladdressExt:$src2),
- "memd($dst1=##$src2) = $src1",
- []>,
- Requires<[HasV4T]>;
-
-// memb(Re=#U)=Rs
-def STrib_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
- (ins IntRegs:$src1, globaladdressExt:$src2),
- "memb($dst1=##$src2) = $src1",
- []>,
- Requires<[HasV4T]>;
-
-// memh(Re=#U)=Rs
-def STrih_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
- (ins IntRegs:$src1, globaladdressExt:$src2),
- "memh($dst1=##$src2) = $src1",
+//===----------------------------------------------------------------------===//
+// Template class for store instructions with Absolute set addressing mode.
+//===----------------------------------------------------------------------===//
+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),
+ mnemonic#"($dst1=##$src2) = $src1",
[]>,
Requires<[HasV4T]>;
-// memw(Re=#U)=Rs
-def STriw_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
- (ins IntRegs:$src1, globaladdressExt:$src2),
- "memw($dst1=##$src2) = $src1",
- []>,
- Requires<[HasV4T]>;
-}
+def STrid_abs_set_V4 : T_ST_abs_set <"memd", DoubleRegs>;
+def STrib_abs_set_V4 : T_ST_abs_set <"memb", IntRegs>;
+def STrih_abs_set_V4 : T_ST_abs_set <"memh", IntRegs>;
+def STriw_abs_set_V4 : T_ST_abs_set <"memw", IntRegs>;
+//===----------------------------------------------------------------------===//
// multiclass for store instructions with base + register offset addressing
// mode
+//===----------------------------------------------------------------------===//
multiclass ST_Idxd_shl_Pbase<string mnemonic, RegisterClass RC, bit isNot,
bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : STInst2<(outs),
(ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
RC:$src5),
@@ -1090,7 +498,7 @@ multiclass ST_Idxd_shl_Pbase<string mnemonic, RegisterClass RC, bit isNot,
}
multiclass ST_Idxd_shl_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 0>;
// Predicate new
defm _cdn#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 1>;
@@ -1118,7 +526,7 @@ multiclass ST_Idxd_shl<string mnemonic, string CextOp, RegisterClass RC> {
// addressing mode.
multiclass ST_Idxd_shl_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME#_nv_V4 : NVInst_V4<(outs),
(ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
RC:$src5),
@@ -1129,7 +537,7 @@ multiclass ST_Idxd_shl_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
}
multiclass ST_Idxd_shl_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 0>;
// Predicate new
defm _cdn#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 1>;
@@ -1155,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 {
@@ -1192,17 +603,59 @@ def : Pat<(store (i64 DoubleRegs:$src4),
u2ImmPred:$src3, DoubleRegs:$src4)>;
}
-// memd(Ru<<#u2+#U6)=Rtt
-let isExtended = 1, opExtendable = 2, AddedComplexity = 10,
-validSubTargets = HasV4SubT in
-def STrid_shl_V4 : STInst<(outs),
- (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, DoubleRegs:$src4),
- "memd($src1<<#$src2+#$src3) = $src4",
- [(store (i64 DoubleRegs:$src4),
+let isExtended = 1, opExtendable = 2 in
+class T_ST_LongOff <string mnemonic, PatFrag stOp, RegisterClass RC, ValueType VT> :
+ STInst<(outs),
+ (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, RC:$src4),
+ mnemonic#"($src1<<#$src2+##$src3) = $src4",
+ [(stOp (VT RC:$src4),
(add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
u0AlwaysExtPred:$src3))]>,
Requires<[HasV4T]>;
+let isExtended = 1, opExtendable = 2, mayStore = 1, isNVStore = 1 in
+class T_ST_LongOff_nv <string mnemonic> :
+ NVInst_V4<(outs),
+ (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
+ mnemonic#"($src1<<#$src2+##$src3) = $src4.new",
+ []>,
+ Requires<[HasV4T]>;
+
+multiclass ST_LongOff <string mnemonic, string BaseOp, PatFrag stOp> {
+ let BaseOpcode = BaseOp#"_shl" in {
+ let isNVStorable = 1 in
+ def NAME#_V4 : T_ST_LongOff<mnemonic, stOp, IntRegs, i32>;
+
+ def NAME#_nv_V4 : T_ST_LongOff_nv<mnemonic>;
+ }
+}
+
+let AddedComplexity = 10, validSubTargets = HasV4SubT in {
+ def STrid_shl_V4 : T_ST_LongOff<"memd", store, DoubleRegs, i64>;
+ defm STrib_shl : ST_LongOff <"memb", "STrib", truncstorei8>, NewValueRel;
+ defm STrih_shl : ST_LongOff <"memh", "Strih", truncstorei16>, NewValueRel;
+ defm STriw_shl : ST_LongOff <"memw", "STriw", store>, NewValueRel;
+}
+
+let AddedComplexity = 40 in
+multiclass T_ST_LOff_Pats <InstHexagon I, RegisterClass RC, ValueType VT,
+ PatFrag stOp> {
+ def : Pat<(stOp (VT RC:$src4),
+ (add (shl IntRegs:$src1, u2ImmPred:$src2),
+ (NumUsesBelowThresCONST32 tglobaladdr:$src3))),
+ (I IntRegs:$src1, u2ImmPred:$src2, tglobaladdr:$src3, RC:$src4)>;
+
+ def : Pat<(stOp (VT RC:$src4),
+ (add IntRegs:$src1,
+ (NumUsesBelowThresCONST32 tglobaladdr:$src3))),
+ (I IntRegs:$src1, 0, tglobaladdr:$src3, RC:$src4)>;
+}
+
+defm : T_ST_LOff_Pats<STrid_shl_V4, DoubleRegs, i64, store>;
+defm : T_ST_LOff_Pats<STriw_shl_V4, IntRegs, i32, store>;
+defm : T_ST_LOff_Pats<STrib_shl_V4, IntRegs, i32, truncstorei8>;
+defm : T_ST_LOff_Pats<STrih_shl_V4, IntRegs, i32, truncstorei16>;
+
// memd(Rx++#s4:3)=Rtt
// memd(Rx++#s4:3:circ(Mu))=Rtt
// memd(Rx++I:circ(Mu))=Rtt
@@ -1222,7 +675,7 @@ def STrid_shl_V4 : STInst<(outs),
//===----------------------------------------------------------------------===//
multiclass ST_Imm_Pbase<string mnemonic, Operand OffsetOp, bit isNot,
bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : STInst2<(outs),
(ins PredRegs:$src1, IntRegs:$src2, OffsetOp:$src3, s6Ext:$src4),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -1232,7 +685,7 @@ multiclass ST_Imm_Pbase<string mnemonic, Operand OffsetOp, bit isNot,
}
multiclass ST_Imm_Pred<string mnemonic, Operand OffsetOp, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 0>;
// Predicate new
defm _cdn#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 1>;
@@ -1257,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 {
@@ -1280,17 +738,6 @@ def : Pat <(truncstorei8 s8ExtPred:$src2, (i32 IntRegs:$src1)),
(STrib_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
Requires<[HasV4T]>;
-// memb(Ru<<#u2+#U6)=Rt
-let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
-validSubTargets = HasV4SubT in
-def STrib_shl_V4 : STInst<(outs),
- (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
- "memb($src1<<#$src2+#$src3) = $src4",
- [(truncstorei8 (i32 IntRegs:$src4),
- (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
- u0AlwaysExtPred:$src3))]>,
- Requires<[HasV4T]>;
-
// memb(Rx++#s4:0:circ(Mu))=Rt
// memb(Rx++I:circ(Mu))=Rt
// memb(Rx++Mu)=Rt
@@ -1311,17 +758,6 @@ def : Pat <(truncstorei16 s8ExtPred:$src2, (i32 IntRegs:$src1)),
// TODO: needs to be implemented.
// memh(Ru<<#u2+#U6)=Rt.H
-// memh(Ru<<#u2+#U6)=Rt
-let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
-validSubTargets = HasV4SubT in
-def STrih_shl_V4 : STInst<(outs),
- (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
- "memh($src1<<#$src2+#$src3) = $src4",
- [(truncstorei16 (i32 IntRegs:$src4),
- (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
- u0AlwaysExtPred:$src3))]>,
- Requires<[HasV4T]>;
-
// memh(Rx++#s4:1:circ(Mu))=Rt.H
// memh(Rx++#s4:1:circ(Mu))=Rt
// memh(Rx++I:circ(Mu))=Rt.H
@@ -1358,241 +794,11 @@ def : Pat <(store s8ExtPred:$src2, (i32 IntRegs:$src1)),
(STriw_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
Requires<[HasV4T]>;
-// memw(Ru<<#u2+#U6)=Rt
-let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
-validSubTargets = HasV4SubT in
-def STriw_shl_V4 : STInst<(outs),
- (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
- "memw($src1<<#$src2+#$src3) = $src4",
- [(store (i32 IntRegs:$src4),
- (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
- u0AlwaysExtPred:$src3))]>,
- Requires<[HasV4T]>;
-
// memw(Rx++#s4:2)=Rt
// memw(Rx++#s4:2:circ(Mu))=Rt
// memw(Rx++I:circ(Mu))=Rt
// memw(Rx++Mu)=Rt
// memw(Rx++Mu:brev)=Rt
-// memw(gp+#u16:2)=Rt
-
-
-// memd(#global)=Rtt
-let isPredicable = 1, mayStore = 1, neverHasSideEffects = 1,
-validSubTargets = HasV4SubT in
-def STd_GP_V4 : STInst2<(outs),
- (ins globaladdress:$global, DoubleRegs:$src),
- "memd(#$global) = $src",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memd(##global) = Rtt
-let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1,
-isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
-def STd_GP_cPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
- "if ($src1) memd(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memd(##global) = Rtt
-def STd_GP_cNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
- "if (!$src1) memd(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memd(##global) = Rtt
-def STd_GP_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
- "if ($src1.new) memd(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memd(##global) = Rtt
-def STd_GP_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
- "if (!$src1.new) memd(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-}
-
-// memb(#global)=Rt
-let isPredicable = 1, neverHasSideEffects = 1, isNVStorable = 1,
-validSubTargets = HasV4SubT in
-def STb_GP_V4 : STInst2<(outs),
- (ins globaladdress:$global, IntRegs:$src),
- "memb(#$global) = $src",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memb(##global) = Rt
-let neverHasSideEffects = 1, isPredicated = 1, isNVStorable = 1,
-isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
-def STb_GP_cPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1) memb(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memb(##global) = Rt
-def STb_GP_cNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1) memb(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memb(##global) = Rt
-def STb_GP_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1.new) memb(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memb(##global) = Rt
-def STb_GP_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1.new) memb(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-}
-
-// memh(#global)=Rt
-let isPredicable = 1, neverHasSideEffects = 1, isNVStorable = 1,
-validSubTargets = HasV4SubT in
-def STh_GP_V4 : STInst2<(outs),
- (ins globaladdress:$global, IntRegs:$src),
- "memh(#$global) = $src",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memh(##global) = Rt
-let neverHasSideEffects = 1, isPredicated = 1, isNVStorable = 1,
-isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
-def STh_GP_cPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1) memh(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memh(##global) = Rt
-def STh_GP_cNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1) memh(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memh(##global) = Rt
-def STh_GP_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1.new) memh(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memh(##global) = Rt
-def STh_GP_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1.new) memh(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-}
-
-// memw(#global)=Rt
-let isPredicable = 1, neverHasSideEffects = 1, isNVStorable = 1,
-validSubTargets = HasV4SubT in
-def STw_GP_V4 : STInst2<(outs),
- (ins globaladdress:$global, IntRegs:$src),
- "memw(#$global) = $src",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memw(##global) = Rt
-let neverHasSideEffects = 1, isPredicated = 1, isNVStorable = 1,
-isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
-def STw_GP_cPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1) memw(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memw(##global) = Rt
-def STw_GP_cNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1) memw(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memw(##global) = Rt
-def STw_GP_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1.new) memw(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memw(##global) = Rt
-def STw_GP_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1.new) memw(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-}
-
-// 64 bit atomic store
-def : Pat <(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global),
- (i64 DoubleRegs:$src1)),
- (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
- Requires<[HasV4T]>;
-
-// Map from store(globaladdress) -> memd(#foo)
-let AddedComplexity = 100 in
-def : Pat <(store (i64 DoubleRegs:$src1),
- (HexagonCONST32_GP tglobaladdr:$global)),
- (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
- Requires<[HasV4T]>;
-
-// 8 bit atomic store
-def : Pat < (atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global),
- (i32 IntRegs:$src1)),
- (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[HasV4T]>;
-
-// Map from store(globaladdress) -> memb(#foo)
-let AddedComplexity = 100 in
-def : Pat<(truncstorei8 (i32 IntRegs:$src1),
- (HexagonCONST32_GP tglobaladdr:$global)),
- (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[HasV4T]>;
-
-// Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1"
-// to "r0 = 1; memw(#foo) = r0"
-let AddedComplexity = 100 in
-def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
- (STb_GP_V4 tglobaladdr:$global, (TFRI 1))>,
- Requires<[HasV4T]>;
-
-def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
- (i32 IntRegs:$src1)),
- (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[HasV4T]>;
-
-// Map from store(globaladdress) -> memh(#foo)
-let AddedComplexity = 100 in
-def : Pat<(truncstorei16 (i32 IntRegs:$src1),
- (HexagonCONST32_GP tglobaladdr:$global)),
- (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[HasV4T]>;
-
-// 32 bit atomic store
-def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global),
- (i32 IntRegs:$src1)),
- (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[HasV4T]>;
-
-// Map from store(globaladdress) -> memw(#foo)
-let AddedComplexity = 100 in
-def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
- (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[HasV4T]>;
//===----------------------------------------------------------------------===
// ST -
@@ -1607,7 +813,7 @@ def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
//
multiclass ST_Idxd_Pbase_nv<string mnemonic, RegisterClass RC,
Operand predImmOp, bit isNot, bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME#_nv_V4 : NVInst_V4<(outs),
(ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -1618,7 +824,7 @@ multiclass ST_Idxd_Pbase_nv<string mnemonic, RegisterClass RC,
multiclass ST_Idxd_Pred_nv<string mnemonic, RegisterClass RC, Operand predImmOp,
bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 0>;
// Predicate new
defm _cdn#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 1>;
@@ -1648,19 +854,24 @@ 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.
// and MEMri operand.
multiclass ST_MEMri_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME#_nv_V4 : NVInst_V4<(outs),
(ins PredRegs:$src1, MEMri:$addr, RC: $src2),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -1670,7 +881,7 @@ multiclass ST_MEMri_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
}
multiclass ST_MEMri_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 0>;
// Predicate new
@@ -1701,19 +912,15 @@ 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;
-// memb(Ru<<#u2+#U6)=Nt.new
-let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
-isNVStore = 1, validSubTargets = HasV4SubT in
-def STrib_shl_nv_V4 : NVInst_V4<(outs),
- (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
- "memb($src1<<#$src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
+ 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;
+}
//===----------------------------------------------------------------------===//
// Post increment store
@@ -1722,7 +929,7 @@ def STrib_shl_nv_V4 : NVInst_V4<(outs),
multiclass ST_PostInc_Pbase_nv<string mnemonic, RegisterClass RC, Operand ImmOp,
bit isNot, bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset, RC:$src3),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -1734,7 +941,7 @@ multiclass ST_PostInc_Pbase_nv<string mnemonic, RegisterClass RC, Operand ImmOp,
multiclass ST_PostInc_Pred_nv<string mnemonic, RegisterClass RC,
Operand ImmOp, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 0>;
// Predicate new
let Predicates = [HasV4T], validSubTargets = HasV4SubT in
@@ -1762,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;
@@ -1772,146 +979,15 @@ defm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel;
// memb(Rx++I:circ(Mu))=Nt.new
// memb(Rx++Mu)=Nt.new
// memb(Rx++Mu:brev)=Nt.new
-
-// memb(#global)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1 in
-def STb_GP_nv_V4 : NVInst_V4<(outs),
- (ins globaladdress:$global, IntRegs:$src),
- "memb(#$global) = $src.new",
- []>,
- Requires<[HasV4T]>;
-
-// memh(Ru<<#u2+#U6)=Nt.new
-let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
-isNVStore = 1, validSubTargets = HasV4SubT in
-def STrih_shl_nv_V4 : NVInst_V4<(outs),
- (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
- "memh($src1<<#$src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
// memh(Rx++#s4:1:circ(Mu))=Nt.new
// memh(Rx++I:circ(Mu))=Nt.new
// memh(Rx++Mu)=Nt.new
// memh(Rx++Mu:brev)=Nt.new
-// memh(#global)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1 in
-def STh_GP_nv_V4 : NVInst_V4<(outs),
- (ins globaladdress:$global, IntRegs:$src),
- "memh(#$global) = $src.new",
- []>,
- Requires<[HasV4T]>;
-
-// memw(Ru<<#u2+#U6)=Nt.new
-let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
-isNVStore = 1, validSubTargets = HasV4SubT in
-def STriw_shl_nv_V4 : NVInst_V4<(outs),
- (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
- "memw($src1<<#$src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
// memw(Rx++#s4:2:circ(Mu))=Nt.new
// memw(Rx++I:circ(Mu))=Nt.new
// memw(Rx++Mu)=Nt.new
// memw(Rx++Mu:brev)=Nt.new
-// memw(gp+#u16:2)=Nt.new
-
-let mayStore = 1, neverHasSideEffects = 1, isNVStore = 1,
-validSubTargets = HasV4SubT in
-def STw_GP_nv_V4 : NVInst_V4<(outs),
- (ins globaladdress:$global, IntRegs:$src),
- "memw(#$global) = $src.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memb(##global) = Rt
-let mayStore = 1, neverHasSideEffects = 1, isNVStore = 1,
-isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
-def STb_GP_cPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1) memb(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memb(##global) = Rt
-def STb_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1) memb(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memb(##global) = Rt
-def STb_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1.new) memb(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memb(##global) = Rt
-def STb_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1.new) memb(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memh(##global) = Rt
-def STh_GP_cPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1) memh(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memh(##global) = Rt
-def STh_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1) memh(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memh(##global) = Rt
-def STh_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1.new) memh(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memh(##global) = Rt
-def STh_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1.new) memh(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memw(##global) = Rt
-def STw_GP_cPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1) memw(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memw(##global) = Rt
-def STw_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1) memw(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memw(##global) = Rt
-def STw_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1.new) memw(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memw(##global) = Rt
-def STw_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1.new) memw(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-}
//===----------------------------------------------------------------------===//
// NV/ST -
@@ -1921,181 +997,195 @@ def STw_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
// 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]>;
-
- def _nv_V4 : NVInst_V4<(outs),
- (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
- !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
- !strconcat("($src1.new, $src2)) jump:",
- !strconcat(TakenStr, " $offset"))))),
- []>,
- Requires<[HasV4T]>;
-}
-
-multiclass NVJ_type_basic_2ndDotNew<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]>;
-
- 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]>;
-}
-
-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]>;
-
- 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]>;
-}
-
-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 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]>;
+//===----------------------------------------------------------------------===//
+// multiclass/template class for the new-value compare jumps with the register
+// operands.
+//===----------------------------------------------------------------------===//
- 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]>;
+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]> {
+
+ bits<5> src1;
+ bits<5> src2;
+ bits<3> Ns; // New-Value Operand
+ bits<5> RegOp; // Non New-Value Operand
+ bits<11> offset;
+
+ let isBrTaken = !if(isTaken, "true", "false");
+ let isPredicatedFalse = isNegCond;
+
+ let Ns = !if(!eq(NvOpNum, 0), src1{2-0}, src2{2-0});
+ let RegOp = !if(!eq(NvOpNum, 0), src2, src1);
+
+ let IClass = 0b0010;
+ let Inst{26} = 0b0;
+ let Inst{25-23} = majOp;
+ let Inst{22} = isNegCond;
+ let Inst{18-16} = Ns;
+ let Inst{13} = isTaken;
+ let Inst{12-8} = RegOp;
+ let Inst{21-20} = offset{10-9};
+ let Inst{7-1} = offset{8-2};
+}
+
+
+multiclass 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>;
+}
+
+// NvOpNum = 0 -> First Operand is a new-value Register
+// NvOpNum = 1 -> Second Operand is a new-value Register
+
+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]> {
+
+ let isPredicatedFalse = isNegCond;
+ let isBrTaken = !if(isTaken, "true", "false");
+
+ bits<3> src1;
+ bits<5> src2;
+ bits<11> offset;
+
+ let IClass = 0b0010;
+ let Inst{26} = 0b1;
+ let Inst{25-23} = majOp;
+ let Inst{22} = isNegCond;
+ let Inst{18-16} = src1;
+ let Inst{13} = isTaken;
+ let Inst{12-8} = src2;
+ let Inst{21-20} = offset{10-9};
+ let Inst{7-1} = offset{8-2};
+}
+
+multiclass NVJri_cond<string mnemonic, bits<3> majOp, bit isNegCond> {
+ // Branch not taken:
+ def _nt_V4: NVJri_template<mnemonic, majOp, isNegCond, 0>;
+ // Branch taken:
+ def _t_V4: NVJri_template<mnemonic, majOp, isNegCond, 1>;
+}
+
+multiclass NVJri_base<string mnemonic, string BaseOp, bits<3> majOp> {
+ let BaseOpcode = BaseOp#_NVJri in {
+ defm _t_Jumpnv : NVJri_cond<mnemonic, majOp, 0>; // True Cond
+ defm _f_Jumpnv : NVJri_cond<mnemonic, majOp, 1>; // False cond
+ }
}
-// 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">;
-}
+// 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
-// 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>;
+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 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/template class for the new-value compare jumps instruction
+// with a register and an hardcoded 0/-1 immediate value.
+//===----------------------------------------------------------------------===//
-// 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>;
+let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 11 in
+class NVJ_ConstImm_template<string mnemonic, bits<3> majOp, string ImmVal,
+ bit isNegCond, bit isTaken>
+ : NVInst_V4<(outs),
+ (ins IntRegs:$src1, brtarget:$offset),
+ "if ("#!if(isNegCond, "!","")#mnemonic
+ #"($src1.new, #"#ImmVal#")) jump:"
+ #!if(isTaken, "t","nt")#" $offset",
+ []>, Requires<[HasV4T]> {
+
+ let isPredicatedFalse = isNegCond;
+ let isBrTaken = !if(isTaken, "true", "false");
+
+ bits<3> src1;
+ bits<11> offset;
+ let IClass = 0b0010;
+ let Inst{26} = 0b1;
+ let Inst{25-23} = majOp;
+ let Inst{22} = isNegCond;
+ let Inst{18-16} = src1;
+ let Inst{13} = isTaken;
+ let Inst{21-20} = offset{10-9};
+ let Inst{7-1} = offset{8-2};
+}
+
+multiclass NVJ_ConstImm_cond<string mnemonic, bits<3> majOp, string ImmVal,
+ bit isNegCond> {
+ // Branch not taken:
+ def _nt_V4: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 0>;
+ // Branch taken:
+ def _t_V4: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 1>;
+}
+
+multiclass NVJ_ConstImm_base<string mnemonic, string BaseOp, bits<3> majOp,
+ string ImmVal> {
+ let BaseOpcode = BaseOp#_NVJ_ConstImm in {
+ defm _t_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 0>; // True cond
+ defm _f_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 1>; // False Cond
+ }
}
-// Multiclass for tstbit.
-multiclass NVJ_type_r0<string OpcStr> {
- defm r0Not : NVJ_type_br_pred_tstbit<"!", OpcStr>;
- defm r0 : NVJ_type_br_pred_tstbit<"", OpcStr>;
- }
-
-// Base Multiclass for New Value Jump.
-multiclass NVJ_type {
- defm GT : NVJ_type_rr_ri<"cmp.gt">;
- defm EQ : NVJ_type_rr_ri_no_2ndDotNew<"cmp.eq">;
- defm GTU : NVJ_type_rr_ri_no_nOne<"cmp.gtu">;
- defm TSTBIT : NVJ_type_r0<"tstbit">;
-}
+// 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 isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC] in {
- defm JMP_ : NVJ_type;
+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;
}
//===----------------------------------------------------------------------===//
-// NV/J -
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
// XTYPE/ALU +
//===----------------------------------------------------------------------===//
@@ -2658,414 +1748,367 @@ def LSRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
// MEMOP: Word, Half, Byte
//===----------------------------------------------------------------------===//
+def MEMOPIMM : SDNodeXForm<imm, [{
+ // Call the transformation function XformM5ToU5Imm to get the negative
+ // immediate's positive counterpart.
+ int32_t imm = N->getSExtValue();
+ return XformM5ToU5Imm(imm);
+}]>;
+
+def MEMOPIMM_HALF : SDNodeXForm<imm, [{
+ // -1 .. -31 represented as 65535..65515
+ // assigning to a short restores our desired signed value.
+ // Call the transformation function XformM5ToU5Imm to get the negative
+ // immediate's positive counterpart.
+ int16_t imm = N->getSExtValue();
+ return XformM5ToU5Imm(imm);
+}]>;
+
+def MEMOPIMM_BYTE : SDNodeXForm<imm, [{
+ // -1 .. -31 represented as 255..235
+ // assigning to a char restores our desired signed value.
+ // Call the transformation function XformM5ToU5Imm to get the negative
+ // immediate's positive counterpart.
+ int8_t imm = N->getSExtValue();
+ return XformM5ToU5Imm(imm);
+}]>;
+
+def SETMEMIMM : SDNodeXForm<imm, [{
+ // Return the bit position we will set [0-31].
+ // As an SDNode.
+ int32_t imm = N->getSExtValue();
+ return XformMskToBitPosU5Imm(imm);
+}]>;
+
+def CLRMEMIMM : SDNodeXForm<imm, [{
+ // Return the bit position we will clear [0-31].
+ // As an SDNode.
+ // we bit negate the value first
+ int32_t imm = ~(N->getSExtValue());
+ return XformMskToBitPosU5Imm(imm);
+}]>;
+
+def SETMEMIMM_SHORT : SDNodeXForm<imm, [{
+ // Return the bit position we will set [0-15].
+ // As an SDNode.
+ int16_t imm = N->getSExtValue();
+ return XformMskToBitPosU4Imm(imm);
+}]>;
+
+def CLRMEMIMM_SHORT : SDNodeXForm<imm, [{
+ // Return the bit position we will clear [0-15].
+ // As an SDNode.
+ // we bit negate the value first
+ int16_t imm = ~(N->getSExtValue());
+ return XformMskToBitPosU4Imm(imm);
+}]>;
+
+def SETMEMIMM_BYTE : SDNodeXForm<imm, [{
+ // Return the bit position we will set [0-7].
+ // As an SDNode.
+ int8_t imm = N->getSExtValue();
+ return XformMskToBitPosU3Imm(imm);
+}]>;
+
+def CLRMEMIMM_BYTE : SDNodeXForm<imm, [{
+ // Return the bit position we will clear [0-7].
+ // As an SDNode.
+ // we bit negate the value first
+ int8_t imm = ~(N->getSExtValue());
+ return XformMskToBitPosU3Imm(imm);
+}]>;
+
//===----------------------------------------------------------------------===//
-// MEMOP: Word
-//
-// Implemented:
-// MEMw_ADDi_indexed_V4 : memw(Rs+#u6:2)+=#U5
-// MEMw_SUBi_indexed_V4 : memw(Rs+#u6:2)-=#U5
-// MEMw_ADDr_indexed_V4 : memw(Rs+#u6:2)+=Rt
-// MEMw_SUBr_indexed_V4 : memw(Rs+#u6:2)-=Rt
-// MEMw_CLRr_indexed_V4 : memw(Rs+#u6:2)&=Rt
-// MEMw_SETr_indexed_V4 : memw(Rs+#u6:2)|=Rt
-// MEMw_ADDi_V4 : memw(Rs+#u6:2)+=#U5
-// MEMw_SUBi_V4 : memw(Rs+#u6:2)-=#U5
-// MEMw_ADDr_V4 : memw(Rs+#u6:2)+=Rt
-// MEMw_SUBr_V4 : memw(Rs+#u6:2)-=Rt
-// MEMw_CLRr_V4 : memw(Rs+#u6:2)&=Rt
-// MEMw_SETr_V4 : memw(Rs+#u6:2)|=Rt
-//
-// Not implemented:
-// MEMw_CLRi_indexed_V4 : memw(Rs+#u6:2)=clrbit(#U5)
-// MEMw_SETi_indexed_V4 : memw(Rs+#u6:2)=setbit(#U5)
-// MEMw_CLRi_V4 : memw(Rs+#u6:2)=clrbit(#U5)
-// MEMw_SETi_V4 : memw(Rs+#u6:2)=setbit(#U5)
+// Template class for MemOp instructions with the register value.
//===----------------------------------------------------------------------===//
+class MemOp_rr_base <string opc, bits<2> opcBits, Operand ImmOp,
+ string memOp, bits<2> memOpBits> :
+ MEMInst_V4<(outs),
+ (ins IntRegs:$base, ImmOp:$offset, IntRegs:$delta),
+ opc#"($base+#$offset)"#memOp#"$delta",
+ []>,
+ Requires<[HasV4T, UseMEMOP]> {
+
+ bits<5> base;
+ bits<5> delta;
+ bits<32> offset;
+ bits<6> offsetBits; // memb - u6:0 , memh - u6:1, memw - u6:2
+
+ let offsetBits = !if (!eq(opcBits, 0b00), offset{5-0},
+ !if (!eq(opcBits, 0b01), offset{6-1},
+ !if (!eq(opcBits, 0b10), offset{7-2},0)));
+
+ let IClass = 0b0011;
+ let Inst{27-24} = 0b1110;
+ let Inst{22-21} = opcBits;
+ let Inst{20-16} = base;
+ let Inst{13} = 0b0;
+ let Inst{12-7} = offsetBits;
+ let Inst{6-5} = memOpBits;
+ let Inst{4-0} = delta;
+}
+//===----------------------------------------------------------------------===//
+// Template class for MemOp instructions with the immediate value.
+//===----------------------------------------------------------------------===//
+class MemOp_ri_base <string opc, bits<2> opcBits, Operand ImmOp,
+ string memOp, bits<2> memOpBits> :
+ MEMInst_V4 <(outs),
+ (ins IntRegs:$base, ImmOp:$offset, u5Imm:$delta),
+ opc#"($base+#$offset)"#memOp#"#$delta"
+ #!if(memOpBits{1},")", ""), // clrbit, setbit - include ')'
+ []>,
+ Requires<[HasV4T, UseMEMOP]> {
+ bits<5> base;
+ bits<5> delta;
+ bits<32> offset;
+ bits<6> offsetBits; // memb - u6:0 , memh - u6:1, memw - u6:2
-// memw(Rs+#u6:2) += #U5
-let AddedComplexity = 30 in
-def MEMw_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_2Imm:$offset, u5Imm:$addend),
- "memw($base+#$offset) += #$addend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
+ let offsetBits = !if (!eq(opcBits, 0b00), offset{5-0},
+ !if (!eq(opcBits, 0b01), offset{6-1},
+ !if (!eq(opcBits, 0b10), offset{7-2},0)));
-// memw(Rs+#u6:2) -= #U5
-let AddedComplexity = 30 in
-def MEMw_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_2Imm:$offset, u5Imm:$subend),
- "memw($base+#$offset) -= #$subend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memw(Rs+#u6:2) += Rt
-let AddedComplexity = 30 in
-def MEMw_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$addend),
- "memw($base+#$offset) += $addend",
- [(store (add (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
- (i32 IntRegs:$addend)),
- (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memw(Rs+#u6:2) -= Rt
-let AddedComplexity = 30 in
-def MEMw_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$subend),
- "memw($base+#$offset) -= $subend",
- [(store (sub (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
- (i32 IntRegs:$subend)),
- (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memw(Rs+#u6:2) &= Rt
-let AddedComplexity = 30 in
-def MEMw_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$andend),
- "memw($base+#$offset) &= $andend",
- [(store (and (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
- (i32 IntRegs:$andend)),
- (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memw(Rs+#u6:2) |= Rt
-let AddedComplexity = 30 in
-def MEMw_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$orend),
- "memw($base+#$offset) |= $orend",
- [(store (or (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
- (i32 IntRegs:$orend)),
- (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memw(Rs+#u6:2) += #U5
-let AddedComplexity = 30 in
-def MEMw_ADDi_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, u5Imm:$addend),
- "memw($addr) += $addend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
+ let IClass = 0b0011;
+ let Inst{27-24} = 0b1111;
+ let Inst{22-21} = opcBits;
+ let Inst{20-16} = base;
+ let Inst{13} = 0b0;
+ let Inst{12-7} = offsetBits;
+ let Inst{6-5} = memOpBits;
+ let Inst{4-0} = delta;
+}
-// memw(Rs+#u6:2) -= #U5
-let AddedComplexity = 30 in
-def MEMw_SUBi_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, u5Imm:$subend),
- "memw($addr) -= $subend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memw(Rs+#u6:2) += Rt
-let AddedComplexity = 30 in
-def MEMw_ADDr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$addend),
- "memw($addr) += $addend",
- [(store (add (load ADDRriU6_2:$addr), (i32 IntRegs:$addend)),
- ADDRriU6_2:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memw(Rs+#u6:2) -= Rt
-let AddedComplexity = 30 in
-def MEMw_SUBr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$subend),
- "memw($addr) -= $subend",
- [(store (sub (load ADDRriU6_2:$addr), (i32 IntRegs:$subend)),
- ADDRriU6_2:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memw(Rs+#u6:2) &= Rt
-let AddedComplexity = 30 in
-def MEMw_ANDr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$andend),
- "memw($addr) &= $andend",
- [(store (and (load ADDRriU6_2:$addr), (i32 IntRegs:$andend)),
- ADDRriU6_2:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memw(Rs+#u6:2) |= Rt
-let AddedComplexity = 30 in
-def MEMw_ORr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$orend),
- "memw($addr) |= $orend",
- [(store (or (load ADDRriU6_2:$addr), (i32 IntRegs:$orend)),
- ADDRriU6_2:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
+// multiclass to define MemOp instructions with register operand.
+multiclass MemOp_rr<string opc, bits<2> opcBits, Operand ImmOp> {
+ def _ADD#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " += ", 0b00>; // add
+ def _SUB#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " -= ", 0b01>; // sub
+ def _AND#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " &= ", 0b10>; // and
+ def _OR#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " |= ", 0b11>; // or
+}
+
+// multiclass to define MemOp instructions with immediate Operand.
+multiclass MemOp_ri<string opc, bits<2> opcBits, Operand ImmOp> {
+ def _ADD#NAME#_V4 : MemOp_ri_base <opc, opcBits, ImmOp, " += ", 0b00 >;
+ def _SUB#NAME#_V4 : MemOp_ri_base <opc, opcBits, ImmOp, " -= ", 0b01 >;
+ def _CLRBIT#NAME#_V4 : MemOp_ri_base<opc, opcBits, ImmOp, " =clrbit(", 0b10>;
+ def _SETBIT#NAME#_V4 : MemOp_ri_base<opc, opcBits, ImmOp, " =setbit(", 0b11>;
+}
+
+multiclass MemOp_base <string opc, bits<2> opcBits, Operand ImmOp> {
+ defm r : MemOp_rr <opc, opcBits, ImmOp>;
+ defm i : MemOp_ri <opc, opcBits, ImmOp>;
+}
+
+// Define MemOp instructions.
+let isExtendable = 1, opExtendable = 1, isExtentSigned = 0,
+validSubTargets =HasV4SubT in {
+ let opExtentBits = 6, accessSize = ByteAccess in
+ defm MemOPb : MemOp_base <"memb", 0b00, u6_0Ext>;
+
+ let opExtentBits = 7, accessSize = HalfWordAccess in
+ defm MemOPh : MemOp_base <"memh", 0b01, u6_1Ext>;
+
+ let opExtentBits = 8, accessSize = WordAccess in
+ defm MemOPw : MemOp_base <"memw", 0b10, u6_2Ext>;
+}
//===----------------------------------------------------------------------===//
-// MEMOP: Halfword
-//
-// Implemented:
-// MEMh_ADDi_indexed_V4 : memw(Rs+#u6:2)+=#U5
-// MEMh_SUBi_indexed_V4 : memw(Rs+#u6:2)-=#U5
-// MEMh_ADDr_indexed_V4 : memw(Rs+#u6:2)+=Rt
-// MEMh_SUBr_indexed_V4 : memw(Rs+#u6:2)-=Rt
-// MEMh_CLRr_indexed_V4 : memw(Rs+#u6:2)&=Rt
-// MEMh_SETr_indexed_V4 : memw(Rs+#u6:2)|=Rt
-// MEMh_ADDi_V4 : memw(Rs+#u6:2)+=#U5
-// MEMh_SUBi_V4 : memw(Rs+#u6:2)-=#U5
-// MEMh_ADDr_V4 : memw(Rs+#u6:2)+=Rt
-// MEMh_SUBr_V4 : memw(Rs+#u6:2)-=Rt
-// MEMh_CLRr_V4 : memw(Rs+#u6:2)&=Rt
-// MEMh_SETr_V4 : memw(Rs+#u6:2)|=Rt
-//
-// Not implemented:
-// MEMh_CLRi_indexed_V4 : memw(Rs+#u6:2)=clrbit(#U5)
-// MEMh_SETi_indexed_V4 : memw(Rs+#u6:2)=setbit(#U5)
-// MEMh_CLRi_V4 : memw(Rs+#u6:2)=clrbit(#U5)
-// MEMh_SETi_V4 : memw(Rs+#u6:2)=setbit(#U5)
+// Multiclass to define 'Def Pats' for ALU operations on the memory
+// Here value used for the ALU operation is an immediate value.
+// mem[bh](Rs+#0) += #U5
+// mem[bh](Rs+#u6) += #U5
//===----------------------------------------------------------------------===//
+multiclass MemOpi_u5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf ExtPred,
+ InstHexagon MI, SDNode OpNode> {
+ let AddedComplexity = 180 in
+ def : Pat < (stOp (OpNode (ldOp IntRegs:$addr), u5ImmPred:$addend),
+ IntRegs:$addr),
+ (MI IntRegs:$addr, #0, u5ImmPred:$addend )>;
-// memh(Rs+#u6:1) += #U5
-let AddedComplexity = 30 in
-def MEMh_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_1Imm:$offset, u5Imm:$addend),
- "memh($base+#$offset) += $addend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
+ let AddedComplexity = 190 in
+ def : Pat <(stOp (OpNode (ldOp (add IntRegs:$base, ExtPred:$offset)),
+ u5ImmPred:$addend),
+ (add IntRegs:$base, ExtPred:$offset)),
+ (MI IntRegs:$base, ExtPred:$offset, u5ImmPred:$addend)>;
+}
-// memh(Rs+#u6:1) -= #U5
-let AddedComplexity = 30 in
-def MEMh_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_1Imm:$offset, u5Imm:$subend),
- "memh($base+#$offset) -= $subend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memh(Rs+#u6:1) += Rt
-let AddedComplexity = 30 in
-def MEMh_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$addend),
- "memh($base+#$offset) += $addend",
- [(truncstorei16 (add (sextloadi16 (add (i32 IntRegs:$base),
- u6_1ImmPred:$offset)),
- (i32 IntRegs:$addend)),
- (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memh(Rs+#u6:1) -= Rt
-let AddedComplexity = 30 in
-def MEMh_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$subend),
- "memh($base+#$offset) -= $subend",
- [(truncstorei16 (sub (sextloadi16 (add (i32 IntRegs:$base),
- u6_1ImmPred:$offset)),
- (i32 IntRegs:$subend)),
- (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memh(Rs+#u6:1) &= Rt
-let AddedComplexity = 30 in
-def MEMh_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$andend),
- "memh($base+#$offset) += $andend",
- [(truncstorei16 (and (sextloadi16 (add (i32 IntRegs:$base),
- u6_1ImmPred:$offset)),
- (i32 IntRegs:$andend)),
- (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memh(Rs+#u6:1) |= Rt
-let AddedComplexity = 30 in
-def MEMh_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$orend),
- "memh($base+#$offset) |= $orend",
- [(truncstorei16 (or (sextloadi16 (add (i32 IntRegs:$base),
- u6_1ImmPred:$offset)),
- (i32 IntRegs:$orend)),
- (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memh(Rs+#u6:1) += #U5
-let AddedComplexity = 30 in
-def MEMh_ADDi_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, u5Imm:$addend),
- "memh($addr) += $addend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
+multiclass MemOpi_u5ALUOp<PatFrag ldOp, PatFrag stOp, PatLeaf ExtPred,
+ InstHexagon addMI, InstHexagon subMI> {
+ defm : MemOpi_u5Pats<ldOp, stOp, ExtPred, addMI, add>;
+ defm : MemOpi_u5Pats<ldOp, stOp, ExtPred, subMI, sub>;
+}
-// memh(Rs+#u6:1) -= #U5
-let AddedComplexity = 30 in
-def MEMh_SUBi_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, u5Imm:$subend),
- "memh($addr) -= $subend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memh(Rs+#u6:1) += Rt
-let AddedComplexity = 30 in
-def MEMh_ADDr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$addend),
- "memh($addr) += $addend",
- [(truncstorei16 (add (sextloadi16 ADDRriU6_1:$addr),
- (i32 IntRegs:$addend)), ADDRriU6_1:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memh(Rs+#u6:1) -= Rt
-let AddedComplexity = 30 in
-def MEMh_SUBr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$subend),
- "memh($addr) -= $subend",
- [(truncstorei16 (sub (sextloadi16 ADDRriU6_1:$addr),
- (i32 IntRegs:$subend)), ADDRriU6_1:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memh(Rs+#u6:1) &= Rt
-let AddedComplexity = 30 in
-def MEMh_ANDr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$andend),
- "memh($addr) &= $andend",
- [(truncstorei16 (and (sextloadi16 ADDRriU6_1:$addr),
- (i32 IntRegs:$andend)), ADDRriU6_1:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memh(Rs+#u6:1) |= Rt
-let AddedComplexity = 30 in
-def MEMh_ORr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$orend),
- "memh($addr) |= $orend",
- [(truncstorei16 (or (sextloadi16 ADDRriU6_1:$addr),
- (i32 IntRegs:$orend)), ADDRriU6_1:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
+multiclass MemOpi_u5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
+ // Half Word
+ defm : MemOpi_u5ALUOp <ldOpHalf, truncstorei16, u6_1ExtPred,
+ MemOPh_ADDi_V4, MemOPh_SUBi_V4>;
+ // Byte
+ defm : MemOpi_u5ALUOp <ldOpByte, truncstorei8, u6ExtPred,
+ MemOPb_ADDi_V4, MemOPb_SUBi_V4>;
+}
+
+let Predicates = [HasV4T, UseMEMOP] in {
+ defm : MemOpi_u5ExtType<zextloadi8, zextloadi16>; // zero extend
+ defm : MemOpi_u5ExtType<sextloadi8, sextloadi16>; // sign extend
+ defm : MemOpi_u5ExtType<extloadi8, extloadi16>; // any extend
+ // Word
+ defm : MemOpi_u5ALUOp <load, store, u6_2ExtPred, MemOPw_ADDi_V4,
+ MemOPw_SUBi_V4>;
+}
//===----------------------------------------------------------------------===//
-// MEMOP: Byte
-//
-// Implemented:
-// MEMb_ADDi_indexed_V4 : memb(Rs+#u6:0)+=#U5
-// MEMb_SUBi_indexed_V4 : memb(Rs+#u6:0)-=#U5
-// MEMb_ADDr_indexed_V4 : memb(Rs+#u6:0)+=Rt
-// MEMb_SUBr_indexed_V4 : memb(Rs+#u6:0)-=Rt
-// MEMb_CLRr_indexed_V4 : memb(Rs+#u6:0)&=Rt
-// MEMb_SETr_indexed_V4 : memb(Rs+#u6:0)|=Rt
-// MEMb_ADDi_V4 : memb(Rs+#u6:0)+=#U5
-// MEMb_SUBi_V4 : memb(Rs+#u6:0)-=#U5
-// MEMb_ADDr_V4 : memb(Rs+#u6:0)+=Rt
-// MEMb_SUBr_V4 : memb(Rs+#u6:0)-=Rt
-// MEMb_CLRr_V4 : memb(Rs+#u6:0)&=Rt
-// MEMb_SETr_V4 : memb(Rs+#u6:0)|=Rt
-//
-// Not implemented:
-// MEMb_CLRi_indexed_V4 : memb(Rs+#u6:0)=clrbit(#U5)
-// MEMb_SETi_indexed_V4 : memb(Rs+#u6:0)=setbit(#U5)
-// MEMb_CLRi_V4 : memb(Rs+#u6:0)=clrbit(#U5)
-// MEMb_SETi_V4 : memb(Rs+#u6:0)=setbit(#U5)
+// multiclass to define 'Def Pats' for ALU operations on the memory.
+// Here value used for the ALU operation is a negative value.
+// mem[bh](Rs+#0) += #m5
+// mem[bh](Rs+#u6) += #m5
//===----------------------------------------------------------------------===//
-// memb(Rs+#u6:0) += #U5
-let AddedComplexity = 30 in
-def MEMb_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_0Imm:$offset, u5Imm:$addend),
- "memb($base+#$offset) += $addend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
+multiclass MemOpi_m5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf extPred,
+ PatLeaf immPred, ComplexPattern addrPred,
+ SDNodeXForm xformFunc, InstHexagon MI> {
+ let AddedComplexity = 190 in
+ def : Pat <(stOp (add (ldOp IntRegs:$addr), immPred:$subend),
+ IntRegs:$addr),
+ (MI IntRegs:$addr, #0, (xformFunc immPred:$subend) )>;
-// memb(Rs+#u6:0) -= #U5
-let AddedComplexity = 30 in
-def MEMb_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_0Imm:$offset, u5Imm:$subend),
- "memb($base+#$offset) -= $subend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memb(Rs+#u6:0) += Rt
-let AddedComplexity = 30 in
-def MEMb_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$addend),
- "memb($base+#$offset) += $addend",
- [(truncstorei8 (add (sextloadi8 (add (i32 IntRegs:$base),
- u6_0ImmPred:$offset)),
- (i32 IntRegs:$addend)),
- (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memb(Rs+#u6:0) -= Rt
-let AddedComplexity = 30 in
-def MEMb_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$subend),
- "memb($base+#$offset) -= $subend",
- [(truncstorei8 (sub (sextloadi8 (add (i32 IntRegs:$base),
- u6_0ImmPred:$offset)),
- (i32 IntRegs:$subend)),
- (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memb(Rs+#u6:0) &= Rt
-let AddedComplexity = 30 in
-def MEMb_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$andend),
- "memb($base+#$offset) += $andend",
- [(truncstorei8 (and (sextloadi8 (add (i32 IntRegs:$base),
- u6_0ImmPred:$offset)),
- (i32 IntRegs:$andend)),
- (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memb(Rs+#u6:0) |= Rt
-let AddedComplexity = 30 in
-def MEMb_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$orend),
- "memb($base+#$offset) |= $orend",
- [(truncstorei8 (or (sextloadi8 (add (i32 IntRegs:$base),
- u6_0ImmPred:$offset)),
- (i32 IntRegs:$orend)),
- (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memb(Rs+#u6:0) += #U5
-let AddedComplexity = 30 in
-def MEMb_ADDi_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, u5Imm:$addend),
- "memb($addr) += $addend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
+ let AddedComplexity = 195 in
+ def : Pat<(stOp (add (ldOp (add IntRegs:$base, extPred:$offset)),
+ immPred:$subend),
+ (add IntRegs:$base, extPred:$offset)),
+ (MI IntRegs:$base, extPred:$offset, (xformFunc immPred:$subend))>;
+}
-// memb(Rs+#u6:0) -= #U5
-let AddedComplexity = 30 in
-def MEMb_SUBi_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, u5Imm:$subend),
- "memb($addr) -= $subend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memb(Rs+#u6:0) += Rt
-let AddedComplexity = 30 in
-def MEMb_ADDr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$addend),
- "memb($addr) += $addend",
- [(truncstorei8 (add (sextloadi8 ADDRriU6_0:$addr),
- (i32 IntRegs:$addend)), ADDRriU6_0:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memb(Rs+#u6:0) -= Rt
-let AddedComplexity = 30 in
-def MEMb_SUBr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$subend),
- "memb($addr) -= $subend",
- [(truncstorei8 (sub (sextloadi8 ADDRriU6_0:$addr),
- (i32 IntRegs:$subend)), ADDRriU6_0:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memb(Rs+#u6:0) &= Rt
-let AddedComplexity = 30 in
-def MEMb_ANDr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$andend),
- "memb($addr) &= $andend",
- [(truncstorei8 (and (sextloadi8 ADDRriU6_0:$addr),
- (i32 IntRegs:$andend)), ADDRriU6_0:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memb(Rs+#u6:0) |= Rt
-let AddedComplexity = 30 in
-def MEMb_ORr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$orend),
- "memb($addr) |= $orend",
- [(truncstorei8 (or (sextloadi8 ADDRriU6_0:$addr),
- (i32 IntRegs:$orend)), ADDRriU6_0:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
+multiclass MemOpi_m5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
+ // Half Word
+ defm : MemOpi_m5Pats <ldOpHalf, truncstorei16, u6_1ExtPred, m5HImmPred,
+ ADDRriU6_1, MEMOPIMM_HALF, MemOPh_SUBi_V4>;
+ // Byte
+ defm : MemOpi_m5Pats <ldOpByte, truncstorei8, u6ExtPred, m5BImmPred,
+ ADDRriU6_0, MEMOPIMM_BYTE, MemOPb_SUBi_V4>;
+}
+
+let Predicates = [HasV4T, UseMEMOP] in {
+ defm : MemOpi_m5ExtType<zextloadi8, zextloadi16>; // zero extend
+ defm : MemOpi_m5ExtType<sextloadi8, sextloadi16>; // sign extend
+ defm : MemOpi_m5ExtType<extloadi8, extloadi16>; // any extend
+
+ // Word
+ defm : MemOpi_m5Pats <load, store, u6_2ExtPred, m5ImmPred,
+ ADDRriU6_2, MEMOPIMM, MemOPw_SUBi_V4>;
+}
+
+//===----------------------------------------------------------------------===//
+// Multiclass to define 'def Pats' for bit operations on the memory.
+// mem[bhw](Rs+#0) = [clrbit|setbit](#U5)
+// mem[bhw](Rs+#u6) = [clrbit|setbit](#U5)
+//===----------------------------------------------------------------------===//
+
+multiclass MemOpi_bitPats <PatFrag ldOp, PatFrag stOp, PatLeaf immPred,
+ PatLeaf extPred, ComplexPattern addrPred,
+ SDNodeXForm xformFunc, InstHexagon MI, SDNode OpNode> {
+
+ // mem[bhw](Rs+#u6:[012]) = [clrbit|setbit](#U5)
+ let AddedComplexity = 250 in
+ def : Pat<(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)),
+ immPred:$bitend),
+ (add IntRegs:$base, extPred:$offset)),
+ (MI IntRegs:$base, extPred:$offset, (xformFunc immPred:$bitend))>;
+
+ // mem[bhw](Rs+#0) = [clrbit|setbit](#U5)
+ let AddedComplexity = 225 in
+ def : Pat <(stOp (OpNode (ldOp addrPred:$addr), immPred:$bitend),
+ addrPred:$addr),
+ (MI IntRegs:$addr, #0, (xformFunc immPred:$bitend))>;
+}
+
+multiclass MemOpi_bitExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
+ // Byte - clrbit
+ defm : MemOpi_bitPats<ldOpByte, truncstorei8, Clr3ImmPred, u6ExtPred,
+ ADDRriU6_0, CLRMEMIMM_BYTE, MemOPb_CLRBITi_V4, and>;
+ // Byte - setbit
+ defm : MemOpi_bitPats<ldOpByte, truncstorei8, Set3ImmPred, u6ExtPred,
+ ADDRriU6_0, SETMEMIMM_BYTE, MemOPb_SETBITi_V4, or>;
+ // Half Word - clrbit
+ defm : MemOpi_bitPats<ldOpHalf, truncstorei16, Clr4ImmPred, u6_1ExtPred,
+ ADDRriU6_1, CLRMEMIMM_SHORT, MemOPh_CLRBITi_V4, and>;
+ // Half Word - setbit
+ defm : MemOpi_bitPats<ldOpHalf, truncstorei16, Set4ImmPred, u6_1ExtPred,
+ ADDRriU6_1, SETMEMIMM_SHORT, MemOPh_SETBITi_V4, or>;
+}
+
+let Predicates = [HasV4T, UseMEMOP] in {
+ // mem[bh](Rs+#0) = [clrbit|setbit](#U5)
+ // mem[bh](Rs+#u6:[01]) = [clrbit|setbit](#U5)
+ defm : MemOpi_bitExtType<zextloadi8, zextloadi16>; // zero extend
+ defm : MemOpi_bitExtType<sextloadi8, sextloadi16>; // sign extend
+ defm : MemOpi_bitExtType<extloadi8, extloadi16>; // any extend
+
+ // memw(Rs+#0) = [clrbit|setbit](#U5)
+ // memw(Rs+#u6:2) = [clrbit|setbit](#U5)
+ defm : MemOpi_bitPats<load, store, Clr5ImmPred, u6_2ExtPred, ADDRriU6_2,
+ CLRMEMIMM, MemOPw_CLRBITi_V4, and>;
+ defm : MemOpi_bitPats<load, store, Set5ImmPred, u6_2ExtPred, ADDRriU6_2,
+ SETMEMIMM, MemOPw_SETBITi_V4, or>;
+}
+//===----------------------------------------------------------------------===//
+// Multiclass to define 'def Pats' for ALU operations on the memory
+// where addend is a register.
+// mem[bhw](Rs+#0) [+-&|]= Rt
+// mem[bhw](Rs+#U6:[012]) [+-&|]= Rt
+//===----------------------------------------------------------------------===//
+
+multiclass MemOpr_Pats <PatFrag ldOp, PatFrag stOp, ComplexPattern addrPred,
+ PatLeaf extPred, InstHexagon MI, SDNode OpNode> {
+ let AddedComplexity = 141 in
+ // mem[bhw](Rs+#0) [+-&|]= Rt
+ def : Pat <(stOp (OpNode (ldOp addrPred:$addr), (i32 IntRegs:$addend)),
+ addrPred:$addr),
+ (MI IntRegs:$addr, #0, (i32 IntRegs:$addend) )>;
+
+ // mem[bhw](Rs+#U6:[012]) [+-&|]= Rt
+ let AddedComplexity = 150 in
+ def : Pat <(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)),
+ (i32 IntRegs:$orend)),
+ (add IntRegs:$base, extPred:$offset)),
+ (MI IntRegs:$base, extPred:$offset, (i32 IntRegs:$orend) )>;
+}
+
+multiclass MemOPr_ALUOp<PatFrag ldOp, PatFrag stOp,
+ ComplexPattern addrPred, PatLeaf extPred,
+ InstHexagon addMI, InstHexagon subMI,
+ InstHexagon andMI, InstHexagon orMI > {
+
+ defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, addMI, add>;
+ defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, subMI, sub>;
+ defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, andMI, and>;
+ defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, orMI, or>;
+}
+
+multiclass MemOPr_ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
+ // Half Word
+ defm : MemOPr_ALUOp <ldOpHalf, truncstorei16, ADDRriU6_1, u6_1ExtPred,
+ MemOPh_ADDr_V4, MemOPh_SUBr_V4,
+ MemOPh_ANDr_V4, MemOPh_ORr_V4>;
+ // Byte
+ defm : MemOPr_ALUOp <ldOpByte, truncstorei8, ADDRriU6_0, u6ExtPred,
+ MemOPb_ADDr_V4, MemOPb_SUBr_V4,
+ MemOPb_ANDr_V4, MemOPb_ORr_V4>;
+}
+
+// Define 'def Pats' for MemOps with register addend.
+let Predicates = [HasV4T, UseMEMOP] in {
+ // Byte, Half Word
+ defm : MemOPr_ExtType<zextloadi8, zextloadi16>; // zero extend
+ defm : MemOPr_ExtType<sextloadi8, sextloadi16>; // sign extend
+ defm : MemOPr_ExtType<extloadi8, extloadi16>; // any extend
+ // Word
+ defm : MemOPr_ALUOp <load, store, ADDRriU6_2, u6_2ExtPred, MemOPw_ADDr_V4,
+ MemOPw_SUBr_V4, MemOPw_ANDr_V4, MemOPw_ORr_V4 >;
+}
//===----------------------------------------------------------------------===//
// XTYPE/PRED +
@@ -3146,7 +2189,7 @@ def CMPbEQri_V4 : MInst<(outs PredRegs:$dst),
def : Pat <(brcond (i1 (setne (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2)),
bb:$offset),
- (JMP_cNot (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2),
+ (JMP_f (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2),
bb:$offset)>,
Requires<[HasV4T]>;
@@ -3521,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]>;
@@ -3531,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]>;
}
@@ -3541,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]>;
}
@@ -3560,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]>;
@@ -3571,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]>;
@@ -3582,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]>;
@@ -3593,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]>;
@@ -3604,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]>;
@@ -3629,9 +2676,9 @@ let isReturn = 1, isTerminator = 1,
multiclass ST_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME#_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdressExt:$absaddr, RC: $src2),
+ (ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
") ")#mnemonic#"(##$absaddr) = $src2",
[]>,
@@ -3639,7 +2686,7 @@ multiclass ST_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
}
multiclass ST_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 0>;
// Predicate new
defm _cdn#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 1>;
@@ -3651,7 +2698,7 @@ multiclass ST_Abs<string mnemonic, string CextOp, RegisterClass RC> {
let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
let opExtendable = 0, isPredicable = 1 in
def NAME#_V4 : STInst2<(outs),
- (ins globaladdressExt:$absaddr, RC:$src),
+ (ins u0AlwaysExt:$absaddr, RC:$src),
mnemonic#"(##$absaddr) = $src",
[]>,
Requires<[HasV4T]>;
@@ -3665,9 +2712,9 @@ multiclass ST_Abs<string mnemonic, string CextOp, RegisterClass RC> {
multiclass ST_Abs_Predbase_nv<string mnemonic, RegisterClass RC, bit isNot,
bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME#_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdressExt:$absaddr, RC: $src2),
+ (ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
") ")#mnemonic#"(##$absaddr) = $src2.new",
[]>,
@@ -3675,7 +2722,7 @@ multiclass ST_Abs_Predbase_nv<string mnemonic, RegisterClass RC, bit isNot,
}
multiclass ST_Abs_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 0>;
// Predicate new
defm _cdn#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 1>;
@@ -3687,7 +2734,7 @@ multiclass ST_Abs_nv<string mnemonic, string CextOp, RegisterClass RC> {
let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
let opExtendable = 0, isPredicable = 1 in
def NAME#_nv_V4 : NVInst_V4<(outs),
- (ins globaladdressExt:$absaddr, RC:$src),
+ (ins u0AlwaysExt:$absaddr, RC:$src),
mnemonic#"(##$absaddr) = $src.new",
[]>,
Requires<[HasV4T]>;
@@ -3700,16 +2747,19 @@ multiclass ST_Abs_nv<string mnemonic, string CextOp, RegisterClass RC> {
}
let addrMode = Absolute in {
+ let accessSize = ByteAccess in
defm STrib_abs : ST_Abs<"memb", "STrib", IntRegs>,
ST_Abs_nv<"memb", "STrib", IntRegs>, AddrModeRel;
+ let accessSize = HalfWordAccess in
defm STrih_abs : ST_Abs<"memh", "STrih", IntRegs>,
ST_Abs_nv<"memh", "STrih", IntRegs>, AddrModeRel;
+ let accessSize = WordAccess in
defm STriw_abs : ST_Abs<"memw", "STriw", IntRegs>,
ST_Abs_nv<"memw", "STriw", IntRegs>, AddrModeRel;
- let isNVStorable = 0 in
+ let accessSize = DoubleWordAccess, isNVStorable = 0 in
defm STrid_abs : ST_Abs<"memd", "STrid", DoubleRegs>, AddrModeRel;
}
@@ -3730,11 +2780,115 @@ def : Pat<(store (i64 DoubleRegs:$src1),
(STrid_abs_V4 tglobaladdr: $absaddr, DoubleRegs: $src1)>;
}
+//===----------------------------------------------------------------------===//
+// multiclass for store instructions with GP-relative addressing mode.
+// mem[bhwd](#global)=Rt
+// if ([!]Pv[.new]) mem[bhwd](##global) = Rt
+//===----------------------------------------------------------------------===//
+let mayStore = 1, isNVStorable = 1 in
+multiclass ST_GP<string mnemonic, string BaseOp, RegisterClass RC> {
+ let BaseOpcode = BaseOp, isPredicable = 1 in
+ def NAME#_V4 : STInst2<(outs),
+ (ins globaladdress:$global, RC:$src),
+ mnemonic#"(#$global) = $src",
+ []>;
+
+ // When GP-relative instructions are predicated, their addressing mode is
+ // changed to absolute and they are always constant extended.
+ let BaseOpcode = BaseOp, isExtended = 1, opExtendable = 1,
+ isPredicated = 1 in {
+ defm Pt : ST_Abs_Pred <mnemonic, RC, 0>;
+ defm NotPt : ST_Abs_Pred <mnemonic, RC, 1>;
+ }
+}
+
+let mayStore = 1, isNVStore = 1 in
+multiclass ST_GP_nv<string mnemonic, string BaseOp, RegisterClass RC> {
+ let BaseOpcode = BaseOp, isPredicable = 1 in
+ def NAME#_nv_V4 : NVInst_V4<(outs),
+ (ins u0AlwaysExt:$global, RC:$src),
+ mnemonic#"(#$global) = $src.new",
+ []>,
+ Requires<[HasV4T]>;
+
+ // When GP-relative instructions are predicated, their addressing mode is
+ // changed to absolute and they are always constant extended.
+ let BaseOpcode = BaseOp, isExtended = 1, opExtendable = 1,
+ isPredicated = 1 in {
+ defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>;
+ defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>;
+ }
+}
+
+let validSubTargets = HasV4SubT, neverHasSideEffects = 1 in {
+ let isNVStorable = 0 in
+ defm STd_GP : ST_GP <"memd", "STd_GP", DoubleRegs>, PredNewRel;
+
+ defm STb_GP : ST_GP<"memb", "STb_GP", IntRegs>,
+ ST_GP_nv<"memb", "STb_GP", IntRegs>, NewValueRel;
+ defm STh_GP : ST_GP<"memh", "STh_GP", IntRegs>,
+ ST_GP_nv<"memh", "STh_GP", IntRegs>, NewValueRel;
+ defm STw_GP : ST_GP<"memw", "STw_GP", IntRegs>,
+ ST_GP_nv<"memw", "STw_GP", IntRegs>, NewValueRel;
+}
+
+// 64 bit atomic store
+def : Pat <(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global),
+ (i64 DoubleRegs:$src1)),
+ (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
+ Requires<[HasV4T]>;
+
+// Map from store(globaladdress) -> memd(#foo)
+let AddedComplexity = 100 in
+def : Pat <(store (i64 DoubleRegs:$src1),
+ (HexagonCONST32_GP tglobaladdr:$global)),
+ (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>;
+
+// 8 bit atomic store
+def : Pat < (atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global),
+ (i32 IntRegs:$src1)),
+ (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
+
+// Map from store(globaladdress) -> memb(#foo)
+let AddedComplexity = 100 in
+def : Pat<(truncstorei8 (i32 IntRegs:$src1),
+ (HexagonCONST32_GP tglobaladdr:$global)),
+ (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
+
+// Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1"
+// to "r0 = 1; memw(#foo) = r0"
+let AddedComplexity = 100 in
+def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
+ (STb_GP_V4 tglobaladdr:$global, (TFRI 1))>;
+
+def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
+ (i32 IntRegs:$src1)),
+ (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
+
+// Map from store(globaladdress) -> memh(#foo)
+let AddedComplexity = 100 in
+def : Pat<(truncstorei16 (i32 IntRegs:$src1),
+ (HexagonCONST32_GP tglobaladdr:$global)),
+ (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
+
+// 32 bit atomic store
+def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global),
+ (i32 IntRegs:$src1)),
+ (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
+
+// Map from store(globaladdress) -> memw(#foo)
+let AddedComplexity = 100 in
+def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
+ (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
+
+//===----------------------------------------------------------------------===//
+// Multiclass for the load instructions with absolute addressing mode.
+//===----------------------------------------------------------------------===//
multiclass LD_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : LDInst2<(outs RC:$dst),
- (ins PredRegs:$src1, globaladdressExt:$absaddr),
+ (ins PredRegs:$src1, u0AlwaysExt:$absaddr),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
") ")#"$dst = "#mnemonic#"(##$absaddr)",
[]>,
@@ -3742,7 +2896,7 @@ multiclass LD_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
}
multiclass LD_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 0>;
// Predicate new
defm _cdn#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 1>;
@@ -3754,7 +2908,7 @@ multiclass LD_Abs<string mnemonic, string CextOp, RegisterClass RC> {
let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
let opExtendable = 1, isPredicable = 1 in
def NAME#_V4 : LDInst2<(outs RC:$dst),
- (ins globaladdressExt:$absaddr),
+ (ins u0AlwaysExt:$absaddr),
"$dst = "#mnemonic#"(##$absaddr)",
[]>,
Requires<[HasV4T]>;
@@ -3767,38 +2921,144 @@ multiclass LD_Abs<string mnemonic, string CextOp, RegisterClass RC> {
}
let addrMode = Absolute in {
+ let accessSize = ByteAccess in {
defm LDrib_abs : LD_Abs<"memb", "LDrib", IntRegs>, AddrModeRel;
defm LDriub_abs : LD_Abs<"memub", "LDriub", IntRegs>, AddrModeRel;
+ }
+ let accessSize = HalfWordAccess in {
defm LDrih_abs : LD_Abs<"memh", "LDrih", IntRegs>, AddrModeRel;
defm LDriuh_abs : LD_Abs<"memuh", "LDriuh", IntRegs>, AddrModeRel;
+ }
+ let accessSize = WordAccess in
defm LDriw_abs : LD_Abs<"memw", "LDriw", IntRegs>, AddrModeRel;
+
+ let accessSize = DoubleWordAccess in
defm LDrid_abs : LD_Abs<"memd", "LDrid", DoubleRegs>, AddrModeRel;
}
-let Predicates = [HasV4T], AddedComplexity = 30 in
+let Predicates = [HasV4T], AddedComplexity = 30 in {
def : Pat<(i32 (load (HexagonCONST32 tglobaladdr:$absaddr))),
(LDriw_abs_V4 tglobaladdr: $absaddr)>;
-let Predicates = [HasV4T], AddedComplexity=30 in
def : Pat<(i32 (sextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
(LDrib_abs_V4 tglobaladdr:$absaddr)>;
-let Predicates = [HasV4T], AddedComplexity=30 in
def : Pat<(i32 (zextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
(LDriub_abs_V4 tglobaladdr:$absaddr)>;
-let Predicates = [HasV4T], AddedComplexity=30 in
def : Pat<(i32 (sextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
(LDrih_abs_V4 tglobaladdr:$absaddr)>;
-let Predicates = [HasV4T], AddedComplexity=30 in
def : Pat<(i32 (zextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
(LDriuh_abs_V4 tglobaladdr:$absaddr)>;
+}
+
+//===----------------------------------------------------------------------===//
+// multiclass for load instructions with GP-relative addressing mode.
+// Rx=mem[bhwd](##global)
+// if ([!]Pv[.new]) Rx=mem[bhwd](##global)
+//===----------------------------------------------------------------------===//
+let neverHasSideEffects = 1, validSubTargets = HasV4SubT in
+multiclass LD_GP<string mnemonic, string BaseOp, RegisterClass RC> {
+ let BaseOpcode = BaseOp in {
+ let isPredicable = 1 in
+ def NAME#_V4 : LDInst2<(outs RC:$dst),
+ (ins globaladdress:$global),
+ "$dst = "#mnemonic#"(#$global)",
+ []>;
+
+ let isExtended = 1, opExtendable = 2, isPredicated = 1 in {
+ defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>;
+ defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>;
+ }
+ }
+}
+
+defm LDd_GP : LD_GP<"memd", "LDd_GP", DoubleRegs>, PredNewRel;
+defm LDb_GP : LD_GP<"memb", "LDb_GP", IntRegs>, PredNewRel;
+defm LDub_GP : LD_GP<"memub", "LDub_GP", IntRegs>, PredNewRel;
+defm LDh_GP : LD_GP<"memh", "LDh_GP", IntRegs>, PredNewRel;
+defm LDuh_GP : LD_GP<"memuh", "LDuh_GP", IntRegs>, PredNewRel;
+defm LDw_GP : LD_GP<"memw", "LDw_GP", IntRegs>, PredNewRel;
+
+def : Pat <(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)),
+ (i64 (LDd_GP_V4 tglobaladdr:$global))>;
+
+def : Pat <(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)),
+ (i32 (LDw_GP_V4 tglobaladdr:$global))>;
+
+def : Pat <(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)),
+ (i32 (LDuh_GP_V4 tglobaladdr:$global))>;
+
+def : Pat <(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)),
+ (i32 (LDub_GP_V4 tglobaladdr:$global))>;
+
+// Map from load(globaladdress) -> memw(#foo + 0)
+let AddedComplexity = 100 in
+def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))),
+ (i64 (LDd_GP_V4 tglobaladdr:$global))>;
+
+// Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd
+let AddedComplexity = 100 in
+def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))),
+ (i1 (TFR_PdRs (i32 (LDb_GP_V4 tglobaladdr:$global))))>;
+
+// When the Interprocedural Global Variable optimizer realizes that a certain
+// global variable takes only two constant values, it shrinks the global to
+// a boolean. Catch those loads here in the following 3 patterns.
+let AddedComplexity = 100 in
+def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDb_GP_V4 tglobaladdr:$global))>;
+
+let AddedComplexity = 100 in
+def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDb_GP_V4 tglobaladdr:$global))>;
+
+// Map from load(globaladdress) -> memb(#foo)
+let AddedComplexity = 100 in
+def : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDb_GP_V4 tglobaladdr:$global))>;
+
+// Map from load(globaladdress) -> memb(#foo)
+let AddedComplexity = 100 in
+def : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDb_GP_V4 tglobaladdr:$global))>;
+
+let AddedComplexity = 100 in
+def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDub_GP_V4 tglobaladdr:$global))>;
+
+// Map from load(globaladdress) -> memub(#foo)
+let AddedComplexity = 100 in
+def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDub_GP_V4 tglobaladdr:$global))>;
+
+// Map from load(globaladdress) -> memh(#foo)
+let AddedComplexity = 100 in
+def : Pat <(i32 (extloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDh_GP_V4 tglobaladdr:$global))>;
+
+// Map from load(globaladdress) -> memh(#foo)
+let AddedComplexity = 100 in
+def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDh_GP_V4 tglobaladdr:$global))>;
+
+// Map from load(globaladdress) -> memuh(#foo)
+let AddedComplexity = 100 in
+def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDuh_GP_V4 tglobaladdr:$global))>;
+
+// Map from load(globaladdress) -> memw(#foo)
+let AddedComplexity = 100 in
+def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDw_GP_V4 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]>;
@@ -3807,54 +3067,61 @@ 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
// as an operand
-let AddedComplexity = 10 in
+let isExtended = 1, opExtendable = 3, AddedComplexity = 40,
+validSubTargets = HasV4SubT in
def LDrid_ind_lo_V4 : LDInst<(outs DoubleRegs:$dst),
- (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$offset),
+ (ins IntRegs:$src1, u2Imm:$src2, globaladdressExt:$offset),
"$dst=memd($src1<<#$src2+##$offset)",
[(set (i64 DoubleRegs:$dst),
(load (add (shl IntRegs:$src1, u2ImmPred:$src2),
(HexagonCONST32 tglobaladdr:$offset))))]>,
Requires<[HasV4T]>;
-let AddedComplexity = 10 in
+let AddedComplexity = 40 in
multiclass LD_indirect_lo<string OpcStr, PatFrag OpNode> {
+let isExtended = 1, opExtendable = 3, validSubTargets = HasV4SubT in
def _lo_V4 : LDInst<(outs IntRegs:$dst),
- (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$offset),
+ (ins IntRegs:$src1, u2Imm:$src2, globaladdressExt:$offset),
!strconcat("$dst = ",
!strconcat(OpcStr, "($src1<<#$src2+##$offset)")),
[(set IntRegs:$dst,
@@ -3865,202 +3132,53 @@ multiclass LD_indirect_lo<string OpcStr, PatFrag OpNode> {
defm LDrib_ind : LD_indirect_lo<"memb", sextloadi8>;
defm LDriub_ind : LD_indirect_lo<"memub", zextloadi8>;
+defm LDriub_ind_anyext : LD_indirect_lo<"memub", extloadi8>;
defm LDrih_ind : LD_indirect_lo<"memh", sextloadi16>;
defm LDriuh_ind : LD_indirect_lo<"memuh", zextloadi16>;
+defm LDriuh_ind_anyext : LD_indirect_lo<"memuh", extloadi16>;
defm LDriw_ind : LD_indirect_lo<"memw", load>;
-// Store - Indirect with long offset: These instructions take global address
-// as an operand
-let AddedComplexity = 10 in
-def STrid_ind_lo_V4 : STInst<(outs),
- (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$src3,
- DoubleRegs:$src4),
- "memd($src1<<#$src2+#$src3) = $src4",
- [(store (i64 DoubleRegs:$src4),
- (add (shl IntRegs:$src1, u2ImmPred:$src2),
- (HexagonCONST32 tglobaladdr:$src3)))]>,
- Requires<[HasV4T]>;
-
-let AddedComplexity = 10 in
-multiclass ST_indirect_lo<string OpcStr, PatFrag OpNode> {
- def _lo_V4 : STInst<(outs),
- (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$src3,
- IntRegs:$src4),
- !strconcat(OpcStr, "($src1<<#$src2+##$src3) = $src4"),
- [(OpNode (i32 IntRegs:$src4),
- (add (shl IntRegs:$src1, u2ImmPred:$src2),
- (HexagonCONST32 tglobaladdr:$src3)))]>,
- Requires<[HasV4T]>;
-}
-
-defm STrib_ind : ST_indirect_lo<"memb", truncstorei8>;
-defm STrih_ind : ST_indirect_lo<"memh", truncstorei16>;
-defm STriw_ind : ST_indirect_lo<"memw", store>;
-
-// Store - absolute addressing mode: These instruction take constant
-// value as the extended operand.
-multiclass ST_absimm<string OpcStr> {
-let isExtended = 1, opExtendable = 0, isPredicable = 1,
-validSubTargets = HasV4SubT in
- def _abs_V4 : STInst2<(outs),
- (ins u0AlwaysExt:$src1, IntRegs:$src2),
- !strconcat(OpcStr, "(##$src1) = $src2"),
- []>,
- Requires<[HasV4T]>;
-
-let isExtended = 1, opExtendable = 1, isPredicated = 1,
-validSubTargets = HasV4SubT in {
- def _abs_cPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
- !strconcat("if ($src1)", !strconcat(OpcStr, "(##$src2) = $src3")),
- []>,
- Requires<[HasV4T]>;
-
- def _abs_cNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
- !strconcat("if (!$src1)", !strconcat(OpcStr, "(##$src2) = $src3")),
- []>,
- Requires<[HasV4T]>;
-
- def _abs_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
- !strconcat("if ($src1.new)",
- !strconcat(OpcStr, "(##$src2) = $src3")),
- []>,
- Requires<[HasV4T]>;
-
- def _abs_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
- !strconcat("if (!$src1.new)",
- !strconcat(OpcStr, "(##$src2) = $src3")),
- []>,
- Requires<[HasV4T]>;
-}
-
-let isExtended = 1, opExtendable = 0, mayStore = 1, isNVStore = 1,
-validSubTargets = HasV4SubT in
- def _abs_nv_V4 : NVInst_V4<(outs),
- (ins u0AlwaysExt:$src1, IntRegs:$src2),
- !strconcat(OpcStr, "(##$src1) = $src2.new"),
- []>,
- Requires<[HasV4T]>;
-
-let isExtended = 1, opExtendable = 1, mayStore = 1, isPredicated = 1,
-isNVStore = 1, validSubTargets = HasV4SubT in {
- def _abs_cPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
- !strconcat("if ($src1)",
- !strconcat(OpcStr, "(##$src2) = $src3.new")),
- []>,
- Requires<[HasV4T]>;
-
- def _abs_cNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
- !strconcat("if (!$src1)",
- !strconcat(OpcStr, "(##$src2) = $src3.new")),
- []>,
- Requires<[HasV4T]>;
-
- def _abs_cdnPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
- !strconcat("if ($src1.new)",
- !strconcat(OpcStr, "(##$src2) = $src3.new")),
- []>,
- Requires<[HasV4T]>;
-
- def _abs_cdnNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
- !strconcat("if (!$src1.new)",
- !strconcat(OpcStr, "(##$src2) = $src3.new")),
- []>,
- Requires<[HasV4T]>;
-}
-}
+let AddedComplexity = 40 in
+def : Pat <(i32 (sextloadi8 (add IntRegs:$src1,
+ (NumUsesBelowThresCONST32 tglobaladdr:$offset)))),
+ (i32 (LDrib_ind_lo_V4 IntRegs:$src1, 0, tglobaladdr:$offset))>,
+ Requires<[HasV4T]>;
-defm STrib_imm : ST_absimm<"memb">;
-defm STrih_imm : ST_absimm<"memh">;
-defm STriw_imm : ST_absimm<"memw">;
+let AddedComplexity = 40 in
+def : Pat <(i32 (zextloadi8 (add IntRegs:$src1,
+ (NumUsesBelowThresCONST32 tglobaladdr:$offset)))),
+ (i32 (LDriub_ind_lo_V4 IntRegs:$src1, 0, tglobaladdr:$offset))>,
+ Requires<[HasV4T]>;
let Predicates = [HasV4T], AddedComplexity = 30 in {
def : Pat<(truncstorei8 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
- (STrib_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
+ (STrib_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
def : Pat<(truncstorei16 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
- (STrih_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
+ (STrih_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
def : Pat<(store (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
- (STriw_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
-}
-
-// Load - absolute addressing mode: These instruction take constant
-// value as the extended operand
-
-multiclass LD_absimm<string OpcStr> {
-let isExtended = 1, opExtendable = 1, isPredicable = 1,
-validSubTargets = HasV4SubT in
- def _abs_V4 : LDInst2<(outs IntRegs:$dst),
- (ins u0AlwaysExt:$src),
- !strconcat("$dst = ",
- !strconcat(OpcStr, "(##$src)")),
- []>,
- Requires<[HasV4T]>;
-
-let isExtended = 1, opExtendable = 2, isPredicated = 1,
-validSubTargets = HasV4SubT in {
- def _abs_cPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, u0AlwaysExt:$src2),
- !strconcat("if ($src1) $dst = ",
- !strconcat(OpcStr, "(##$src2)")),
- []>,
- Requires<[HasV4T]>;
-
- def _abs_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, u0AlwaysExt:$src2),
- !strconcat("if (!$src1) $dst = ",
- !strconcat(OpcStr, "(##$src2)")),
- []>,
- Requires<[HasV4T]>;
-
- def _abs_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, u0AlwaysExt:$src2),
- !strconcat("if ($src1.new) $dst = ",
- !strconcat(OpcStr, "(##$src2)")),
- []>,
- Requires<[HasV4T]>;
-
- def _abs_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, u0AlwaysExt:$src2),
- !strconcat("if (!$src1.new) $dst = ",
- !strconcat(OpcStr, "(##$src2)")),
- []>,
- Requires<[HasV4T]>;
+ (STriw_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
}
-}
-
-defm LDrib_imm : LD_absimm<"memb">;
-defm LDriub_imm : LD_absimm<"memub">;
-defm LDrih_imm : LD_absimm<"memh">;
-defm LDriuh_imm : LD_absimm<"memuh">;
-defm LDriw_imm : LD_absimm<"memw">;
let Predicates = [HasV4T], AddedComplexity = 30 in {
def : Pat<(i32 (load u0AlwaysExtPred:$src)),
- (LDriw_imm_abs_V4 u0AlwaysExtPred:$src)>;
+ (LDriw_abs_V4 u0AlwaysExtPred:$src)>;
def : Pat<(i32 (sextloadi8 u0AlwaysExtPred:$src)),
- (LDrib_imm_abs_V4 u0AlwaysExtPred:$src)>;
+ (LDrib_abs_V4 u0AlwaysExtPred:$src)>;
def : Pat<(i32 (zextloadi8 u0AlwaysExtPred:$src)),
- (LDriub_imm_abs_V4 u0AlwaysExtPred:$src)>;
+ (LDriub_abs_V4 u0AlwaysExtPred:$src)>;
def : Pat<(i32 (sextloadi16 u0AlwaysExtPred:$src)),
- (LDrih_imm_abs_V4 u0AlwaysExtPred:$src)>;
+ (LDrih_abs_V4 u0AlwaysExtPred:$src)>;
def : Pat<(i32 (zextloadi16 u0AlwaysExtPred:$src)),
- (LDriuh_imm_abs_V4 u0AlwaysExtPred:$src)>;
+ (LDriuh_abs_V4 u0AlwaysExtPred:$src)>;
}
-// Indexed store double word - global address.
+// Indexed store word - global address.
// memw(Rs+#u6:2)=#S8
let AddedComplexity = 10 in
def STriw_offset_ext_V4 : STInst<(outs),
@@ -4070,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/HexagonMCInst.h b/lib/Target/Hexagon/HexagonMCInst.h
deleted file mode 100644
index e16636e..0000000
--- a/lib/Target/Hexagon/HexagonMCInst.h
+++ /dev/null
@@ -1,41 +0,0 @@
-//===- HexagonMCInst.h - Hexagon sub-class of MCInst ----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class extends MCInst to allow some VLIW annotation.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef HEXAGONMCINST_H
-#define HEXAGONMCINST_H
-
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/MC/MCInst.h"
-
-namespace llvm {
- class HexagonMCInst: public MCInst {
- // Packet start and end markers
- unsigned startPacket: 1, endPacket: 1;
- const MachineInstr *MachineI;
- public:
- explicit HexagonMCInst(): MCInst(),
- startPacket(0), endPacket(0) {}
-
- const MachineInstr* getMI() const { return MachineI; }
-
- void setMI(const MachineInstr *MI) { MachineI = MI; }
-
- bool isStartPacket() const { return (startPacket); }
- bool isEndPacket() const { return (endPacket); }
-
- void setStartPacket(bool yes) { startPacket = yes; }
- void setEndPacket(bool yes) { endPacket = yes; }
- };
-}
-
-#endif
diff --git a/lib/Target/Hexagon/HexagonMachineFunctionInfo.h b/lib/Target/Hexagon/HexagonMachineFunctionInfo.h
index 0318c51..bd7b26a 100644
--- a/lib/Target/Hexagon/HexagonMachineFunctionInfo.h
+++ b/lib/Target/Hexagon/HexagonMachineFunctionInfo.h
@@ -29,15 +29,18 @@ class HexagonMachineFunctionInfo : public MachineFunctionInfo {
std::vector<MachineInstr*> AllocaAdjustInsts;
int VarArgsFrameIndex;
bool HasClobberLR;
+ bool HasEHReturn;
std::map<const MachineInstr*, unsigned> PacketInfo;
public:
- HexagonMachineFunctionInfo() : SRetReturnReg(0), HasClobberLR(0) {}
+ HexagonMachineFunctionInfo() : SRetReturnReg(0), HasClobberLR(0),
+ HasEHReturn(false) {}
HexagonMachineFunctionInfo(MachineFunction &MF) : SRetReturnReg(0),
- HasClobberLR(0) {}
+ HasClobberLR(0),
+ HasEHReturn(false) {}
unsigned getSRetReturnReg() const { return SRetReturnReg; }
void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
@@ -69,6 +72,8 @@ public:
void setHasClobberLR(bool v) { HasClobberLR = v; }
bool hasClobberLR() const { return HasClobberLR; }
+ bool hasEHReturn() const { return HasEHReturn; };
+ void setHasEHReturn(bool H = true) { HasEHReturn = H; };
};
} // End llvm namespace
diff --git a/lib/Target/Hexagon/HexagonMachineScheduler.cpp b/lib/Target/Hexagon/HexagonMachineScheduler.cpp
index 1388ad4..10bb3e9 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);
@@ -209,6 +208,8 @@ void ConvergingVLIWScheduler::initialize(ScheduleDAGMI *dag) {
Top.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG);
Bot.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG);
+ delete Top.ResourceModel;
+ delete Bot.ResourceModel;
Top.ResourceModel = new VLIWResourceModel(TM, DAG->getSchedModel());
Bot.ResourceModel = new VLIWResourceModel(TM, DAG->getSchedModel());
@@ -223,7 +224,7 @@ void ConvergingVLIWScheduler::releaseTopNode(SUnit *SU) {
for (SUnit::succ_iterator I = SU->Preds.begin(), E = SU->Preds.end();
I != E; ++I) {
unsigned PredReadyCycle = I->getSUnit()->TopReadyCycle;
- unsigned MinLatency = I->getMinLatency();
+ unsigned MinLatency = I->getLatency();
#ifndef NDEBUG
Top.MaxMinLatency = std::max(MinLatency, Top.MaxMinLatency);
#endif
@@ -242,7 +243,7 @@ void ConvergingVLIWScheduler::releaseBottomNode(SUnit *SU) {
for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
I != E; ++I) {
unsigned SuccReadyCycle = I->getSUnit()->BotReadyCycle;
- unsigned MinLatency = I->getMinLatency();
+ unsigned MinLatency = I->getLatency();
#ifndef NDEBUG
Bot.MaxMinLatency = std::max(MinLatency, Bot.MaxMinLatency);
#endif
@@ -409,7 +410,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 cd3d289..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,9 +72,12 @@ namespace {
public:
static char ID;
- HexagonNewValueJump() : MachineFunctionPass(ID) { }
+ HexagonNewValueJump() : MachineFunctionPass(ID) {
+ initializeHexagonNewValueJumpPass(*PassRegistry::getPassRegistry());
+ }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<MachineBranchProbabilityInfo>();
MachineFunctionPass::getAnalysisUsage(AU);
}
@@ -78,6 +88,8 @@ namespace {
virtual bool runOnMachineFunction(MachineFunction &Fn);
private:
+ /// \brief A handle to the branch probability pass.
+ const MachineBranchProbabilityInfo *MBPI;
};
@@ -85,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,
@@ -208,14 +227,10 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII,
// range specified by the arch.
if (!secondReg) {
int64_t v = MI->getOperand(2).getImm();
- if (MI->getOpcode() == Hexagon::CMPGEri ||
- (MI->getOpcode() == Hexagon::CMPGEUri && v > 0))
- --v;
if (!(isUInt<5>(v) ||
((MI->getOpcode() == Hexagon::CMPEQri ||
- MI->getOpcode() == Hexagon::CMPGTri ||
- MI->getOpcode() == Hexagon::CMPGEri) &&
+ MI->getOpcode() == Hexagon::CMPGTri) &&
(v == -1))))
return false;
}
@@ -271,58 +286,63 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII,
// Given a compare operator, return a matching New Value Jump
// compare operator. Make sure that MI here is included in
// HexagonInstrInfo.cpp::isNewValueJumpCandidate
-static unsigned getNewValueJumpOpcode(const MachineInstr *MI, int reg,
- bool secondRegNewified) {
+static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg,
+ bool secondRegNewified,
+ MachineBasicBlock *jmpTarget,
+ const MachineBranchProbabilityInfo
+ *MBPI) {
+ bool taken = false;
+ MachineBasicBlock *Src = MI->getParent();
+ const BranchProbability Prediction =
+ MBPI->getEdgeProbability(Src, jmpTarget);
+
+ if (Prediction >= BranchProbability(1,2))
+ taken = true;
+
switch (MI->getOpcode()) {
case Hexagon::CMPEQrr:
- return Hexagon::JMP_EQrrPt_nv_V4;
+ return taken ? Hexagon::CMPEQrr_t_Jumpnv_t_V4
+ : Hexagon::CMPEQrr_t_Jumpnv_nt_V4;
case Hexagon::CMPEQri: {
if (reg >= 0)
- return Hexagon::JMP_EQriPt_nv_V4;
+ return taken ? Hexagon::CMPEQri_t_Jumpnv_t_V4
+ : Hexagon::CMPEQri_t_Jumpnv_nt_V4;
else
- return Hexagon::JMP_EQriPtneg_nv_V4;
+ return taken ? Hexagon::CMPEQn1_t_Jumpnv_t_V4
+ : Hexagon::CMPEQn1_t_Jumpnv_nt_V4;
}
- case Hexagon::CMPLTrr:
case Hexagon::CMPGTrr: {
if (secondRegNewified)
- return Hexagon::JMP_GTrrdnPt_nv_V4;
+ return taken ? Hexagon::CMPLTrr_t_Jumpnv_t_V4
+ : Hexagon::CMPLTrr_t_Jumpnv_nt_V4;
else
- return Hexagon::JMP_GTrrPt_nv_V4;
- }
-
- case Hexagon::CMPGEri: {
- if (reg >= 1)
- return Hexagon::JMP_GTriPt_nv_V4;
- else
- return Hexagon::JMP_GTriPtneg_nv_V4;
+ return taken ? Hexagon::CMPGTrr_t_Jumpnv_t_V4
+ : Hexagon::CMPGTrr_t_Jumpnv_nt_V4;
}
case Hexagon::CMPGTri: {
if (reg >= 0)
- return Hexagon::JMP_GTriPt_nv_V4;
+ return taken ? Hexagon::CMPGTri_t_Jumpnv_t_V4
+ : Hexagon::CMPGTri_t_Jumpnv_nt_V4;
else
- return Hexagon::JMP_GTriPtneg_nv_V4;
+ return taken ? Hexagon::CMPGTn1_t_Jumpnv_t_V4
+ : Hexagon::CMPGTn1_t_Jumpnv_nt_V4;
}
- case Hexagon::CMPLTUrr:
case Hexagon::CMPGTUrr: {
if (secondRegNewified)
- return Hexagon::JMP_GTUrrdnPt_nv_V4;
+ return taken ? Hexagon::CMPLTUrr_t_Jumpnv_t_V4
+ : Hexagon::CMPLTUrr_t_Jumpnv_nt_V4;
else
- return Hexagon::JMP_GTUrrPt_nv_V4;
+ return taken ? Hexagon::CMPGTUrr_t_Jumpnv_t_V4
+ : Hexagon::CMPGTUrr_t_Jumpnv_nt_V4;
}
case Hexagon::CMPGTUri:
- return Hexagon::JMP_GTUriPt_nv_V4;
-
- case Hexagon::CMPGEUri: {
- if (reg == 0)
- return Hexagon::JMP_EQrrPt_nv_V4;
- else
- return Hexagon::JMP_GTUriPt_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.");
@@ -346,6 +366,7 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
QII = static_cast<const HexagonInstrInfo *>(MF.getTarget().getInstrInfo());
QRI =
static_cast<const HexagonRegisterInfo *>(MF.getTarget().getRegisterInfo());
+ MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
if (!QRI->Subtarget.hasV4TOps() ||
DisableNewValueJumps) {
@@ -393,12 +414,12 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
DEBUG(dbgs() << "Instr: "; MI->dump(); dbgs() << "\n");
if (!foundJump &&
- (MI->getOpcode() == Hexagon::JMP_c ||
- MI->getOpcode() == Hexagon::JMP_cNot ||
- MI->getOpcode() == Hexagon::JMP_cdnPt ||
- MI->getOpcode() == Hexagon::JMP_cdnPnt ||
- MI->getOpcode() == Hexagon::JMP_cdnNotPt ||
- MI->getOpcode() == Hexagon::JMP_cdnNotPnt)) {
+ (MI->getOpcode() == Hexagon::JMP_t ||
+ MI->getOpcode() == Hexagon::JMP_f ||
+ MI->getOpcode() == Hexagon::JMP_tnew_t ||
+ MI->getOpcode() == Hexagon::JMP_tnew_nt ||
+ MI->getOpcode() == Hexagon::JMP_fnew_t ||
+ MI->getOpcode() == Hexagon::JMP_fnew_nt)) {
// This is where you would insert your compare and
// instr that feeds compare
jmpPos = MII;
@@ -434,9 +455,9 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
jmpTarget = MI->getOperand(1).getMBB();
foundJump = true;
- if (MI->getOpcode() == Hexagon::JMP_cNot ||
- MI->getOpcode() == Hexagon::JMP_cdnNotPt ||
- MI->getOpcode() == Hexagon::JMP_cdnNotPnt) {
+ if (MI->getOpcode() == Hexagon::JMP_f ||
+ MI->getOpcode() == Hexagon::JMP_fnew_t ||
+ MI->getOpcode() == Hexagon::JMP_fnew_nt) {
invertPredicate = true;
}
continue;
@@ -525,10 +546,8 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
if (isSecondOpReg) {
// In case of CMPLT, or CMPLTU, or EQ with the second register
// to newify, swap the operands.
- if (cmpInstr->getOpcode() == Hexagon::CMPLTrr ||
- cmpInstr->getOpcode() == Hexagon::CMPLTUrr ||
- (cmpInstr->getOpcode() == Hexagon::CMPEQrr &&
- feederReg == (unsigned) cmpOp2)) {
+ if (cmpInstr->getOpcode() == Hexagon::CMPEQrr &&
+ feederReg == (unsigned) cmpOp2) {
unsigned tmp = cmpReg1;
bool tmpIsKill = MO1IsKill;
cmpReg1 = cmpOp2;
@@ -582,44 +601,37 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
assert((QII->isNewValueJumpCandidate(cmpInstr)) &&
"This compare is not a New Value Jump candidate.");
unsigned opc = getNewValueJumpOpcode(cmpInstr, cmpOp2,
- isSecondOpNewified);
+ isSecondOpNewified,
+ jmpTarget, MBPI);
if (invertPredicate)
opc = QII->getInvertedPredicatedOpcode(opc);
- // Manage the conversions from CMPGEUri to either CMPEQrr
- // or CMPGTUri properly. See Arch spec for CMPGEUri instructions.
- // This has to be after the getNewValueJumpOpcode function call as
- // second operand of the compare could be modified in this logic.
- if (cmpInstr->getOpcode() == Hexagon::CMPGEUri) {
- if (cmpOp2 == 0) {
- cmpOp2 = cmpReg1;
- MO2IsKill = MO1IsKill;
- isSecondOpReg = true;
- } else
- --cmpOp2;
- }
-
- // Manage the conversions from CMPGEri to CMPGTUri properly.
- // See Arch spec for CMPGEri instructions.
- if (cmpInstr->getOpcode() == Hexagon::CMPGEri)
- --cmpOp2;
-
- if (isSecondOpReg) {
+ if (isSecondOpReg)
NewMI = BuildMI(*MBB, jmpPos, dl,
QII->get(opc))
.addReg(cmpReg1, getKillRegState(MO1IsKill))
.addReg(cmpOp2, getKillRegState(MO2IsKill))
.addMBB(jmpTarget);
- }
- else {
+
+ else if ((cmpInstr->getOpcode() == Hexagon::CMPEQri ||
+ cmpInstr->getOpcode() == Hexagon::CMPGTri) &&
+ cmpOp2 == -1 )
+ // Corresponding new-value compare jump instructions don't have the
+ // operand for -1 immediate value.
+ NewMI = BuildMI(*MBB, jmpPos, dl,
+ QII->get(opc))
+ .addReg(cmpReg1, getKillRegState(MO1IsKill))
+ .addMBB(jmpTarget);
+
+ else
NewMI = BuildMI(*MBB, jmpPos, dl,
QII->get(opc))
.addReg(cmpReg1, getKillRegState(MO1IsKill))
.addImm(cmpOp2)
.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 576f1d7..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"));
@@ -73,6 +69,14 @@ static cl::opt<bool> DisableOptSZExt("disable-hexagon-optszext",
cl::Hidden, cl::ZeroOrMore, cl::init(false),
cl::desc("Disable Optimization of Sign/Zero Extends"));
+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;
@@ -81,7 +85,9 @@ namespace {
public:
static char ID;
- HexagonPeephole() : MachineFunctionPass(ID) { }
+ HexagonPeephole() : MachineFunctionPass(ID) {
+ initializeHexagonPeepholePass(*PassRegistry::getPassRegistry());
+ }
bool runOnMachineFunction(MachineFunction &MF);
@@ -100,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().
@@ -142,6 +150,21 @@ bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
}
}
+ // Look for %vreg170<def> = COMBINE_ir_V4 (0, %vreg169)
+ // %vreg170:DoublRegs, %vreg169:IntRegs
+ if (!DisableOptExtTo64 &&
+ MI->getOpcode () == Hexagon::COMBINE_Ir_V4) {
+ assert (MI->getNumOperands() == 3);
+ MachineOperand &Dst = MI->getOperand(0);
+ MachineOperand &Src1 = MI->getOperand(1);
+ MachineOperand &Src2 = MI->getOperand(2);
+ if (Src1.getImm() != 0)
+ continue;
+ unsigned DstReg = Dst.getReg();
+ unsigned SrcReg = Src2.getReg();
+ PeepholeMap[DstReg] = SrcReg;
+ }
+
// Look for this sequence below
// %vregDoubleReg1 = LSRd_ri %vregDoubleReg0, 32
// %vregIntReg = COPY %vregDoubleReg1:subreg_loreg.
diff --git a/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/lib/Target/Hexagon/HexagonRegisterInfo.cpp
index f947dfc..d5ca4d7 100644
--- a/lib/Target/Hexagon/HexagonRegisterInfo.cpp
+++ b/lib/Target/Hexagon/HexagonRegisterInfo.cpp
@@ -14,34 +14,33 @@
#include "HexagonRegisterInfo.h"
#include "Hexagon.h"
-#include "HexagonMachineFunctionInfo.h"
#include "HexagonSubtarget.h"
#include "HexagonTargetMachine.h"
+#include "HexagonMachineFunctionInfo.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Type.h"
#include "llvm/MC/MachineLocation.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ErrorHandling.h"
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
@@ -129,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();
@@ -215,28 +216,41 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
MI.getOperand(FIOperandNum).ChangeToRegister(resReg, false, false,true);
MI.getOperand(FIOperandNum+1).ChangeToImmediate(0);
} else if (TII.isMemOp(&MI)) {
- unsigned resReg = HEXAGON_RESERVED_REG_1;
- if (!MFI.hasVarSizedObjects() &&
- TII.isValidOffset(MI.getOpcode(), (FrameSize+Offset))) {
- MI.getOperand(FIOperandNum).ChangeToRegister(getStackRegister(),
- false, false, true);
- MI.getOperand(FIOperandNum+1).ChangeToImmediate(FrameSize+Offset);
- } else if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) {
- BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
- TII.get(Hexagon::CONST32_Int_Real), resReg).addImm(Offset);
- BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
- TII.get(Hexagon::ADD_rr),
- resReg).addReg(FrameReg).addReg(resReg);
- MI.getOperand(FIOperandNum).ChangeToRegister(resReg, false, false,
- true);
- MI.getOperand(FIOperandNum+1).ChangeToImmediate(0);
+ // use the constant extender if the instruction provides it
+ // and we are V4TOps.
+ if (Subtarget.hasV4TOps()) {
+ if (TII.isConstExtended(&MI)) {
+ MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false);
+ MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset);
+ TII.immediateExtend(&MI);
+ } else {
+ llvm_unreachable("Need to implement for memops");
+ }
} else {
- BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
- TII.get(Hexagon::ADD_ri),
- resReg).addReg(FrameReg).addImm(Offset);
- MI.getOperand(FIOperandNum).ChangeToRegister(resReg, false, false,
- true);
- MI.getOperand(FIOperandNum+1).ChangeToImmediate(0);
+ // Only V3 and older instructions here.
+ unsigned ResReg = HEXAGON_RESERVED_REG_1;
+ if (!MFI.hasVarSizedObjects() &&
+ TII.isValidOffset(MI.getOpcode(), (FrameSize+Offset))) {
+ MI.getOperand(FIOperandNum).ChangeToRegister(getStackRegister(),
+ false, false, false);
+ MI.getOperand(FIOperandNum+1).ChangeToImmediate(FrameSize+Offset);
+ } else if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) {
+ BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
+ TII.get(Hexagon::CONST32_Int_Real), ResReg).addImm(Offset);
+ BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
+ TII.get(Hexagon::ADD_rr), ResReg).addReg(FrameReg).
+ addReg(ResReg);
+ MI.getOperand(FIOperandNum).ChangeToRegister(ResReg, false, false,
+ true);
+ MI.getOperand(FIOperandNum+1).ChangeToImmediate(0);
+ } else {
+ BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
+ TII.get(Hexagon::ADD_ri), ResReg).addReg(FrameReg).
+ addImm(Offset);
+ MI.getOperand(FIOperandNum).ChangeToRegister(ResReg, false, false,
+ true);
+ MI.getOperand(FIOperandNum+1).ChangeToImmediate(0);
+ }
}
} else {
unsigned dstReg = MI.getOperand(0).getReg();
@@ -281,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/HexagonSubtarget.cpp b/lib/Target/Hexagon/HexagonSubtarget.cpp
index 4bacb8f..07d5ce1 100644
--- a/lib/Target/Hexagon/HexagonSubtarget.cpp
+++ b/lib/Target/Hexagon/HexagonSubtarget.cpp
@@ -29,8 +29,16 @@ EnableV3("enable-hexagon-v3", cl::Hidden,
static cl::opt<bool>
EnableMemOps(
"enable-hexagon-memops",
- cl::Hidden, cl::ZeroOrMore, cl::ValueDisallowed,
- cl::desc("Generate V4 memop instructions."));
+ cl::Hidden, cl::ZeroOrMore, cl::ValueDisallowed, cl::init(true),
+ cl::desc(
+ "Generate V4 MEMOP in code generation for Hexagon target"));
+
+static cl::opt<bool>
+DisableMemOps(
+ "disable-hexagon-memops",
+ cl::Hidden, cl::ZeroOrMore, cl::ValueDisallowed, cl::init(false),
+ cl::desc(
+ "Do not generate V4 MEMOP in code generation for Hexagon target"));
static cl::opt<bool>
EnableIEEERndNear(
@@ -64,7 +72,10 @@ HexagonSubtarget::HexagonSubtarget(StringRef TT, StringRef CPU, StringRef FS):
// Initialize scheduling itinerary for the specified CPU.
InstrItins = getInstrItineraryForCPU(CPUString);
- if (EnableMemOps)
+ // UseMemOps on by default unless disabled explicitly
+ if (DisableMemOps)
+ UseMemOps = false;
+ else if (EnableMemOps)
UseMemOps = true;
else
UseMemOps = false;
diff --git a/lib/Target/Hexagon/HexagonTargetMachine.cpp b/lib/Target/Hexagon/HexagonTargetMachine.cpp
index d9fef3e..cd96b58 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,15 +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> DisableHexagonCFGOpt("disable-hexagon-cfgopt",
+ cl::Hidden, cl::ZeroOrMore, cl::init(false),
+ cl::desc("Disable Hexagon CFG Optimization"));
-static cl::
-opt<bool> DisableHexagonMISched("disable-hexagon-misched",
- cl::Hidden, cl::ZeroOrMore, cl::init(false),
- cl::desc("Disable Hexagon MI Scheduling"));
/// HexagonTargetMachineModule - Note that this is used on hosts that
/// cannot link in a library unless there are references into the
@@ -75,19 +78,21 @@ HexagonTargetMachine::HexagonTargetMachine(const Target &T, StringRef TT,
TSInfo(*this),
FrameLowering(Subtarget),
InstrItins(&Subtarget.getInstrItineraryData()) {
- setMCUseCFI(false);
+ setMCUseCFI(false);
+ initAsmInfo();
}
// addPassesForOptimizations - Allow the backend (target) to add Target
// Independent Optimization passes to the Pass Manager.
bool HexagonTargetMachine::addPassesForOptimizations(PassManagerBase &PM) {
-
- PM.add(createConstantPropagationPass());
- PM.add(createLoopSimplifyPass());
- PM.add(createDeadCodeEliminationPass());
- PM.add(createConstantPropagationPass());
- PM.add(createLoopUnrollPass());
- PM.add(createLoopStrengthReducePass());
+ if (getOptLevel() != CodeGenOpt::None) {
+ PM.add(createConstantPropagationPass());
+ PM.add(createLoopSimplifyPass());
+ PM.add(createDeadCodeEliminationPass());
+ PM.add(createConstantPropagationPass());
+ PM.add(createLoopUnrollPass());
+ PM.add(createLoopStrengthReducePass());
+ }
return true;
}
@@ -121,47 +126,71 @@ TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) {
}
bool HexagonPassConfig::addInstSelector() {
- addPass(createHexagonRemoveExtendOps(getHexagonTargetMachine()));
- addPass(createHexagonISelDag(getHexagonTargetMachine(), getOptLevel()));
- addPass(createHexagonPeephole());
+ HexagonTargetMachine &TM = getHexagonTargetMachine();
+ bool NoOpt = (getOptLevel() == CodeGenOpt::None);
+
+ if (!NoOpt)
+ addPass(createHexagonRemoveExtendArgs(TM));
+
+ addPass(createHexagonISelDag(TM, getOptLevel()));
+
+ if (!NoOpt) {
+ addPass(createHexagonPeephole());
+ printAndVerify("After hexagon peephole pass");
+ }
+
return false;
}
-
bool HexagonPassConfig::addPreRegAlloc() {
- if (!DisableHardwareLoops) {
- addPass(createHexagonHardwareLoops());
- }
+ if (getOptLevel() != CodeGenOpt::None)
+ if (!DisableHardwareLoops)
+ addPass(createHexagonHardwareLoops());
return false;
}
bool HexagonPassConfig::addPostRegAlloc() {
- addPass(createHexagonCFGOptimizer(getHexagonTargetMachine()));
- return true;
+ const HexagonTargetMachine &TM = getHexagonTargetMachine();
+ if (getOptLevel() != CodeGenOpt::None)
+ if (!DisableHexagonCFGOpt)
+ addPass(createHexagonCFGOptimizer(TM));
+ return false;
}
-
bool HexagonPassConfig::addPreSched2() {
- addPass(&IfConverterID);
+ 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) {
- addPass(createHexagonFixupHwLoops());
- }
-
- addPass(createHexagonNewValueJump());
+ 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.
- addPass(createHexagonPacketizer());
+ 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 866beb1..41e382d 100644
--- a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
+++ b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
@@ -48,19 +48,32 @@
#include "HexagonMachineFunctionInfo.h"
#include <map>
+#include <vector>
using namespace llvm;
+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"));
+
+namespace llvm {
+ void initializeHexagonPacketizerPass(PassRegistry&);
+}
+
+
namespace {
class HexagonPacketizer : public MachineFunctionPass {
public:
static char ID;
- HexagonPacketizer() : MachineFunctionPass(ID) {}
+ HexagonPacketizer() : MachineFunctionPass(ID) {
+ initializeHexagonPacketizerPass(*PassRegistry::getPassRegistry());
+ }
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
AU.addRequired<MachineDominatorTree>();
+ AU.addRequired<MachineBranchProbabilityInfo>();
AU.addPreserved<MachineDominatorTree>();
AU.addRequired<MachineLoopInfo>();
AU.addPreserved<MachineLoopInfo>();
@@ -96,10 +109,17 @@ namespace {
// schedule this instruction.
bool FoundSequentialDependence;
+ /// \brief A handle to the branch probability pass.
+ const MachineBranchProbabilityInfo *MBPI;
+
+ // Track MIs with ignored dependece.
+ std::vector<MachineInstr*> IgnoreDepMIs;
+
public:
// Ctor.
HexagonPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI,
- MachineDominatorTree &MDT);
+ MachineDominatorTree &MDT,
+ const MachineBranchProbabilityInfo *MBPI);
// initPacketizerState - initialize some internal flags.
void initPacketizerState();
@@ -123,20 +143,20 @@ namespace {
private:
bool IsCallDependent(MachineInstr* MI, SDep::Kind DepType, unsigned DepReg);
bool PromoteToDotNew(MachineInstr* MI, SDep::Kind DepType,
- MachineBasicBlock::iterator &MII,
- const TargetRegisterClass* RC);
+ MachineBasicBlock::iterator &MII,
+ const TargetRegisterClass* RC);
bool CanPromoteToDotNew(MachineInstr* MI, SUnit* PacketSU,
- unsigned DepReg,
- std::map <MachineInstr*, SUnit*> MIToSUnit,
- MachineBasicBlock::iterator &MII,
- const TargetRegisterClass* RC);
+ unsigned DepReg,
+ std::map <MachineInstr*, SUnit*> MIToSUnit,
+ MachineBasicBlock::iterator &MII,
+ const TargetRegisterClass* RC);
bool CanPromoteToNewValue(MachineInstr* MI, SUnit* PacketSU,
- unsigned DepReg,
- std::map <MachineInstr*, SUnit*> MIToSUnit,
- MachineBasicBlock::iterator &MII);
+ unsigned DepReg,
+ std::map <MachineInstr*, SUnit*> MIToSUnit,
+ MachineBasicBlock::iterator &MII);
bool CanPromoteToNewValueStore(MachineInstr* MI, MachineInstr* PacketMI,
- unsigned DepReg,
- std::map <MachineInstr*, SUnit*> MIToSUnit);
+ unsigned DepReg,
+ std::map <MachineInstr*, SUnit*> MIToSUnit);
bool DemoteToDotOld(MachineInstr* MI);
bool ArePredicatesComplements(MachineInstr* MI1, MachineInstr* MI2,
std::map <MachineInstr*, SUnit*> MIToSUnit);
@@ -144,28 +164,39 @@ 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);
bool isNewValueInst(MachineInstr* MI);
- bool isDotNewInst(MachineInstr* MI);
};
}
+INITIALIZE_PASS_BEGIN(HexagonPacketizer, "packets", "Hexagon Packetizer",
+ false, false)
+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)
+
+
// HexagonPacketizerList Ctor.
HexagonPacketizerList::HexagonPacketizerList(
- MachineFunction &MF, MachineLoopInfo &MLI,MachineDominatorTree &MDT)
+ MachineFunction &MF, MachineLoopInfo &MLI,MachineDominatorTree &MDT,
+ const MachineBranchProbabilityInfo *MBPI)
: VLIWPacketizerList(MF, MLI, MDT, true){
+ this->MBPI = MBPI;
}
bool HexagonPacketizer::runOnMachineFunction(MachineFunction &Fn) {
const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo();
MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>();
MachineDominatorTree &MDT = getAnalysis<MachineDominatorTree>();
-
+ const MachineBranchProbabilityInfo *MBPI =
+ &getAnalysis<MachineBranchProbabilityInfo>();
// Instantiate the packetizer.
- HexagonPacketizerList Packetizer(Fn, MLI, MDT);
+ HexagonPacketizerList Packetizer(Fn, MLI, MDT, MBPI);
// DFA state table should not be empty.
assert(Packetizer.getResourceTracker() && "Empty DFA table!");
@@ -351,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);
@@ -466,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(const int opc) {
- switch (opc) {
- 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_c:
- return Hexagon::JMP_cdnPt;
-
- case Hexagon::JMP_cNot:
- return Hexagon::JMP_cdnNotPt;
-
- case Hexagon::JMPR_cPt:
- return Hexagon::JMPR_cdnPt_V3;
-
- case Hexagon::JMPR_cNotPt:
- return Hexagon::JMPR_cdnNotPt_V3;
-
- // 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;
@@ -1262,1062 +437,38 @@ bool HexagonPacketizerList::PromoteToDotNew(MachineInstr* MI,
int NewOpcode;
if (RC == &Hexagon::PredRegsRegClass)
- NewOpcode = GetDotNewPredOp(MI->getOpcode());
+ 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_cdnPt:
- return Hexagon::JMP_c;
-
- case Hexagon::JMP_cdnNotPt:
- return Hexagon::JMP_cNot;
-
- case Hexagon::JMPR_cdnPt_V3:
- return Hexagon::JMPR_cPt;
-
- case Hexagon::JMPR_cdnNotPt_V3:
- return Hexagon::JMPR_cNotPt;
-
- // 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.
-
-static bool GetPredicateSense(MachineInstr* MI,
- const HexagonInstrInfo *QII) {
-
- 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_cdnPt :
- 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;
+enum PredicateKind {
+ PK_False,
+ PK_True,
+ PK_Unknown
+};
- 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_cdnNotPt :
- 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;
-}
+/// 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;
-bool HexagonPacketizerList::isDotNewInst(MachineInstr* MI) {
- const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
- if (QII->isNewValueInst(MI))
- return true;
+ if (QII->isPredicatedTrue(MI))
+ return PK_True;
- switch (MI->getOpcode()) {
- case Hexagon::TFR_cdnNotPt:
- case Hexagon::TFR_cdnPt:
- case Hexagon::TFRI_cdnNotPt:
- case Hexagon::TFRI_cdnPt:
- case Hexagon::LDrid_cdnPt :
- case Hexagon::LDrid_cdnNotPt :
- case Hexagon::LDrid_indexed_cdnPt :
- case Hexagon::LDrid_indexed_cdnNotPt :
- case Hexagon::POST_LDrid_cdnPt_V4 :
- case Hexagon::POST_LDrid_cdnNotPt_V4 :
- case Hexagon::LDriw_cdnPt :
- case Hexagon::LDriw_cdnNotPt :
- case Hexagon::LDriw_indexed_cdnPt :
- case Hexagon::LDriw_indexed_cdnNotPt :
- case Hexagon::POST_LDriw_cdnPt_V4 :
- case Hexagon::POST_LDriw_cdnNotPt_V4 :
- case Hexagon::LDrih_cdnPt :
- case Hexagon::LDrih_cdnNotPt :
- case Hexagon::LDrih_indexed_cdnPt :
- case Hexagon::LDrih_indexed_cdnNotPt :
- case Hexagon::POST_LDrih_cdnPt_V4 :
- case Hexagon::POST_LDrih_cdnNotPt_V4 :
- case Hexagon::LDrib_cdnPt :
- case Hexagon::LDrib_cdnNotPt :
- case Hexagon::LDrib_indexed_cdnPt :
- case Hexagon::LDrib_indexed_cdnNotPt :
- case Hexagon::POST_LDrib_cdnPt_V4 :
- case Hexagon::POST_LDrib_cdnNotPt_V4 :
- case Hexagon::LDriuh_cdnPt :
- case Hexagon::LDriuh_cdnNotPt :
- case Hexagon::LDriuh_indexed_cdnPt :
- case Hexagon::LDriuh_indexed_cdnNotPt :
- case Hexagon::POST_LDriuh_cdnPt_V4 :
- case Hexagon::POST_LDriuh_cdnNotPt_V4 :
- case Hexagon::LDriub_cdnPt :
- case Hexagon::LDriub_cdnNotPt :
- case Hexagon::LDriub_indexed_cdnPt :
- case Hexagon::LDriub_indexed_cdnNotPt :
- case Hexagon::POST_LDriub_cdnPt_V4 :
- case Hexagon::POST_LDriub_cdnNotPt_V4 :
-
- case Hexagon::LDrid_indexed_shl_cdnPt_V4 :
- case Hexagon::LDrid_indexed_shl_cdnNotPt_V4 :
- case Hexagon::LDrib_indexed_shl_cdnPt_V4 :
- case Hexagon::LDrib_indexed_shl_cdnNotPt_V4 :
- case Hexagon::LDriub_indexed_shl_cdnPt_V4 :
- case Hexagon::LDriub_indexed_shl_cdnNotPt_V4 :
- case Hexagon::LDrih_indexed_shl_cdnPt_V4 :
- case Hexagon::LDrih_indexed_shl_cdnNotPt_V4 :
- case Hexagon::LDriuh_indexed_shl_cdnPt_V4 :
- case Hexagon::LDriuh_indexed_shl_cdnNotPt_V4 :
- case Hexagon::LDriw_indexed_shl_cdnPt_V4 :
- case Hexagon::LDriw_indexed_shl_cdnNotPt_V4 :
-
-// Coditional add
- case Hexagon::ADD_ri_cdnPt:
- case Hexagon::ADD_ri_cdnNotPt:
- case Hexagon::ADD_rr_cdnPt:
- case Hexagon::ADD_rr_cdnNotPt:
-
- // Conditional logical operations
- case Hexagon::XOR_rr_cdnPt :
- case Hexagon::XOR_rr_cdnNotPt :
- case Hexagon::AND_rr_cdnPt :
- case Hexagon::AND_rr_cdnNotPt :
- case Hexagon::OR_rr_cdnPt :
- case Hexagon::OR_rr_cdnNotPt :
-
- // Conditonal subtract
- case Hexagon::SUB_rr_cdnPt :
- case Hexagon::SUB_rr_cdnNotPt :
-
- // Conditional combine
- case Hexagon::COMBINE_rr_cdnPt :
- case Hexagon::COMBINE_rr_cdnNotPt :
-
- // Conditional shift operations
- case Hexagon::ASLH_cdnPt_V4:
- case Hexagon::ASLH_cdnNotPt_V4:
- case Hexagon::ASRH_cdnPt_V4:
- case Hexagon::ASRH_cdnNotPt_V4:
- case Hexagon::SXTB_cdnPt_V4:
- case Hexagon::SXTB_cdnNotPt_V4:
- case Hexagon::SXTH_cdnPt_V4:
- case Hexagon::SXTH_cdnNotPt_V4:
- case Hexagon::ZXTB_cdnPt_V4:
- case Hexagon::ZXTB_cdnNotPt_V4:
- case Hexagon::ZXTH_cdnPt_V4:
- case Hexagon::ZXTH_cdnNotPt_V4:
-
- // Conditional stores
- case Hexagon::STrib_imm_cdnPt_V4 :
- case Hexagon::STrib_imm_cdnNotPt_V4 :
- case Hexagon::STrib_cdnPt_V4 :
- case Hexagon::STrib_cdnNotPt_V4 :
- case Hexagon::STrib_indexed_cdnPt_V4 :
- case Hexagon::STrib_indexed_cdnNotPt_V4 :
- case Hexagon::POST_STbri_cdnPt_V4 :
- case Hexagon::POST_STbri_cdnNotPt_V4 :
- case Hexagon::STrib_indexed_shl_cdnPt_V4 :
- case Hexagon::STrib_indexed_shl_cdnNotPt_V4 :
-
- // Store doubleword conditionally
- case Hexagon::STrid_indexed_cdnPt_V4 :
- case Hexagon::STrid_indexed_cdnNotPt_V4 :
- case Hexagon::STrid_indexed_shl_cdnPt_V4 :
- case Hexagon::STrid_indexed_shl_cdnNotPt_V4 :
- case Hexagon::POST_STdri_cdnPt_V4 :
- case Hexagon::POST_STdri_cdnNotPt_V4 :
-
- // Store halfword conditionally
- case Hexagon::STrih_cdnPt_V4 :
- case Hexagon::STrih_cdnNotPt_V4 :
- case Hexagon::STrih_indexed_cdnPt_V4 :
- case Hexagon::STrih_indexed_cdnNotPt_V4 :
- case Hexagon::STrih_imm_cdnPt_V4 :
- case Hexagon::STrih_imm_cdnNotPt_V4 :
- case Hexagon::STrih_indexed_shl_cdnPt_V4 :
- case Hexagon::STrih_indexed_shl_cdnNotPt_V4 :
- case Hexagon::POST_SThri_cdnPt_V4 :
- case Hexagon::POST_SThri_cdnNotPt_V4 :
-
- // Store word conditionally
- case Hexagon::STriw_cdnPt_V4 :
- case Hexagon::STriw_cdnNotPt_V4 :
- case Hexagon::STriw_indexed_cdnPt_V4 :
- case Hexagon::STriw_indexed_cdnNotPt_V4 :
- case Hexagon::STriw_imm_cdnPt_V4 :
- case Hexagon::STriw_imm_cdnNotPt_V4 :
- case Hexagon::STriw_indexed_shl_cdnPt_V4 :
- case Hexagon::STriw_indexed_shl_cdnNotPt_V4 :
- case Hexagon::POST_STwri_cdnPt_V4 :
- case Hexagon::POST_STwri_cdnNotPt_V4 :
-
- case Hexagon::LDd_GP_cdnPt_V4:
- case Hexagon::LDd_GP_cdnNotPt_V4:
- case Hexagon::LDb_GP_cdnPt_V4:
- case Hexagon::LDb_GP_cdnNotPt_V4:
- case Hexagon::LDub_GP_cdnPt_V4:
- case Hexagon::LDub_GP_cdnNotPt_V4:
- case Hexagon::LDh_GP_cdnPt_V4:
- case Hexagon::LDh_GP_cdnNotPt_V4:
- case Hexagon::LDuh_GP_cdnPt_V4:
- case Hexagon::LDuh_GP_cdnNotPt_V4:
- case Hexagon::LDw_GP_cdnPt_V4:
- case Hexagon::LDw_GP_cdnNotPt_V4:
-
- case Hexagon::STd_GP_cdnPt_V4:
- case Hexagon::STd_GP_cdnNotPt_V4:
- case Hexagon::STb_GP_cdnPt_V4:
- case Hexagon::STb_GP_cdnNotPt_V4:
- case Hexagon::STh_GP_cdnPt_V4:
- case Hexagon::STh_GP_cdnNotPt_V4:
- case Hexagon::STw_GP_cdnPt_V4:
- case Hexagon::STw_GP_cdnNotPt_V4:
- return true;
- }
- return false;
+ return PK_False;
}
static MachineOperand& GetPostIncrementOperand(MachineInstr *MI,
@@ -2386,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
@@ -2397,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
@@ -2445,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;
@@ -2490,8 +640,8 @@ bool HexagonPacketizerList::CanPromoteToNewValueStore( MachineInstr *MI,
// sense, i.e, either both should be negated or both should be none negated.
if (( predRegNumDst != predRegNumSrc) ||
- isDotNewInst(PacketMI) != isDotNewInst(MI) ||
- GetPredicateSense(MI, QII) != GetPredicateSense(PacketMI, QII)) {
+ QII->isDotNewInst(PacketMI) != QII->isDotNewInst(MI) ||
+ getPredicateSense(MI, QII) != getPredicateSense(PacketMI, QII)) {
return false;
}
}
@@ -2572,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();
@@ -2600,8 +751,9 @@ bool HexagonPacketizerList::CanPromoteToDotNew( MachineInstr *MI,
MachineBasicBlock::iterator &MII,
const TargetRegisterClass* RC )
{
- // already a dot new instruction
- if (isDotNewInst(MI) && !IsNewifyStore(MI))
+ const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
+ // Already a dot new instruction.
+ if (QII->isDotNewInst(MI) && !QII->mayBeNewStore(MI))
return false;
if (!isNewifiable(MI))
@@ -2611,13 +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.
- const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
- int NewOpcode = GetDotNewOp(MI->getOpcode());
+ int NewOpcode = QII->GetDotNewOp(MI);
const MCInstrDesc &desc = QII->get(NewOpcode);
DebugLoc dl;
MachineInstr *NewMI =
@@ -2686,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];
@@ -2734,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.
@@ -2757,9 +931,13 @@ 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)) &&
- (isDotNewInst(MI1) == isDotNewInst(MI2)));
+ 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)));
}
// initPacketizerState - Initialize packetizer flags
@@ -2856,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;
}
@@ -2898,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;
}
@@ -2906,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/InstPrinter/HexagonInstPrinter.cpp b/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp
index 36da6df..2ea0d2e 100644
--- a/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp
+++ b/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp
@@ -179,7 +179,7 @@ void HexagonInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) const {
// Branches can take an immediate operand. This is used by the branch
// selection pass to print $+8, an eight byte displacement from the PC.
- assert("Unknown branch operand.");
+ llvm_unreachable("Unknown branch operand.");
}
void HexagonInstPrinter::printCallOperand(const MCInst *MI, unsigned OpNo,
@@ -196,15 +196,9 @@ void HexagonInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
void HexagonInstPrinter::printSymbol(const MCInst *MI, unsigned OpNo,
raw_ostream &O, bool hi) const {
- const MCOperand& MO = MI->getOperand(OpNo);
+ assert(MI->getOperand(OpNo).isImm() && "Unknown symbol operand");
- O << '#' << (hi? "HI": "LO") << '(';
- if (MO.isImm()) {
- O << '#';
- printOperand(MI, OpNo, O);
- } else {
- assert("Unknown symbol operand");
- printOperand(MI, OpNo, O);
- }
+ O << '#' << (hi ? "HI" : "LO") << "(#";
+ printOperand(MI, OpNo, O);
O << ')';
}
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 86f75d1..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.
@@ -31,6 +31,7 @@ HexagonMCAsmInfo::HexagonMCAsmInfo(const Target &T, StringRef TT) {
AscizDirective = "\t.string\t";
WeakRefDirective = "\t.weak\t";
+ SupportsDebugInformation = true;
UsesELFSectionDirectiveForBSS = true;
ExceptionsType = ExceptionHandling::DwarfCFI;
}
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;
}