aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/Hexagon
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2013-01-21 13:15:17 -0800
committerStephen Hines <srhines@google.com>2013-01-21 13:15:17 -0800
commit059800f9e3fee2852672f846d91a2da14da7783a (patch)
treea6ef16b7263252ae1b8069295ea9cbbae0d9467d /lib/Target/Hexagon
parentcbefa15de4821975bb99fc6d74b3bdb42b2df45c (diff)
parentb6714227eda5d499f7667fc865f931126a8dc488 (diff)
downloadexternal_llvm-059800f9e3fee2852672f846d91a2da14da7783a.zip
external_llvm-059800f9e3fee2852672f846d91a2da14da7783a.tar.gz
external_llvm-059800f9e3fee2852672f846d91a2da14da7783a.tar.bz2
Merge remote-tracking branch 'upstream/master' into merge-llvm
Conflicts: lib/CodeGen/AsmPrinter/AsmPrinter.cpp lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp lib/MC/MCAssembler.cpp lib/Support/Atomic.cpp lib/Support/Memory.cpp lib/Target/ARM/ARMJITInfo.cpp Change-Id: Ib339baf88df5b04870c8df1bedcfe1f877ccab8d
Diffstat (limited to 'lib/Target/Hexagon')
-rw-r--r--lib/Target/Hexagon/CMakeLists.txt4
-rw-r--r--lib/Target/Hexagon/Hexagon.td101
-rw-r--r--lib/Target/Hexagon/HexagonAsmPrinter.cpp32
-rw-r--r--[-rwxr-xr-x]lib/Target/Hexagon/HexagonAsmPrinter.h0
-rw-r--r--lib/Target/Hexagon/HexagonCFGOptimizer.cpp11
-rw-r--r--lib/Target/Hexagon/HexagonCallingConvLower.cpp6
-rw-r--r--lib/Target/Hexagon/HexagonCallingConvLower.h4
-rw-r--r--lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp11
-rw-r--r--lib/Target/Hexagon/HexagonFrameLowering.cpp17
-rw-r--r--lib/Target/Hexagon/HexagonHardwareLoops.cpp27
-rw-r--r--lib/Target/Hexagon/HexagonISelDAGToDAG.cpp14
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.cpp22
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.h13
-rw-r--r--lib/Target/Hexagon/HexagonImmediates.td508
-rw-r--r--lib/Target/Hexagon/HexagonInstrFormats.td73
-rw-r--r--lib/Target/Hexagon/HexagonInstrFormatsV4.td9
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.cpp54
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.h2
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.td1774
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfoV4.td1871
-rw-r--r--lib/Target/Hexagon/HexagonMCInst.h2
-rw-r--r--lib/Target/Hexagon/HexagonMCInstLower.cpp2
-rw-r--r--lib/Target/Hexagon/HexagonMachineScheduler.cpp364
-rw-r--r--lib/Target/Hexagon/HexagonMachineScheduler.h253
-rw-r--r--lib/Target/Hexagon/HexagonNewValueJump.cpp34
-rw-r--r--lib/Target/Hexagon/HexagonOperands.td858
-rw-r--r--lib/Target/Hexagon/HexagonPeephole.cpp8
-rw-r--r--lib/Target/Hexagon/HexagonRegisterInfo.cpp14
-rw-r--r--lib/Target/Hexagon/HexagonRegisterInfo.h2
-rw-r--r--lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp9
-rw-r--r--lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp13
-rw-r--r--lib/Target/Hexagon/HexagonSubtarget.h2
-rw-r--r--lib/Target/Hexagon/HexagonTargetMachine.cpp10
-rw-r--r--lib/Target/Hexagon/HexagonTargetMachine.h12
-rw-r--r--lib/Target/Hexagon/HexagonTargetObjectFile.cpp12
-rw-r--r--lib/Target/Hexagon/HexagonVLIWPacketizer.cpp51
-rw-r--r--lib/Target/Hexagon/HexagonVarargsCallingConvention.h8
-rw-r--r--lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp6
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h63
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp2
-rw-r--r--lib/Target/Hexagon/TargetInfo/HexagonTargetInfo.cpp2
41 files changed, 2478 insertions, 3802 deletions
diff --git a/lib/Target/Hexagon/CMakeLists.txt b/lib/Target/Hexagon/CMakeLists.txt
index 306084b..aee43ba 100644
--- a/lib/Target/Hexagon/CMakeLists.txt
+++ b/lib/Target/Hexagon/CMakeLists.txt
@@ -9,6 +9,8 @@ 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
@@ -33,8 +35,6 @@ add_llvm_target(HexagonCodeGen
HexagonNewValueJump.cpp
)
-add_dependencies(LLVMHexagonCodeGen intrinsics_gen)
-
add_subdirectory(TargetInfo)
add_subdirectory(InstPrinter)
add_subdirectory(MCTargetDesc)
diff --git a/lib/Target/Hexagon/Hexagon.td b/lib/Target/Hexagon/Hexagon.td
index 451e562..8a5ee40 100644
--- a/lib/Target/Hexagon/Hexagon.td
+++ b/lib/Target/Hexagon/Hexagon.td
@@ -32,6 +32,107 @@ def ArchV5 : SubtargetFeature<"v5", "HexagonArchVersion", "V5",
"Hexagon v5">;
//===----------------------------------------------------------------------===//
+// Hexagon Instruction Predicate Definitions.
+//===----------------------------------------------------------------------===//
+def HasV2T : Predicate<"Subtarget.hasV2TOps()">;
+def HasV2TOnly : Predicate<"Subtarget.hasV2TOpsOnly()">;
+def NoV2T : Predicate<"!Subtarget.hasV2TOps()">;
+def HasV3T : Predicate<"Subtarget.hasV3TOps()">;
+def HasV3TOnly : Predicate<"Subtarget.hasV3TOpsOnly()">;
+def NoV3T : Predicate<"!Subtarget.hasV3TOps()">;
+def HasV4T : Predicate<"Subtarget.hasV4TOps()">;
+def NoV4T : Predicate<"!Subtarget.hasV4TOps()">;
+def HasV5T : Predicate<"Subtarget.hasV5TOps()">;
+def NoV5T : Predicate<"!Subtarget.hasV5TOps()">;
+def UseMEMOP : Predicate<"Subtarget.useMemOps()">;
+def IEEERndNearV5T : Predicate<"Subtarget.modeIEEERndNear()">;
+
+//===----------------------------------------------------------------------===//
+// Classes used for relation maps.
+//===----------------------------------------------------------------------===//
+// PredRel - Filter class used to relate non-predicated instructions with their
+// predicated forms.
+class PredRel;
+// PredNewRel - Filter class used to relate predicated instructions with their
+// predicate-new forms.
+class PredNewRel: PredRel;
+// ImmRegRel - Filter class used to relate instructions having reg-reg form
+// with their reg-imm counterparts.
+class ImmRegRel;
+// NewValueRel - Filter class used to relate regular store instructions with
+// their new-value store form.
+class NewValueRel: PredNewRel;
+// NewValueRel - Filter class used to relate load/store instructions having
+// different addressing modes with each other.
+class AddrModeRel: NewValueRel;
+
+//===----------------------------------------------------------------------===//
+// Generate mapping table to relate non-predicate instructions with their
+// predicated formats - true and false.
+//
+
+def getPredOpcode : InstrMapping {
+ let FilterClass = "PredRel";
+ // Instructions with the same BaseOpcode and isNVStore values form a row.
+ let RowFields = ["BaseOpcode", "isNVStore", "PNewValue"];
+ // Instructions with the same predicate sense form a column.
+ let ColFields = ["PredSense"];
+ // The key column is the unpredicated instructions.
+ let KeyCol = [""];
+ // Value columns are PredSense=true and PredSense=false
+ let ValueCols = [["true"], ["false"]];
+}
+
+//===----------------------------------------------------------------------===//
+// Generate mapping table to relate predicated instructions with their .new
+// format.
+//
+def getPredNewOpcode : InstrMapping {
+ let FilterClass = "PredNewRel";
+ let RowFields = ["BaseOpcode", "PredSense", "isNVStore"];
+ let ColFields = ["PNewValue"];
+ let KeyCol = [""];
+ let ValueCols = [["new"]];
+}
+
+//===----------------------------------------------------------------------===//
+// 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"]];
+}
+
+def getBasedWithImmOffset : InstrMapping {
+ let FilterClass = "AddrModeRel";
+ let RowFields = ["CextOpcode", "PredSense", "PNewValue", "isNVStore",
+ "isMEMri", "isFloat"];
+ let ColFields = ["addrMode"];
+ let KeyCol = ["Absolute"];
+ let ValueCols = [["BaseImmOffset"]];
+}
+
+def getBaseWithRegOffset : InstrMapping {
+ let FilterClass = "AddrModeRel";
+ let RowFields = ["CextOpcode", "PredSense", "PNewValue", "isNVStore"];
+ let ColFields = ["addrMode"];
+ let KeyCol = ["BaseImmOffset"];
+ let ValueCols = [["BaseRegOffset"]];
+}
+
+def getRegForm : InstrMapping {
+ let FilterClass = "ImmRegRel";
+ let RowFields = ["CextOpcode", "PredSense", "PNewValue"];
+ let ColFields = ["InputType"];
+ let KeyCol = ["imm"];
+ let ValueCols = [["reg"]];
+}
+
+//===----------------------------------------------------------------------===//
// Register File, Calling Conv, Instruction Descriptions
//===----------------------------------------------------------------------===//
include "HexagonSchedule.td"
diff --git a/lib/Target/Hexagon/HexagonAsmPrinter.cpp b/lib/Target/Hexagon/HexagonAsmPrinter.cpp
index 5fa4740..58b89d1 100644
--- a/lib/Target/Hexagon/HexagonAsmPrinter.cpp
+++ b/lib/Target/Hexagon/HexagonAsmPrinter.cpp
@@ -14,23 +14,27 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "asm-printer"
-#include "Hexagon.h"
#include "HexagonAsmPrinter.h"
-#include "HexagonMachineFunctionInfo.h"
+#include "Hexagon.h"
#include "HexagonMCInst.h"
-#include "HexagonTargetMachine.h"
+#include "HexagonMachineFunctionInfo.h"
#include "HexagonSubtarget.h"
+#include "HexagonTargetMachine.h"
#include "InstPrinter/HexagonInstPrinter.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Module.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
@@ -38,22 +42,18 @@
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/Support/MathExtras.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/Mangler.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
-#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
diff --git a/lib/Target/Hexagon/HexagonAsmPrinter.h b/lib/Target/Hexagon/HexagonAsmPrinter.h
index bc2af63..bc2af63 100755..100644
--- a/lib/Target/Hexagon/HexagonAsmPrinter.h
+++ b/lib/Target/Hexagon/HexagonAsmPrinter.h
diff --git a/lib/Target/Hexagon/HexagonCFGOptimizer.cpp b/lib/Target/Hexagon/HexagonCFGOptimizer.cpp
index 9bca9e0..d4078ad 100644
--- a/lib/Target/Hexagon/HexagonCFGOptimizer.cpp
+++ b/lib/Target/Hexagon/HexagonCFGOptimizer.cpp
@@ -7,21 +7,22 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "hexagon_cfg"
-#include "HexagonTargetMachine.h"
-#include "HexagonSubtarget.h"
+#include "Hexagon.h"
#include "HexagonMachineFunctionInfo.h"
+#include "HexagonSubtarget.h"
+#include "HexagonTargetMachine.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.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/Support/MathExtras.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
diff --git a/lib/Target/Hexagon/HexagonCallingConvLower.cpp b/lib/Target/Hexagon/HexagonCallingConvLower.cpp
index ba8e679..2c93d04 100644
--- a/lib/Target/Hexagon/HexagonCallingConvLower.cpp
+++ b/lib/Target/Hexagon/HexagonCallingConvLower.cpp
@@ -15,12 +15,12 @@
#include "HexagonCallingConvLower.h"
#include "Hexagon.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetMachine.h"
+#include "llvm/IR/DataLayout.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
Hexagon_CCState::Hexagon_CCState(CallingConv::ID CC, bool isVarArg,
diff --git a/lib/Target/Hexagon/HexagonCallingConvLower.h b/lib/Target/Hexagon/HexagonCallingConvLower.h
index 1f601e8..489b3a3 100644
--- a/lib/Target/Hexagon/HexagonCallingConvLower.h
+++ b/lib/Target/Hexagon/HexagonCallingConvLower.h
@@ -17,9 +17,9 @@
#define LLVM_Hexagon_CODEGEN_CALLINGCONVLOWER_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/ValueTypes.h"
-#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/CodeGen/CallingConvLower.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/ValueTypes.h"
//
// Need to handle varargs.
diff --git a/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp b/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp
index ae2ca37..0814421 100644
--- a/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp
+++ b/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp
@@ -17,9 +17,10 @@
//
//===----------------------------------------------------------------------===//
-#include "HexagonTargetMachine.h"
-#include "HexagonSubtarget.h"
+#include "Hexagon.h"
#include "HexagonMachineFunctionInfo.h"
+#include "HexagonSubtarget.h"
+#include "HexagonTargetMachine.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/LatencyPriorityQueue.h"
#include "llvm/CodeGen/MachineDominators.h"
@@ -30,12 +31,12 @@
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
#include "llvm/CodeGen/SchedulerRegistry.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/Support/MathExtras.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
diff --git a/lib/Target/Hexagon/HexagonFrameLowering.cpp b/lib/Target/Hexagon/HexagonFrameLowering.cpp
index cd682df..9043cf9 100644
--- a/lib/Target/Hexagon/HexagonFrameLowering.cpp
+++ b/lib/Target/Hexagon/HexagonFrameLowering.cpp
@@ -11,28 +11,28 @@
#include "HexagonFrameLowering.h"
#include "Hexagon.h"
#include "HexagonInstrInfo.h"
+#include "HexagonMachineFunctionInfo.h"
#include "HexagonRegisterInfo.h"
#include "HexagonSubtarget.h"
#include "HexagonTargetMachine.h"
-#include "HexagonMachineFunctionInfo.h"
-#include "llvm/Function.h"
-#include "llvm/Type.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
-#include "llvm/MC/MachineLocation.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Type.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MachineLocation.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Support/CommandLine.h"
using namespace llvm;
@@ -166,7 +166,8 @@ bool HexagonFrameLowering::hasTailCall(MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
unsigned RetOpcode = MBBI->getOpcode();
- return RetOpcode == Hexagon::TCRETURNtg || RetOpcode == Hexagon::TCRETURNtext;}
+ return RetOpcode == Hexagon::TCRETURNtg || RetOpcode == Hexagon::TCRETURNtext;
+}
void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
diff --git a/lib/Target/Hexagon/HexagonHardwareLoops.cpp b/lib/Target/Hexagon/HexagonHardwareLoops.cpp
index d756aec..2a00a9f 100644
--- a/lib/Target/Hexagon/HexagonHardwareLoops.cpp
+++ b/lib/Target/Hexagon/HexagonHardwareLoops.cpp
@@ -29,18 +29,18 @@
#define DEBUG_TYPE "hwloops"
#include "Hexagon.h"
#include "HexagonTargetMachine.h"
-#include "llvm/Constants.h"
-#include "llvm/PassSupport.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/RegisterScavenging.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/PassSupport.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
@@ -461,6 +461,9 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L) {
return false;
}
MachineBasicBlock::iterator LastI = LastMBB->getFirstTerminator();
+ if (LastI == LastMBB->end()) {
+ return false;
+ }
// Determine the loop start.
MachineBasicBlock *LoopStart = L->getTopBlock();
@@ -478,6 +481,9 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L) {
// Convert the loop to a hardware loop
DEBUG(dbgs() << "Change to hardware loop at "; L->dump());
+ DebugLoc InsertPosDL;
+ if (InsertPos != Preheader->end())
+ InsertPosDL = InsertPos->getDebugLoc();
if (TripCount->isReg()) {
// Create a copy of the loop count register.
@@ -485,23 +491,23 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L) {
const TargetRegisterClass *RC =
MF->getRegInfo().getRegClass(TripCount->getReg());
unsigned CountReg = MF->getRegInfo().createVirtualRegister(RC);
- BuildMI(*Preheader, InsertPos, InsertPos->getDebugLoc(),
+ BuildMI(*Preheader, InsertPos, InsertPosDL,
TII->get(TargetOpcode::COPY), CountReg).addReg(TripCount->getReg());
if (TripCount->isNeg()) {
unsigned CountReg1 = CountReg;
CountReg = MF->getRegInfo().createVirtualRegister(RC);
- BuildMI(*Preheader, InsertPos, InsertPos->getDebugLoc(),
+ BuildMI(*Preheader, InsertPos, InsertPosDL,
TII->get(Hexagon::NEG), CountReg).addReg(CountReg1);
}
// Add the Loop instruction to the beginning of the loop.
- BuildMI(*Preheader, InsertPos, InsertPos->getDebugLoc(),
+ BuildMI(*Preheader, InsertPos, InsertPosDL,
TII->get(Hexagon::LOOP0_r)).addMBB(LoopStart).addReg(CountReg);
} else {
assert(TripCount->isImm() && "Expecting immedate vaule for trip count");
// Add the Loop immediate instruction to the beginning of the loop.
int64_t CountImm = TripCount->getImm();
- BuildMI(*Preheader, InsertPos, InsertPos->getDebugLoc(),
+ BuildMI(*Preheader, InsertPos, InsertPosDL,
TII->get(Hexagon::LOOP0_i)).addMBB(LoopStart).addImm(CountImm);
}
@@ -514,8 +520,9 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L) {
BlockAddress::get(const_cast<BasicBlock *>(LoopStart->getBasicBlock()));
// Replace the loop branch with an endloop instruction.
- DebugLoc dl = LastI->getDebugLoc();
- BuildMI(*LastMBB, LastI, dl, TII->get(Hexagon::ENDLOOP0)).addMBB(LoopStart);
+ DebugLoc LastIDL = LastI->getDebugLoc();
+ BuildMI(*LastMBB, LastI, LastIDL,
+ TII->get(Hexagon::ENDLOOP0)).addMBB(LoopStart);
// The loop ends with either:
// - a conditional branch followed by an unconditional branch, or
@@ -530,7 +537,7 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L) {
TII->RemoveBranch(*LastMBB);
}
SmallVector<MachineOperand, 0> Cond;
- TII->InsertBranch(*LastMBB, BranchTarget, 0, Cond, dl);
+ TII->InsertBranch(*LastMBB, BranchTarget, 0, Cond, LastIDL);
}
} else {
// Conditional branch to loop start; just delete it.
diff --git a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
index 5499134..db292f2 100644
--- a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
+++ b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
@@ -12,10 +12,11 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "hexagon-isel"
+#include "Hexagon.h"
#include "HexagonISelLowering.h"
#include "HexagonTargetMachine.h"
-#include "llvm/Intrinsics.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
@@ -94,6 +95,7 @@ public:
SDNode *SelectConstant(SDNode *N);
SDNode *SelectConstantFP(SDNode *N);
SDNode *SelectAdd(SDNode *N);
+ bool isConstExtProfitable(SDNode *N) const;
// Include the pieces autogenerated from the target description.
#include "HexagonGenDAGISel.inc"
@@ -1507,3 +1509,13 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
OutOps.push_back(Op1);
return false;
}
+
+bool HexagonDAGToDAGISel::isConstExtProfitable(SDNode *N) const {
+ unsigned UseCount = 0;
+ for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
+ UseCount++;
+ }
+
+ return (UseCount <= 1);
+
+}
diff --git a/lib/Target/Hexagon/HexagonISelLowering.cpp b/lib/Target/Hexagon/HexagonISelLowering.cpp
index 703a128..16cec5c 100644
--- a/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -13,17 +13,10 @@
//===----------------------------------------------------------------------===//
#include "HexagonISelLowering.h"
-#include "HexagonTargetMachine.h"
#include "HexagonMachineFunctionInfo.h"
-#include "HexagonTargetObjectFile.h"
#include "HexagonSubtarget.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/InlineAsm.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/GlobalAlias.h"
-#include "llvm/Intrinsics.h"
-#include "llvm/CallingConv.h"
+#include "HexagonTargetMachine.h"
+#include "HexagonTargetObjectFile.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -32,6 +25,13 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalAlias.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -608,7 +608,7 @@ static bool getIndexedAddressParts(SDNode *Ptr, EVT VT,
// TODO: Put this function along with the other isS* functions in
// HexagonISelDAGToDAG.cpp into a common file. Or better still, use the
-// functions defined in HexagonImmediates.td.
+// functions defined in HexagonOperands.td.
static bool Is_PostInc_S4_Offset(SDNode * S, int ShiftAmount) {
ConstantSDNode *N = cast<ConstantSDNode>(S);
@@ -1350,6 +1350,8 @@ HexagonTargetLowering::HexagonTargetLowering(HexagonTargetMachine
} else {
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
}
+ // Increase jump tables cutover to 5, was 4.
+ setMinimumJumpTableEntries(5);
setOperationAction(ISD::BR_CC, MVT::i32, Expand);
diff --git a/lib/Target/Hexagon/HexagonISelLowering.h b/lib/Target/Hexagon/HexagonISelLowering.h
index fe6c905..5a415eb 100644
--- a/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/lib/Target/Hexagon/HexagonISelLowering.h
@@ -16,9 +16,9 @@
#define Hexagon_ISELLOWERING_H
#include "Hexagon.h"
-#include "llvm/Target/TargetLowering.h"
-#include "llvm/CallingConv.h"
#include "llvm/CodeGen/CallingConvLower.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/Target/TargetLowering.h"
namespace llvm {
namespace HexagonISD {
@@ -50,6 +50,15 @@ namespace llvm {
BARRIER, // Memory barrier.
WrapperJT,
WrapperCP,
+ WrapperCombineII,
+ WrapperCombineRR,
+ WrapperPackhl,
+ WrapperSplatB,
+ WrapperSplatH,
+ WrapperShuffEB,
+ WrapperShuffEH,
+ WrapperShuffOB,
+ WrapperShuffOH,
TC_RETURN
};
}
diff --git a/lib/Target/Hexagon/HexagonImmediates.td b/lib/Target/Hexagon/HexagonImmediates.td
deleted file mode 100644
index 18692c4..0000000
--- a/lib/Target/Hexagon/HexagonImmediates.td
+++ /dev/null
@@ -1,508 +0,0 @@
-//===- HexagonImmediates.td - Hexagon immediate processing -*- tablegen -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illnois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// From IA64's InstrInfo file
-def s32Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def s16Imm : Operand<i32> {
- let PrintMethod = "printImmOperand";
-}
-
-def s12Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def s11Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def s11_0Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def s11_1Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def s11_2Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def s11_3Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def s10Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def s9Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def s8Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def s8Imm64 : Operand<i64> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def s6Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def s4Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def s4_0Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def s4_1Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def s4_2Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def s4_3Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u64Imm : Operand<i64> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u32Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u16Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u16_0Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u16_1Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u16_2Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u11_3Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u10Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u9Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u8Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u7Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u6Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u6_0Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u6_1Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u6_2Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u6_3Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u5Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u4Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u3Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u2Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def u1Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def n8Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def m6Imm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printImmOperand";
-}
-
-def nOneImm : Operand<i32> {
- // For now, we use a generic print function for all operands.
- let PrintMethod = "printNOneImmOperand";
-}
-
-//
-// Immediate predicates
-//
-def s32ImmPred : PatLeaf<(i32 imm), [{
- // immS16 predicate - True if the immediate fits in a 16-bit sign extended
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isInt<32>(v);
-}]>;
-
-def s32_24ImmPred : PatLeaf<(i32 imm), [{
- // s32_24ImmPred predicate - True if the immediate fits in a 32-bit sign
- // extended field that is a multiple of 0x1000000.
- int64_t v = (int64_t)N->getSExtValue();
- return isShiftedInt<32,24>(v);
-}]>;
-
-def s32_16s8ImmPred : PatLeaf<(i32 imm), [{
- // s32_16s8ImmPred predicate - True if the immediate fits in a 32-bit sign
- // extended field that is a multiple of 0x10000.
- int64_t v = (int64_t)N->getSExtValue();
- return isShiftedInt<24,16>(v);
-}]>;
-
-def s16ImmPred : PatLeaf<(i32 imm), [{
- // immS16 predicate - True if the immediate fits in a 16-bit sign extended
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isInt<16>(v);
-}]>;
-
-
-def s13ImmPred : PatLeaf<(i32 imm), [{
- // immS13 predicate - True if the immediate fits in a 13-bit sign extended
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isInt<13>(v);
-}]>;
-
-
-def s12ImmPred : PatLeaf<(i32 imm), [{
- // immS16 predicate - True if the immediate fits in a 16-bit sign extended
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isInt<12>(v);
-}]>;
-
-def s11_0ImmPred : PatLeaf<(i32 imm), [{
- // immS16 predicate - True if the immediate fits in a 16-bit sign extended
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isInt<11>(v);
-}]>;
-
-
-def s11_1ImmPred : PatLeaf<(i32 imm), [{
- // immS16 predicate - True if the immediate fits in a 16-bit sign extended
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isShiftedInt<11,1>(v);
-}]>;
-
-
-def s11_2ImmPred : PatLeaf<(i32 imm), [{
- // immS16 predicate - True if the immediate fits in a 16-bit sign extended
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isShiftedInt<11,2>(v);
-}]>;
-
-
-def s11_3ImmPred : PatLeaf<(i32 imm), [{
- // immS16 predicate - True if the immediate fits in a 16-bit sign extended
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isShiftedInt<11,3>(v);
-}]>;
-
-
-def s10ImmPred : PatLeaf<(i32 imm), [{
- // s10ImmPred predicate - True if the immediate fits in a 10-bit sign extended
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isInt<10>(v);
-}]>;
-
-
-def s9ImmPred : PatLeaf<(i32 imm), [{
- // s9ImmPred predicate - True if the immediate fits in a 9-bit sign extended
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isInt<9>(v);
-}]>;
-
-
-def s8ImmPred : PatLeaf<(i32 imm), [{
- // s8ImmPred predicate - True if the immediate fits in a 8-bit sign extended
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isInt<8>(v);
-}]>;
-
-
-def s8Imm64Pred : PatLeaf<(i64 imm), [{
- // s8ImmPred predicate - True if the immediate fits in a 8-bit sign extended
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isInt<8>(v);
-}]>;
-
-
-def s6ImmPred : PatLeaf<(i32 imm), [{
- // s6ImmPred predicate - True if the immediate fits in a 6-bit sign extended
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isInt<6>(v);
-}]>;
-
-
-def s4_0ImmPred : PatLeaf<(i32 imm), [{
- // s4_0ImmPred predicate - True if the immediate fits in a 4-bit sign extended
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isInt<4>(v);
-}]>;
-
-
-def s4_1ImmPred : PatLeaf<(i32 imm), [{
- // s4_1ImmPred predicate - True if the immediate fits in a 4-bit sign extended
- // field of 2.
- int64_t v = (int64_t)N->getSExtValue();
- return isShiftedInt<4,1>(v);
-}]>;
-
-
-def s4_2ImmPred : PatLeaf<(i32 imm), [{
- // s4_2ImmPred predicate - True if the immediate fits in a 4-bit sign extended
- // field that is a multiple of 4.
- int64_t v = (int64_t)N->getSExtValue();
- return isShiftedInt<4,2>(v);
-}]>;
-
-
-def s4_3ImmPred : PatLeaf<(i32 imm), [{
- // s4_3ImmPred predicate - True if the immediate fits in a 4-bit sign extended
- // field that is a multiple of 8.
- int64_t v = (int64_t)N->getSExtValue();
- return isShiftedInt<4,3>(v);
-}]>;
-
-
-def u64ImmPred : PatLeaf<(i64 imm), [{
- // immS16 predicate - True if the immediate fits in a 16-bit sign extended
- // field.
- // Adding "N ||" to suppress gcc unused warning.
- return (N || true);
-}]>;
-
-def u32ImmPred : PatLeaf<(i32 imm), [{
- // immS16 predicate - True if the immediate fits in a 16-bit sign extended
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isUInt<32>(v);
-}]>;
-
-def u16ImmPred : PatLeaf<(i32 imm), [{
- // u16ImmPred predicate - True if the immediate fits in a 16-bit unsigned
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isUInt<16>(v);
-}]>;
-
-def u16_s8ImmPred : PatLeaf<(i32 imm), [{
- // u16_s8ImmPred predicate - True if the immediate fits in a 16-bit sign
- // extended s8 field.
- int64_t v = (int64_t)N->getSExtValue();
- return isShiftedUInt<16,8>(v);
-}]>;
-
-def u9ImmPred : PatLeaf<(i32 imm), [{
- // u9ImmPred predicate - True if the immediate fits in a 9-bit unsigned
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isUInt<9>(v);
-}]>;
-
-
-def u8ImmPred : PatLeaf<(i32 imm), [{
- // u8ImmPred predicate - True if the immediate fits in a 8-bit unsigned
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isUInt<8>(v);
-}]>;
-
-def u7ImmPred : PatLeaf<(i32 imm), [{
- // u7ImmPred predicate - True if the immediate fits in a 8-bit unsigned
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isUInt<7>(v);
-}]>;
-
-
-def u6ImmPred : PatLeaf<(i32 imm), [{
- // u6ImmPred predicate - True if the immediate fits in a 6-bit unsigned
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isUInt<6>(v);
-}]>;
-
-def u6_0ImmPred : PatLeaf<(i32 imm), [{
- // u6_0ImmPred predicate - True if the immediate fits in a 6-bit unsigned
- // field. Same as u6ImmPred.
- int64_t v = (int64_t)N->getSExtValue();
- return isUInt<6>(v);
-}]>;
-
-def u6_1ImmPred : PatLeaf<(i32 imm), [{
- // u6_1ImmPred predicate - True if the immediate fits in a 6-bit unsigned
- // field that is 1 bit alinged - multiple of 2.
- int64_t v = (int64_t)N->getSExtValue();
- return isShiftedUInt<6,1>(v);
-}]>;
-
-def u6_2ImmPred : PatLeaf<(i32 imm), [{
- // u6_2ImmPred predicate - True if the immediate fits in a 6-bit unsigned
- // field that is 2 bits alinged - multiple of 4.
- int64_t v = (int64_t)N->getSExtValue();
- return isShiftedUInt<6,2>(v);
-}]>;
-
-def u6_3ImmPred : PatLeaf<(i32 imm), [{
- // u6_3ImmPred predicate - True if the immediate fits in a 6-bit unsigned
- // field that is 3 bits alinged - multiple of 8.
- int64_t v = (int64_t)N->getSExtValue();
- return isShiftedUInt<6,3>(v);
-}]>;
-
-def u5ImmPred : PatLeaf<(i32 imm), [{
- // u5ImmPred predicate - True if the immediate fits in a 5-bit unsigned
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isUInt<5>(v);
-}]>;
-
-
-def u3ImmPred : PatLeaf<(i32 imm), [{
- // u3ImmPred predicate - True if the immediate fits in a 3-bit unsigned
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isUInt<3>(v);
-}]>;
-
-
-def u2ImmPred : PatLeaf<(i32 imm), [{
- // u2ImmPred predicate - True if the immediate fits in a 2-bit unsigned
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isUInt<2>(v);
-}]>;
-
-
-def u1ImmPred : PatLeaf<(i1 imm), [{
- // u1ImmPred predicate - True if the immediate fits in a 1-bit unsigned
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return isUInt<1>(v);
-}]>;
-
-def m6ImmPred : PatLeaf<(i32 imm), [{
- // m6ImmPred predicate - True if the immediate is negative and fits in
- // a 6-bit negative number.
- int64_t v = (int64_t)N->getSExtValue();
- return isInt<6>(v);
-}]>;
-
-//InN means negative integers in [-(2^N - 1), 0]
-def n8ImmPred : PatLeaf<(i32 imm), [{
- // n8ImmPred predicate - True if the immediate fits in a 8-bit signed
- // field.
- int64_t v = (int64_t)N->getSExtValue();
- return (-255 <= v && v <= 0);
-}]>;
-
-def nOneImmPred : PatLeaf<(i32 imm), [{
- // nOneImmPred predicate - True if the immediate is -1.
- int64_t v = (int64_t)N->getSExtValue();
- return (-1 == v);
-}]>;
-
diff --git a/lib/Target/Hexagon/HexagonInstrFormats.td b/lib/Target/Hexagon/HexagonInstrFormats.td
index e472d49..71c620b 100644
--- a/lib/Target/Hexagon/HexagonInstrFormats.td
+++ b/lib/Target/Hexagon/HexagonInstrFormats.td
@@ -27,6 +27,34 @@ def TypeSYSTEM : Type<7>;
def TypeXTYPE : Type<8>;
def TypeMARKER : Type<31>;
+// Maintain list of valid subtargets for each instruction.
+class SubTarget<bits<4> value> {
+ bits<4> Value = value;
+}
+
+def HasV2SubT : SubTarget<0xf>;
+def HasV2SubTOnly : SubTarget<0x1>;
+def NoV2SubT : SubTarget<0x0>;
+def HasV3SubT : SubTarget<0xe>;
+def HasV3SubTOnly : SubTarget<0x2>;
+def NoV3SubT : SubTarget<0x1>;
+def HasV4SubT : SubTarget<0xc>;
+def NoV4SubT : SubTarget<0x3>;
+def HasV5SubT : SubTarget<0x8>;
+def NoV5SubT : SubTarget<0x7>;
+
+// Addressing modes for load/store instructions
+class AddrModeType<bits<4> value> {
+ bits<4> Value = value;
+}
+
+def NoAddrMode : AddrModeType<0>; // No addressing mode
+def Absolute : AddrModeType<1>; // Absolute addressing mode
+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
+
//===----------------------------------------------------------------------===//
// Intruction Class Declaration +
//===----------------------------------------------------------------------===//
@@ -55,8 +83,49 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern,
// Predicated instructions.
bits<1> isPredicated = 0;
let TSFlags{6} = isPredicated;
-
- // *** The code above must match HexagonBaseInfo.h ***
+ bits<1> isPredicatedNew = 0;
+ let TSFlags{7} = isPredicatedNew;
+
+ // Stores that can be newified.
+ bits<1> isNVStorable = 0;
+ let TSFlags{8} = isNVStorable;
+
+ // New-value store instructions.
+ bits<1> isNVStore = 0;
+ let TSFlags{9} = isNVStore;
+
+ // Immediate extender helper fields.
+ bits<1> isExtendable = 0;
+ let TSFlags{10} = isExtendable; // Insn may be extended.
+ bits<1> isExtended = 0;
+ let TSFlags{11} = isExtended; // Insn must be extended.
+ bits<3> opExtendable = 0;
+ let TSFlags{14-12} = opExtendable; // Which operand may be extended.
+ bits<1> isExtentSigned = 0;
+ let TSFlags{15} = isExtentSigned; // Signed or unsigned range.
+ bits<5> opExtentBits = 0;
+ let TSFlags{20-16} = opExtentBits; //Number of bits of range before extending.
+
+ // If an instruction is valid on a subtarget (v2-v5), set the corresponding
+ // bit from validSubTargets. v2 is the least significant bit.
+ // By default, instruction is valid on all subtargets.
+ SubTarget validSubTargets = HasV2SubT;
+ let TSFlags{24-21} = validSubTargets.Value;
+
+ // Addressing mode for load/store instrutions.
+ AddrModeType addrMode = NoAddrMode;
+ let TSFlags{28-25} = addrMode.Value;
+
+ // Fields used for relation models.
+ string BaseOpcode = "";
+ string CextOpcode = "";
+ string PredSense = "";
+ string PNewValue = "";
+ 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.
+
+ // *** Must match MCTargetDesc/HexagonBaseInfo.h ***
}
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/Hexagon/HexagonInstrFormatsV4.td b/lib/Target/Hexagon/HexagonInstrFormatsV4.td
index 49741a3..05f1e23 100644
--- a/lib/Target/Hexagon/HexagonInstrFormatsV4.td
+++ b/lib/Target/Hexagon/HexagonInstrFormatsV4.td
@@ -59,9 +59,6 @@ class MEMInst_V4<dag outs, dag ins, string asmstr, list<dag> pattern>
bits<6> imm6;
}
-class Immext<dag outs, dag ins, string asmstr, list<dag> pattern>
- : InstHexagon<outs, ins, asmstr, pattern, "", PREFIX, TypePREFIX> {
- let isCodeGenOnly = 1;
-
- bits<26> imm26;
-}
+let isCodeGenOnly = 1 in
+class EXTENDERInst<dag outs, dag ins, string asmstr, list<dag> pattern = []>
+ : InstHexagon<outs, ins, asmstr, pattern, "", PREFIX, TypePREFIX>;
diff --git a/lib/Target/Hexagon/HexagonInstrInfo.cpp b/lib/Target/Hexagon/HexagonInstrInfo.cpp
index c8f933d..3b1ae09 100644
--- a/lib/Target/Hexagon/HexagonInstrInfo.cpp
+++ b/lib/Target/Hexagon/HexagonInstrInfo.cpp
@@ -12,19 +12,20 @@
//===----------------------------------------------------------------------===//
#include "HexagonInstrInfo.h"
+#include "Hexagon.h"
#include "HexagonRegisterInfo.h"
#include "HexagonSubtarget.h"
-#include "Hexagon.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/DFAPacketizer.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/Support/MathExtras.h"
#define GET_INSTRINFO_CTOR
+#define GET_INSTRMAP_INFO
#include "HexagonGenInstrInfo.inc"
#include "HexagonGenDFAPacketizer.inc"
@@ -313,7 +314,7 @@ void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
return;
}
if (Hexagon::DoubleRegsRegClass.contains(SrcReg, DestReg)) {
- BuildMI(MBB, I, DL, get(Hexagon::TFR_64), DestReg).addReg(SrcReg);
+ BuildMI(MBB, I, DL, get(Hexagon::TFR64), DestReg).addReg(SrcReg);
return;
}
if (Hexagon::PredRegsRegClass.contains(SrcReg, DestReg)) {
@@ -940,42 +941,36 @@ unsigned HexagonInstrInfo::getImmExtForm(const MachineInstr* MI) const {
case Hexagon::TFR_FI:
return Hexagon::TFR_FI_immext_V4;
- case Hexagon::MEMw_ADDSUBi_indexed_MEM_V4 :
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_ADDSUBi_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_ADDSUBi_indexed_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_ADDSUBi_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_ADDSUBi_indexed_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_ADDSUBi_MEM_V4 :
case Hexagon::MEMb_ADDi_MEM_V4 :
case Hexagon::MEMb_SUBi_MEM_V4 :
case Hexagon::MEMb_ADDr_MEM_V4 :
@@ -1915,6 +1910,15 @@ unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const {
int HexagonInstrInfo::
getMatchingCondBranchOpcode(int Opc, bool invertPredicate) const {
+ enum Hexagon::PredSense inPredSense;
+ inPredSense = invertPredicate ? Hexagon::PredSense_false :
+ Hexagon::PredSense_true;
+ int CondOpcode = Hexagon::getPredOpcode(Opc, inPredSense);
+ if (CondOpcode >= 0) // Valid Conditional opcode/instruction
+ return CondOpcode;
+
+ // 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 :
@@ -1934,24 +1938,6 @@ getMatchingCondBranchOpcode(int Opc, bool invertPredicate) const {
case Hexagon::JMP_EQriPt_nv_V4:
return !invertPredicate ? Hexagon::JMP_EQriPt_nv_V4 :
Hexagon::JMP_EQriNotPt_nv_V4;
- case Hexagon::ADD_ri:
- return !invertPredicate ? Hexagon::ADD_ri_cPt :
- Hexagon::ADD_ri_cNotPt;
- case Hexagon::ADD_rr:
- return !invertPredicate ? Hexagon::ADD_rr_cPt :
- Hexagon::ADD_rr_cNotPt;
- case Hexagon::XOR_rr:
- return !invertPredicate ? Hexagon::XOR_rr_cPt :
- Hexagon::XOR_rr_cNotPt;
- case Hexagon::AND_rr:
- return !invertPredicate ? Hexagon::AND_rr_cPt :
- Hexagon::AND_rr_cNotPt;
- case Hexagon::OR_rr:
- return !invertPredicate ? Hexagon::OR_rr_cPt :
- Hexagon::OR_rr_cNotPt;
- case Hexagon::SUB_rr:
- return !invertPredicate ? Hexagon::SUB_rr_cPt :
- Hexagon::SUB_rr_cNotPt;
case Hexagon::COMBINE_rr:
return !invertPredicate ? Hexagon::COMBINE_rr_cPt :
Hexagon::COMBINE_rr_cNotPt;
@@ -2399,14 +2385,12 @@ isValidOffset(const int Opcode, const int Offset) const {
return (Offset >= Hexagon_ADDI_OFFSET_MIN) &&
(Offset <= Hexagon_ADDI_OFFSET_MAX);
- case Hexagon::MEMw_ADDSUBi_indexed_MEM_V4 :
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_ADDSUBi_MEM_V4 :
case Hexagon::MEMw_ADDi_MEM_V4 :
case Hexagon::MEMw_SUBi_MEM_V4 :
case Hexagon::MEMw_ADDr_MEM_V4 :
@@ -2416,14 +2400,12 @@ isValidOffset(const int Opcode, const int Offset) const {
assert ((Offset % 4) == 0 && "MEMOPw offset is not aligned correctly." );
return (0 <= Offset && Offset <= 255);
- case Hexagon::MEMh_ADDSUBi_indexed_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_ADDSUBi_MEM_V4 :
case Hexagon::MEMh_ADDi_MEM_V4 :
case Hexagon::MEMh_SUBi_MEM_V4 :
case Hexagon::MEMh_ADDr_MEM_V4 :
@@ -2433,14 +2415,12 @@ isValidOffset(const int Opcode, const int Offset) const {
assert ((Offset % 2) == 0 && "MEMOPh offset is not aligned correctly." );
return (0 <= Offset && Offset <= 127);
- case Hexagon::MEMb_ADDSUBi_indexed_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_ADDSUBi_MEM_V4 :
case Hexagon::MEMb_ADDi_MEM_V4 :
case Hexagon::MEMb_SUBi_MEM_V4 :
case Hexagon::MEMb_ADDr_MEM_V4 :
@@ -2499,42 +2479,36 @@ isMemOp(const MachineInstr *MI) const {
switch (MI->getOpcode())
{
default: return false;
- case Hexagon::MEMw_ADDSUBi_indexed_MEM_V4 :
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_ADDSUBi_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_ADDSUBi_indexed_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_ADDSUBi_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_ADDSUBi_indexed_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_ADDSUBi_MEM_V4 :
case Hexagon::MEMb_ADDi_MEM_V4 :
case Hexagon::MEMb_SUBi_MEM_V4 :
case Hexagon::MEMb_ADDr_MEM_V4 :
diff --git a/lib/Target/Hexagon/HexagonInstrInfo.h b/lib/Target/Hexagon/HexagonInstrInfo.h
index 2bb53f8..29e3eb1 100644
--- a/lib/Target/Hexagon/HexagonInstrInfo.h
+++ b/lib/Target/Hexagon/HexagonInstrInfo.h
@@ -16,8 +16,8 @@
#include "HexagonRegisterInfo.h"
#include "MCTargetDesc/HexagonBaseInfo.h"
-#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetFrameLowering.h"
+#include "llvm/Target/TargetInstrInfo.h"
#define GET_INSTRINFO_HEADER
diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td
index c0c0df6..8b183b9 100644
--- a/lib/Target/Hexagon/HexagonInstrInfo.td
+++ b/lib/Target/Hexagon/HexagonInstrInfo.td
@@ -12,76 +12,7 @@
//===----------------------------------------------------------------------===//
include "HexagonInstrFormats.td"
-include "HexagonImmediates.td"
-
-//===----------------------------------------------------------------------===//
-// Hexagon Instruction Predicate Definitions.
-//===----------------------------------------------------------------------===//
-def HasV2T : Predicate<"Subtarget.hasV2TOps()">;
-def HasV2TOnly : Predicate<"Subtarget.hasV2TOpsOnly()">;
-def NoV2T : Predicate<"!Subtarget.hasV2TOps()">;
-def HasV3T : Predicate<"Subtarget.hasV3TOps()">;
-def HasV3TOnly : Predicate<"Subtarget.hasV3TOpsOnly()">;
-def NoV3T : Predicate<"!Subtarget.hasV3TOps()">;
-def HasV4T : Predicate<"Subtarget.hasV4TOps()">;
-def NoV4T : Predicate<"!Subtarget.hasV4TOps()">;
-def HasV5T : Predicate<"Subtarget.hasV5TOps()">;
-def NoV5T : Predicate<"!Subtarget.hasV5TOps()">;
-def UseMEMOP : Predicate<"Subtarget.useMemOps()">;
-def IEEERndNearV5T : Predicate<"Subtarget.modeIEEERndNear()">;
-
-// Addressing modes.
-def ADDRrr : ComplexPattern<i32, 2, "SelectADDRrr", [], []>;
-def ADDRri : ComplexPattern<i32, 2, "SelectADDRri", [frameindex], []>;
-def ADDRriS11_0 : ComplexPattern<i32, 2, "SelectADDRriS11_0", [frameindex], []>;
-def ADDRriS11_1 : ComplexPattern<i32, 2, "SelectADDRriS11_1", [frameindex], []>;
-def ADDRriS11_2 : ComplexPattern<i32, 2, "SelectADDRriS11_2", [frameindex], []>;
-def ADDRriS11_3 : ComplexPattern<i32, 2, "SelectADDRriS11_3", [frameindex], []>;
-def ADDRriU6_0 : ComplexPattern<i32, 2, "SelectADDRriU6_0", [frameindex], []>;
-def ADDRriU6_1 : ComplexPattern<i32, 2, "SelectADDRriU6_1", [frameindex], []>;
-def ADDRriU6_2 : ComplexPattern<i32, 2, "SelectADDRriU6_2", [frameindex], []>;
-
-// Address operands.
-def MEMrr : Operand<i32> {
- let PrintMethod = "printMEMrrOperand";
- let MIOperandInfo = (ops IntRegs, IntRegs);
-}
-
-// Address operands
-def MEMri : Operand<i32> {
- let PrintMethod = "printMEMriOperand";
- let MIOperandInfo = (ops IntRegs, IntRegs);
-}
-
-def MEMri_s11_2 : Operand<i32>,
- ComplexPattern<i32, 2, "SelectMEMriS11_2", []> {
- let PrintMethod = "printMEMriOperand";
- let MIOperandInfo = (ops IntRegs, s11Imm);
-}
-
-def FrameIndex : Operand<i32> {
- let PrintMethod = "printFrameIndexOperand";
- let MIOperandInfo = (ops IntRegs, s11Imm);
-}
-
-let PrintMethod = "printGlobalOperand" in
- def globaladdress : Operand<i32>;
-
-let PrintMethod = "printJumpTable" in
- def jumptablebase : Operand<i32>;
-
-def brtarget : Operand<OtherVT>;
-def calltarget : Operand<i32>;
-
-def bblabel : Operand<i32>;
-def bbl : SDNode<"ISD::BasicBlock", SDTPtrLeaf , [], "BasicBlockSDNode">;
-
-def symbolHi32 : Operand<i32> {
- let PrintMethod = "printSymbolHi";
-}
-def symbolLo32 : Operand<i32> {
- let PrintMethod = "printSymbolLo";
-}
+include "HexagonOperands.td"
// Multi-class for logical operators.
multiclass ALU32_rr_ri<string OpcStr, SDNode OpNode> {
@@ -110,100 +41,166 @@ multiclass CMP32_rr<string OpcStr, PatFrag OpNode> {
(OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>;
}
-multiclass CMP32_rr_ri_s10<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)))]>;
- def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s10Imm:$c),
- !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")),
- [(set (i1 PredRegs:$dst),
- (OpNode (i32 IntRegs:$b), s10ImmPred:$c))]>;
+multiclass CMP32_rr_ri_s10<string OpcStr, string CextOp, PatFrag OpNode> {
+ let CextOpcode = CextOp in {
+ let InputType = "reg" in
+ 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)))]>;
+
+ let isExtendable = 1, opExtendable = 2, isExtentSigned = 1,
+ opExtentBits = 10, InputType = "imm" in
+ def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s10Ext:$c),
+ !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")),
+ [(set (i1 PredRegs:$dst),
+ (OpNode (i32 IntRegs:$b), s10ExtPred:$c))]>;
+ }
}
-multiclass CMP32_rr_ri_u9<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)))]>;
- def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, u9Imm:$c),
- !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")),
- [(set (i1 PredRegs:$dst),
- (OpNode (i32 IntRegs:$b), u9ImmPred:$c))]>;
+multiclass CMP32_rr_ri_u9<string OpcStr, string CextOp, PatFrag OpNode> {
+ let CextOpcode = CextOp in {
+ let InputType = "reg" in
+ 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)))]>;
+
+ let isExtendable = 1, opExtendable = 2, isExtentSigned = 0,
+ opExtentBits = 9, InputType = "imm" in
+ def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, u9Ext:$c),
+ !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")),
+ [(set (i1 PredRegs:$dst),
+ (OpNode (i32 IntRegs:$b), u9ExtPred:$c))]>;
+ }
}
multiclass CMP32_ri_u8<string OpcStr, PatFrag OpNode> {
- def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, u8Imm:$c),
+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),
- u8ImmPred:$c))]>;
+ u8ExtPred:$c))]>;
}
multiclass CMP32_ri_s8<string OpcStr, PatFrag OpNode> {
- def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s8Imm:$c),
+let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8 in
+ def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s8Ext:$c),
!strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")),
[(set (i1 PredRegs:$dst), (OpNode (i32 IntRegs:$b),
- s8ImmPred:$c))]>;
+ s8ExtPred:$c))]>;
}
}
//===----------------------------------------------------------------------===//
-// ALU32/ALU +
+// ALU32/ALU (Instructions with register-register form)
//===----------------------------------------------------------------------===//
-// Add.
-let isCommutable = 1, isPredicable = 1 in
-def ADD_rr : ALU32_rr<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = add($src1, $src2)",
- [(set (i32 IntRegs:$dst), (add (i32 IntRegs:$src1),
- (i32 IntRegs:$src2)))]>;
+multiclass ALU32_Pbase<string mnemonic, bit isNot,
+ bit isPredNew> {
-let isPredicable = 1 in
-def ADD_ri : ALU32_ri<(outs IntRegs:$dst),
- (ins IntRegs:$src1, s16Imm:$src2),
- "$dst = add($src1, #$src2)",
- [(set (i32 IntRegs:$dst), (add (i32 IntRegs:$src1),
- s16ImmPred:$src2))]>;
+ let PNewValue = !if(isPredNew, "new", "") in
+ def NAME : ALU32_rr<(outs IntRegs:$dst),
+ (ins PredRegs:$src1, IntRegs:$src2, IntRegs: $src3),
+ !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ",
+ ") $dst = ")#mnemonic#"($src2, $src3)",
+ []>;
+}
-// Logical operations.
-let isPredicable = 1 in
-def XOR_rr : ALU32_rr<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = xor($src1, $src2)",
- [(set (i32 IntRegs:$dst), (xor (i32 IntRegs:$src1),
- (i32 IntRegs:$src2)))]>;
+multiclass ALU32_Pred<string mnemonic, bit PredNot> {
+ let PredSense = !if(PredNot, "false", "true") in {
+ defm _c#NAME : ALU32_Pbase<mnemonic, PredNot, 0>;
+ // Predicate new
+ defm _cdn#NAME : ALU32_Pbase<mnemonic, PredNot, 1>;
+ }
+}
-let isCommutable = 1, isPredicable = 1 in
-def AND_rr : ALU32_rr<(outs IntRegs:$dst),
+let InputType = "reg" in
+multiclass ALU32_base<string mnemonic, string CextOp, SDNode OpNode> {
+ let CextOpcode = CextOp, BaseOpcode = CextOp#_rr in {
+ let isPredicable = 1 in
+ def NAME : ALU32_rr<(outs IntRegs:$dst),
(ins IntRegs:$src1, IntRegs:$src2),
- "$dst = and($src1, $src2)",
- [(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1),
- (i32 IntRegs:$src2)))]>;
+ "$dst = "#mnemonic#"($src1, $src2)",
+ [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$src1),
+ (i32 IntRegs:$src2)))]>;
+
+ let neverHasSideEffects = 1, isPredicated = 1 in {
+ defm Pt : ALU32_Pred<mnemonic, 0>;
+ defm NotPt : ALU32_Pred<mnemonic, 1>;
+ }
+ }
+}
+
+let isCommutable = 1 in {
+ defm ADD_rr : ALU32_base<"add", "ADD", add>, ImmRegRel, PredNewRel;
+ defm AND_rr : ALU32_base<"and", "AND", and>, ImmRegRel, PredNewRel;
+ defm XOR_rr : ALU32_base<"xor", "XOR", xor>, ImmRegRel, PredNewRel;
+ defm OR_rr : ALU32_base<"or", "OR", or>, ImmRegRel, PredNewRel;
+}
+
+defm SUB_rr : ALU32_base<"sub", "SUB", sub>, ImmRegRel, PredNewRel;
+
+//===----------------------------------------------------------------------===//
+// ALU32/ALU (ADD with register-immediate form)
+//===----------------------------------------------------------------------===//
+multiclass ALU32ri_Pbase<string mnemonic, bit isNot, bit isPredNew> {
+ let PNewValue = !if(isPredNew, "new", "") 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 = ",
+ ") $dst = ")#mnemonic#"($src2, #$src3)",
+ []>;
+}
+
+multiclass ALU32ri_Pred<string mnemonic, bit PredNot> {
+ let PredSense = !if(PredNot, "false", "true") in {
+ defm _c#NAME : ALU32ri_Pbase<mnemonic, PredNot, 0>;
+ // Predicate new
+ defm _cdn#NAME : ALU32ri_Pbase<mnemonic, PredNot, 1>;
+ }
+}
+
+let isExtendable = 1, InputType = "imm" in
+multiclass ALU32ri_base<string mnemonic, string CextOp, SDNode OpNode> {
+ let CextOpcode = CextOp, BaseOpcode = CextOp#_ri in {
+ let opExtendable = 2, isExtentSigned = 1, opExtentBits = 16,
+ isPredicable = 1 in
+ def NAME : ALU32_ri<(outs IntRegs:$dst),
+ (ins IntRegs:$src1, s16Ext:$src2),
+ "$dst = "#mnemonic#"($src1, #$src2)",
+ [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$src1),
+ (s16ExtPred:$src2)))]>;
+
+ let opExtendable = 3, isExtentSigned = 1, opExtentBits = 8,
+ neverHasSideEffects = 1, isPredicated = 1 in {
+ defm Pt : ALU32ri_Pred<mnemonic, 0>;
+ defm NotPt : ALU32ri_Pred<mnemonic, 1>;
+ }
+ }
+}
+
+defm ADD_ri : ALU32ri_base<"add", "ADD", add>, ImmRegRel, PredNewRel;
+let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 10,
+CextOpcode = "OR", InputType = "imm" in
def OR_ri : ALU32_ri<(outs IntRegs:$dst),
- (ins IntRegs:$src1, s10Imm:$src2),
+ (ins IntRegs:$src1, s10Ext:$src2),
"$dst = or($src1, #$src2)",
[(set (i32 IntRegs:$dst), (or (i32 IntRegs:$src1),
- s10ImmPred:$src2))]>;
+ 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),
- (ins IntRegs:$src1, s10Imm:$src2),
+ (ins IntRegs:$src1, s10Ext:$src2),
"$dst = and($src1, #$src2)",
[(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1),
- s10ImmPred:$src2))]>;
-
-let isCommutable = 1, isPredicable = 1 in
-def OR_rr : ALU32_rr<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = or($src1, $src2)",
- [(set (i32 IntRegs:$dst), (or (i32 IntRegs:$src1),
- (i32 IntRegs:$src2)))]>;
-
+ s10ExtPred:$src2))]>, ImmRegRel;
// Negate.
def NEG : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
"$dst = neg($src1)",
@@ -214,36 +211,113 @@ def NOP : ALU32_rr<(outs), (ins),
"nop",
[]>;
-// Subtract.
-let isPredicable = 1 in
-def SUB_rr : ALU32_rr<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = sub($src1, $src2)",
- [(set (i32 IntRegs:$dst), (sub (i32 IntRegs:$src1),
- (i32 IntRegs:$src2)))]>;
-
// Rd32=sub(#s10,Rs32)
+let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 10,
+CextOpcode = "SUB", InputType = "imm" in
def SUB_ri : ALU32_ri<(outs IntRegs:$dst),
- (ins s10Imm:$src1, IntRegs:$src2),
+ (ins s10Ext:$src1, IntRegs:$src2),
"$dst = sub(#$src1, $src2)",
- [(set IntRegs:$dst, (sub s10ImmPred:$src1, IntRegs:$src2))]>;
-
-// Transfer immediate.
-let isMoveImm = 1, isReMaterializable = 1, isPredicable = 1 in
-def TFRI : ALU32_ri<(outs IntRegs:$dst), (ins s16Imm:$src1),
- "$dst = #$src1",
- [(set (i32 IntRegs:$dst), s16ImmPred:$src1)]>;
-
-// Transfer register.
-let neverHasSideEffects = 1, isPredicable = 1 in
-def TFR : ALU32_ri<(outs IntRegs:$dst), (ins IntRegs:$src1),
- "$dst = $src1",
- []>;
+ [(set IntRegs:$dst, (sub s10ExtPred:$src1, IntRegs:$src2))]>,
+ ImmRegRel;
-let neverHasSideEffects = 1, isPredicable = 1 in
-def TFR64 : ALU32_ri<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1),
- "$dst = $src1",
- []>;
+
+multiclass TFR_Pred<bit PredNot> {
+ let PredSense = !if(PredNot, "false", "true") 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
+ def _cdn#NAME : ALU32_rr<(outs IntRegs:$dst),
+ (ins PredRegs:$src1, IntRegs:$src2),
+ !if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = $src2",
+ []>;
+ }
+}
+
+let InputType = "reg", neverHasSideEffects = 1 in
+multiclass TFR_base<string CextOp> {
+ let CextOpcode = CextOp, BaseOpcode = CextOp in {
+ let isPredicable = 1 in
+ def NAME : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
+ "$dst = $src1",
+ []>;
+
+ let isPredicated = 1 in {
+ defm Pt : TFR_Pred<0>;
+ defm NotPt : TFR_Pred<1>;
+ }
+ }
+}
+
+multiclass TFR64_Pred<bit PredNot> {
+ let PredSense = !if(PredNot, "false", "true") in {
+ def _c#NAME : ALU32_rr<(outs DoubleRegs:$dst),
+ (ins PredRegs:$src1, DoubleRegs:$src2),
+ !if(PredNot, "if (!$src1", "if ($src1")#") $dst = $src2",
+ []>;
+ // Predicate new
+ let PNewValue = "new" in
+ def _cdn#NAME : ALU32_rr<(outs DoubleRegs:$dst),
+ (ins PredRegs:$src1, DoubleRegs:$src2),
+ !if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = $src2",
+ []>;
+ }
+}
+
+let InputType = "reg", neverHasSideEffects = 1 in
+multiclass TFR64_base<string CextOp> {
+ let CextOpcode = CextOp, BaseOpcode = CextOp in {
+ let isPredicable = 1 in
+ def NAME : ALU32_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1),
+ "$dst = $src1",
+ []>;
+
+ let isPredicated = 1 in {
+ defm Pt : TFR64_Pred<0>;
+ defm NotPt : TFR64_Pred<1>;
+ }
+ }
+}
+
+
+multiclass TFRI_Pred<bit PredNot> {
+ let PredSense = !if(PredNot, "false", "true") 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
+ def _cdn#NAME : ALU32_rr<(outs IntRegs:$dst),
+ (ins PredRegs:$src1, s12Ext:$src2),
+ !if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = #$src2",
+ []>;
+ }
+}
+
+let InputType = "imm", isExtendable = 1, isExtentSigned = 1 in
+multiclass TFRI_base<string CextOp> {
+ let CextOpcode = CextOp, BaseOpcode = CextOp#I in {
+ let opExtendable = 1, opExtentBits = 16, isMoveImm = 1, isPredicable = 1,
+ isReMaterializable = 1 in
+ def NAME : ALU32_ri<(outs IntRegs:$dst), (ins s16Ext:$src1),
+ "$dst = #$src1",
+ [(set (i32 IntRegs:$dst), s16ExtPred:$src1)]>;
+
+ let opExtendable = 2, opExtentBits = 12, neverHasSideEffects = 1,
+ isPredicated = 1 in {
+ defm Pt : TFRI_Pred<0>;
+ defm NotPt : TFRI_Pred<1>;
+ }
+ }
+}
+
+defm TFRI : TFRI_base<"TFR">, ImmRegRel, PredNewRel;
+defm TFR : TFR_base<"TFR">, ImmRegRel, PredNewRel;
+defm TFR64 : TFR64_base<"TFR64">, ImmRegRel, PredNewRel;
// Transfer control register.
let neverHasSideEffects = 1 in
@@ -260,17 +334,50 @@ def TFCR : CRInst<(outs CRRegs:$dst), (ins IntRegs:$src1),
//===----------------------------------------------------------------------===//
// Combine.
-let isPredicable = 1, neverHasSideEffects = 1 in
-def COMBINE_rr : ALU32_rr<(outs DoubleRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = combine($src1, $src2)",
- []>;
-let neverHasSideEffects = 1 in
-def COMBINE_ii : ALU32_ii<(outs DoubleRegs:$dst),
- (ins s8Imm:$src1, s8Imm:$src2),
- "$dst = combine(#$src1, #$src2)",
- []>;
+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>;
// Mux.
def VMUX_prr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1,
@@ -279,32 +386,38 @@ def VMUX_prr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1,
"$dst = vmux($src1, $src2, $src3)",
[]>;
+let CextOpcode = "MUX", InputType = "reg" in
def MUX_rr : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1,
IntRegs:$src2, IntRegs:$src3),
"$dst = mux($src1, $src2, $src3)",
- [(set (i32 IntRegs:$dst), (i32 (select (i1 PredRegs:$src1),
- (i32 IntRegs:$src2),
- (i32 IntRegs:$src3))))]>;
+ [(set (i32 IntRegs:$dst),
+ (i32 (select (i1 PredRegs:$src1), (i32 IntRegs:$src2),
+ (i32 IntRegs:$src3))))]>, ImmRegRel;
-def MUX_ir : ALU32_ir<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Imm:$src2,
+let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8,
+CextOpcode = "MUX", InputType = "imm" in
+def MUX_ir : ALU32_ir<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Ext:$src2,
IntRegs:$src3),
"$dst = mux($src1, #$src2, $src3)",
- [(set (i32 IntRegs:$dst), (i32 (select (i1 PredRegs:$src1),
- s8ImmPred:$src2,
- (i32 IntRegs:$src3))))]>;
+ [(set (i32 IntRegs:$dst),
+ (i32 (select (i1 PredRegs:$src1), s8ExtPred:$src2,
+ (i32 IntRegs:$src3))))]>, ImmRegRel;
+let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 8,
+CextOpcode = "MUX", InputType = "imm" in
def MUX_ri : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2,
- s8Imm:$src3),
+ s8Ext:$src3),
"$dst = mux($src1, $src2, #$src3)",
- [(set (i32 IntRegs:$dst), (i32 (select (i1 PredRegs:$src1),
- (i32 IntRegs:$src2),
- s8ImmPred:$src3)))]>;
+ [(set (i32 IntRegs:$dst),
+ (i32 (select (i1 PredRegs:$src1), (i32 IntRegs:$src2),
+ s8ExtPred:$src3)))]>, ImmRegRel;
-def MUX_ii : ALU32_ii<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Imm:$src2,
+let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8 in
+def MUX_ii : ALU32_ii<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Ext:$src2,
s8Imm:$src3),
"$dst = mux($src1, #$src2, #$src3)",
[(set (i32 IntRegs:$dst), (i32 (select (i1 PredRegs:$src1),
- s8ImmPred:$src2,
+ s8ExtPred:$src2,
s8ImmPred:$src3)))]>;
// Shift halfword.
@@ -348,58 +461,7 @@ def ZXTH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
// ALU32/PRED +
//===----------------------------------------------------------------------===//
-// Conditional add.
-let neverHasSideEffects = 1, isPredicated = 1 in
-def ADD_ri_cPt : ALU32_ri<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, s8Imm:$src3),
- "if ($src1) $dst = add($src2, #$src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def ADD_ri_cNotPt : ALU32_ri<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, s8Imm:$src3),
- "if (!$src1) $dst = add($src2, #$src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def ADD_ri_cdnPt : ALU32_ri<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, s8Imm:$src3),
- "if ($src1.new) $dst = add($src2, #$src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def ADD_ri_cdnNotPt : ALU32_ri<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, s8Imm:$src3),
- "if (!$src1.new) $dst = add($src2, #$src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def ADD_rr_cPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if ($src1) $dst = add($src2, $src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def ADD_rr_cNotPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if (!$src1) $dst = add($src2, $src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def ADD_rr_cdnPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if ($src1.new) $dst = add($src2, $src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def ADD_rr_cdnNotPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if (!$src1.new) $dst = add($src2, $src3)",
- []>;
-
-
// Conditional combine.
-
let neverHasSideEffects = 1, isPredicated = 1 in
def COMBINE_rr_cPt : ALU32_rr<(outs DoubleRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
@@ -424,175 +486,41 @@ def COMBINE_rr_cdnNotPt : ALU32_rr<(outs DoubleRegs:$dst),
"if (!$src1.new) $dst = combine($src2, $src3)",
[]>;
-// Conditional logical operations.
-
-let isPredicated = 1 in
-def XOR_rr_cPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if ($src1) $dst = xor($src2, $src3)",
- []>;
-
-let isPredicated = 1 in
-def XOR_rr_cNotPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if (!$src1) $dst = xor($src2, $src3)",
- []>;
-
-let isPredicated = 1 in
-def XOR_rr_cdnPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if ($src1.new) $dst = xor($src2, $src3)",
- []>;
-
-let isPredicated = 1 in
-def XOR_rr_cdnNotPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if (!$src1.new) $dst = xor($src2, $src3)",
- []>;
-
-let isPredicated = 1 in
-def AND_rr_cPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if ($src1) $dst = and($src2, $src3)",
- []>;
-
-let isPredicated = 1 in
-def AND_rr_cNotPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if (!$src1) $dst = and($src2, $src3)",
- []>;
-
-let isPredicated = 1 in
-def AND_rr_cdnPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if ($src1.new) $dst = and($src2, $src3)",
- []>;
-
-let isPredicated = 1 in
-def AND_rr_cdnNotPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if (!$src1.new) $dst = and($src2, $src3)",
- []>;
-
-let isPredicated = 1 in
-def OR_rr_cPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if ($src1) $dst = or($src2, $src3)",
- []>;
-
-let isPredicated = 1 in
-def OR_rr_cNotPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if (!$src1) $dst = or($src2, $src3)",
- []>;
-
-let isPredicated = 1 in
-def OR_rr_cdnPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if ($src1.new) $dst = or($src2, $src3)",
- []>;
-
-let isPredicated = 1 in
-def OR_rr_cdnNotPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if (!$src1.new) $dst = or($src2, $src3)",
- []>;
-
-
-// Conditional subtract.
-
-let isPredicated = 1 in
-def SUB_rr_cPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if ($src1) $dst = sub($src2, $src3)",
- []>;
-
-let isPredicated = 1 in
-def SUB_rr_cNotPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if (!$src1) $dst = sub($src2, $src3)",
- []>;
-
-let isPredicated = 1 in
-def SUB_rr_cdnPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if ($src1.new) $dst = sub($src2, $src3)",
- []>;
-
-let isPredicated = 1 in
-def SUB_rr_cdnNotPt : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if (!$src1.new) $dst = sub($src2, $src3)",
- []>;
-
-
-// Conditional transfer.
-let neverHasSideEffects = 1, isPredicated = 1 in
-def TFR_cPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1) $dst = $src2",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def TFR_cNotPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1,
- IntRegs:$src2),
- "if (!$src1) $dst = $src2",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def TFR64_cPt : ALU32_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1,
- DoubleRegs:$src2),
- "if ($src1) $dst = $src2",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def TFR64_cNotPt : ALU32_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1,
- DoubleRegs:$src2),
- "if (!$src1) $dst = $src2",
- []>;
+// 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>;
-let neverHasSideEffects = 1, isPredicated = 1 in
-def TFRI_cPt : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1, s12Imm:$src2),
- "if ($src1) $dst = #$src2",
- []>;
+def CTLZ_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1),
+ "$dst = cl0($src1)",
+ [(set (i32 IntRegs:$dst), (ctlz (i32 IntRegs:$src1)))]>;
-let neverHasSideEffects = 1, isPredicated = 1 in
-def TFRI_cNotPt : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1,
- s12Imm:$src2),
- "if (!$src1) $dst = #$src2",
- []>;
+def CTTZ_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1),
+ "$dst = ct0($src1)",
+ [(set (i32 IntRegs:$dst), (cttz (i32 IntRegs:$src1)))]>;
-let neverHasSideEffects = 1, isPredicated = 1 in
-def TFR_cdnPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1,
- IntRegs:$src2),
- "if ($src1.new) $dst = $src2",
- []>;
+def CTLZ64_rr : SInst<(outs IntRegs:$dst), (ins DoubleRegs:$src1),
+ "$dst = cl0($src1)",
+ [(set (i32 IntRegs:$dst), (i32 (trunc (ctlz (i64 DoubleRegs:$src1)))))]>;
-let neverHasSideEffects = 1, isPredicated = 1 in
-def TFR_cdnNotPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1,
- IntRegs:$src2),
- "if (!$src1.new) $dst = $src2",
- []>;
+def CTTZ64_rr : SInst<(outs IntRegs:$dst), (ins DoubleRegs:$src1),
+ "$dst = ct0($src1)",
+ [(set (i32 IntRegs:$dst), (i32 (trunc (cttz (i64 DoubleRegs:$src1)))))]>;
-let neverHasSideEffects = 1, isPredicated = 1 in
-def TFRI_cdnPt : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1,
- s12Imm:$src2),
- "if ($src1.new) $dst = #$src2",
- []>;
+def TSTBIT_rr : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
+ "$dst = tstbit($src1, $src2)",
+ [(set (i1 PredRegs:$dst),
+ (setne (and (shl 1, (i32 IntRegs:$src2)), (i32 IntRegs:$src1)), 0))]>;
-let neverHasSideEffects = 1, isPredicated = 1 in
-def TFRI_cdnNotPt : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1,
- s12Imm:$src2),
- "if (!$src1.new) $dst = #$src2",
- []>;
+def TSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
+ "$dst = tstbit($src1, $src2)",
+ [(set (i1 PredRegs:$dst),
+ (setne (and (shl 1, (u5ImmPred:$src2)), (i32 IntRegs:$src1)), 0))]>;
-// Compare.
-defm CMPGTU : CMP32_rr_ri_u9<"cmp.gtu", setugt>;
-defm CMPGT : CMP32_rr_ri_s10<"cmp.gt", setgt>;
-defm CMPLT : CMP32_rr<"cmp.lt", setlt>;
-defm CMPLTU : CMP32_rr<"cmp.ltu", setult>;
-defm CMPEQ : CMP32_rr_ri_s10<"cmp.eq", seteq>;
-defm CMPGE : CMP32_ri_s8<"cmp.ge", setge>;
-defm CMPGEU : CMP32_ri_u8<"cmp.geu", setuge>;
//===----------------------------------------------------------------------===//
// ALU32/PRED -
//===----------------------------------------------------------------------===//
@@ -709,11 +637,6 @@ def SUB64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
// Subtract halfword.
-// Transfer register.
-let neverHasSideEffects = 1 in
-def TFR_64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1),
- "$dst = $src1",
- []>;
//===----------------------------------------------------------------------===//
// ALU64/ALU -
//===----------------------------------------------------------------------===//
@@ -919,23 +842,146 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicated = 1,
// LD +
//===----------------------------------------------------------------------===//
///
-/// Make sure that in post increment load, the first operand is always the post
-/// increment operand.
-///
-// Load doubleword.
-let isPredicable = 1 in
-def LDrid : LDInst<(outs DoubleRegs:$dst),
- (ins MEMri:$addr),
- "$dst = memd($addr)",
- [(set (i64 DoubleRegs:$dst), (i64 (load ADDRriS11_3:$addr)))]>;
+// Load -- MEMri operand
+multiclass LD_MEMri_Pbase<string mnemonic, RegisterClass RC,
+ bit isNot, bit isPredNew> {
+ let PNewValue = !if(isPredNew, "new", "") in
+ def NAME : LDInst2<(outs RC:$dst),
+ (ins PredRegs:$src1, MEMri:$addr),
+ !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
+ ") ")#"$dst = "#mnemonic#"($addr)",
+ []>;
+}
-let isPredicable = 1, AddedComplexity = 20 in
-def LDrid_indexed : LDInst<(outs DoubleRegs:$dst),
- (ins IntRegs:$src1, s11_3Imm:$offset),
- "$dst = memd($src1+#$offset)",
- [(set (i64 DoubleRegs:$dst),
- (i64 (load (add (i32 IntRegs:$src1),
- s11_3ImmPred:$offset))))]>;
+multiclass LD_MEMri_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
+ let PredSense = !if(PredNot, "false", "true") in {
+ defm _c#NAME : LD_MEMri_Pbase<mnemonic, RC, PredNot, 0>;
+ // Predicate new
+ defm _cdn#NAME : LD_MEMri_Pbase<mnemonic, RC, PredNot, 1>;
+ }
+}
+
+let isExtendable = 1, neverHasSideEffects = 1 in
+multiclass LD_MEMri<string mnemonic, string CextOp, RegisterClass RC,
+ bits<5> ImmBits, bits<5> PredImmBits> {
+
+ let CextOpcode = CextOp, BaseOpcode = CextOp in {
+ let opExtendable = 2, isExtentSigned = 1, opExtentBits = ImmBits,
+ isPredicable = 1 in
+ def NAME : LDInst2<(outs RC:$dst), (ins MEMri:$addr),
+ "$dst = "#mnemonic#"($addr)",
+ []>;
+
+ let opExtendable = 3, isExtentSigned = 0, opExtentBits = PredImmBits,
+ isPredicated = 1 in {
+ defm Pt : LD_MEMri_Pred<mnemonic, RC, 0 >;
+ defm NotPt : LD_MEMri_Pred<mnemonic, RC, 1 >;
+ }
+ }
+}
+
+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;
+}
+
+def : Pat < (i32 (sextloadi8 ADDRriS11_0:$addr)),
+ (LDrib ADDRriS11_0:$addr) >;
+
+def : Pat < (i32 (zextloadi8 ADDRriS11_0:$addr)),
+ (LDriub ADDRriS11_0:$addr) >;
+
+def : Pat < (i32 (sextloadi16 ADDRriS11_1:$addr)),
+ (LDrih ADDRriS11_1:$addr) >;
+
+def : Pat < (i32 (zextloadi16 ADDRriS11_1:$addr)),
+ (LDriuh ADDRriS11_1:$addr) >;
+
+def : Pat < (i32 (load ADDRriS11_2:$addr)),
+ (LDriw ADDRriS11_2:$addr) >;
+
+def : Pat < (i64 (load ADDRriS11_3:$addr)),
+ (LDrid 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
+ def NAME : LDInst2<(outs RC:$dst),
+ (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3),
+ !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
+ ") ")#"$dst = "#mnemonic#"($src2+#$src3)",
+ []>;
+}
+
+multiclass LD_Idxd_Pred<string mnemonic, RegisterClass RC, Operand predImmOp,
+ bit PredNot> {
+ let PredSense = !if(PredNot, "false", "true") 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>;
+ }
+}
+
+let isExtendable = 1, neverHasSideEffects = 1 in
+multiclass LD_Idxd<string mnemonic, string CextOp, RegisterClass RC,
+ Operand ImmOp, Operand predImmOp, bits<5> ImmBits,
+ bits<5> PredImmBits> {
+
+ let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
+ let opExtendable = 2, isExtentSigned = 1, opExtentBits = ImmBits,
+ isPredicable = 1, AddedComplexity = 20 in
+ def NAME : LDInst2<(outs RC:$dst), (ins IntRegs:$src1, ImmOp:$offset),
+ "$dst = "#mnemonic#"($src1+#$offset)",
+ []>;
+
+ let opExtendable = 3, isExtentSigned = 0, opExtentBits = PredImmBits,
+ isPredicated = 1 in {
+ defm Pt : LD_Idxd_Pred<mnemonic, RC, predImmOp, 0 >;
+ defm NotPt : LD_Idxd_Pred<mnemonic, RC, predImmOp, 1 >;
+ }
+ }
+}
+
+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 AddedComplexity = 20 in {
+def : Pat < (i32 (sextloadi8 (add IntRegs:$src1, s11_0ExtPred:$offset))),
+ (LDrib_indexed IntRegs:$src1, s11_0ExtPred:$offset) >;
+
+def : Pat < (i32 (zextloadi8 (add IntRegs:$src1, s11_0ExtPred:$offset))),
+ (LDriub_indexed IntRegs:$src1, s11_0ExtPred:$offset) >;
+
+def : Pat < (i32 (sextloadi16 (add IntRegs:$src1, s11_1ExtPred:$offset))),
+ (LDrih_indexed IntRegs:$src1, s11_1ExtPred:$offset) >;
+
+def : Pat < (i32 (zextloadi16 (add IntRegs:$src1, s11_1ExtPred:$offset))),
+ (LDriuh_indexed IntRegs:$src1, s11_1ExtPred:$offset) >;
+
+def : Pat < (i32 (load (add IntRegs:$src1, s11_2ExtPred:$offset))),
+ (LDriw_indexed IntRegs:$src1, s11_2ExtPred:$offset) >;
+
+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),
@@ -944,105 +990,80 @@ def LDrid_GP : LDInst2<(outs DoubleRegs:$dst),
[]>,
Requires<[NoV4T]>;
-let neverHasSideEffects = 1 in
+let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def LDd_GP : LDInst2<(outs DoubleRegs:$dst),
(ins globaladdress:$global),
"$dst = memd(#$global)",
[]>,
Requires<[NoV4T]>;
-let isPredicable = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
-def POST_LDrid : LDInst2PI<(outs DoubleRegs:$dst, IntRegs:$dst2),
- (ins IntRegs:$src1, s4Imm:$offset),
- "$dst = memd($src1++#$offset)",
- [],
- "$src1 = $dst2">;
-
-// Load doubleword conditionally.
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrid_cPt : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if ($src1) $dst = memd($addr)",
- []>;
-
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrid_cNotPt : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if (!$src1) $dst = memd($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrid_indexed_cPt : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_3Imm:$src3),
- "if ($src1) $dst = memd($src2+#$src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrid_indexed_cNotPt : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_3Imm:$src3),
- "if (!$src1) $dst = memd($src2+#$src3)",
- []>;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDrid_cPt : LDInst2PI<(outs DoubleRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_3Imm:$src3),
- "if ($src1) $dst1 = memd($src2++#$src3)",
- [],
- "$src2 = $dst2">;
+//===----------------------------------------------------------------------===//
+// Post increment load
+// Make sure that in post increment load, the first operand is always the post
+// increment operand.
+//===----------------------------------------------------------------------===//
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDrid_cNotPt : LDInst2PI<(outs DoubleRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_3Imm:$src3),
- "if (!$src1) $dst1 = memd($src2++#$src3)",
+multiclass LD_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp,
+ bit isNot, bit isPredNew> {
+ let PNewValue = !if(isPredNew, "new", "") 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) ",
+ ") ")#"$dst = "#mnemonic#"($src2++#$offset)",
[],
"$src2 = $dst2">;
+}
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrid_cdnPt : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if ($src1.new) $dst = memd($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrid_cdnNotPt : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if (!$src1.new) $dst = memd($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrid_indexed_cdnPt : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_3Imm:$src3),
- "if ($src1.new) $dst = memd($src2+#$src3)",
- []>;
+multiclass LD_PostInc_Pred<string mnemonic, RegisterClass RC,
+ Operand ImmOp, bit PredNot> {
+ let PredSense = !if(PredNot, "false", "true") in {
+ defm _c#NAME : LD_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>;
+ // Predicate new
+ let Predicates = [HasV4T], validSubTargets = HasV4SubT in
+ defm _cdn#NAME#_V4 : LD_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 1>;
+ }
+}
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrid_indexed_cdnNotPt : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_3Imm:$src3),
- "if (!$src1.new) $dst = memd($src2+#$src3)",
- []>;
+multiclass LD_PostInc<string mnemonic, string BaseOp, RegisterClass RC,
+ Operand ImmOp> {
+
+ let BaseOpcode = "POST_"#BaseOp in {
+ let isPredicable = 1 in
+ def NAME : LDInst2PI<(outs RC:$dst, IntRegs:$dst2),
+ (ins IntRegs:$src1, ImmOp:$offset),
+ "$dst = "#mnemonic#"($src1++#$offset)",
+ [],
+ "$src1 = $dst2">;
+
+ let isPredicated = 1 in {
+ defm Pt : LD_PostInc_Pred<mnemonic, RC, ImmOp, 0 >;
+ defm NotPt : LD_PostInc_Pred<mnemonic, RC, ImmOp, 1 >;
+ }
+ }
+}
+let hasCtrlDep = 1, neverHasSideEffects = 1 in {
+ defm POST_LDrib : LD_PostInc<"memb", "LDrib", IntRegs, s4_0Imm>,
+ PredNewRel;
+ defm POST_LDriub : LD_PostInc<"memub", "LDriub", IntRegs, s4_0Imm>,
+ PredNewRel;
+ defm POST_LDrih : LD_PostInc<"memh", "LDrih", IntRegs, s4_1Imm>,
+ PredNewRel;
+ defm POST_LDriuh : LD_PostInc<"memuh", "LDriuh", IntRegs, s4_1Imm>,
+ PredNewRel;
+ defm POST_LDriw : LD_PostInc<"memw", "LDriw", IntRegs, s4_2Imm>,
+ PredNewRel;
+ defm POST_LDrid : LD_PostInc<"memd", "LDrid", DoubleRegs, s4_3Imm>,
+ PredNewRel;
+}
-// Load byte.
-let isPredicable = 1 in
-def LDrib : LDInst<(outs IntRegs:$dst),
- (ins MEMri:$addr),
- "$dst = memb($addr)",
- [(set (i32 IntRegs:$dst), (i32 (sextloadi8 ADDRriS11_0:$addr)))]>;
+def : Pat< (i32 (extloadi1 ADDRriS11_0:$addr)),
+ (i32 (LDrib ADDRriS11_0:$addr)) >;
// Load byte any-extend.
def : Pat < (i32 (extloadi8 ADDRriS11_0:$addr)),
(i32 (LDrib ADDRriS11_0:$addr)) >;
-// Indexed load byte.
-let isPredicable = 1, AddedComplexity = 20 in
-def LDrib_indexed : LDInst<(outs IntRegs:$dst),
- (ins IntRegs:$src1, s11_0Imm:$offset),
- "$dst = memb($src1+#$offset)",
- [(set (i32 IntRegs:$dst),
- (i32 (sextloadi8 (add (i32 IntRegs:$src1),
- s11_0ImmPred:$offset))))]>;
-
// Indexed load byte any-extend.
let AddedComplexity = 20 in
def : Pat < (i32 (extloadi8 (add IntRegs:$src1, s11_0ImmPred:$offset))),
@@ -1055,106 +1076,20 @@ def LDrib_GP : LDInst2<(outs IntRegs:$dst),
[]>,
Requires<[NoV4T]>;
-let neverHasSideEffects = 1 in
+let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def LDb_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst = memb(#$global)",
[]>,
Requires<[NoV4T]>;
-let neverHasSideEffects = 1 in
+let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def LDub_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst = memub(#$global)",
[]>,
Requires<[NoV4T]>;
-let isPredicable = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
-def POST_LDrib : LDInst2PI<(outs IntRegs:$dst, IntRegs:$dst2),
- (ins IntRegs:$src1, s4Imm:$offset),
- "$dst = memb($src1++#$offset)",
- [],
- "$src1 = $dst2">;
-
-// Load byte conditionally.
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrib_cPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if ($src1) $dst = memb($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrib_cNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if (!$src1) $dst = memb($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrib_indexed_cPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3),
- "if ($src1) $dst = memb($src2+#$src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrib_indexed_cNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3),
- "if (!$src1) $dst = memb($src2+#$src3)",
- []>;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDrib_cPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
- "if ($src1) $dst1 = memb($src2++#$src3)",
- [],
- "$src2 = $dst2">;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDrib_cNotPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
- "if (!$src1) $dst1 = memb($src2++#$src3)",
- [],
- "$src2 = $dst2">;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrib_cdnPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if ($src1.new) $dst = memb($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrib_cdnNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if (!$src1.new) $dst = memb($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrib_indexed_cdnPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3),
- "if ($src1.new) $dst = memb($src2+#$src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrib_indexed_cdnNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3),
- "if (!$src1.new) $dst = memb($src2+#$src3)",
- []>;
-
-
-// Load halfword.
-let isPredicable = 1 in
-def LDrih : LDInst<(outs IntRegs:$dst),
- (ins MEMri:$addr),
- "$dst = memh($addr)",
- [(set (i32 IntRegs:$dst), (i32 (sextloadi16 ADDRriS11_1:$addr)))]>;
-
-let isPredicable = 1, AddedComplexity = 20 in
-def LDrih_indexed : LDInst<(outs IntRegs:$dst),
- (ins IntRegs:$src1, s11_1Imm:$offset),
- "$dst = memh($src1+#$offset)",
- [(set (i32 IntRegs:$dst),
- (i32 (sextloadi16 (add (i32 IntRegs:$src1),
- s11_1ImmPred:$offset))))]>;
-
def : Pat < (i32 (extloadi16 ADDRriS11_1:$addr)),
(i32 (LDrih ADDRriS11_1:$addr))>;
@@ -1169,108 +1104,24 @@ def LDrih_GP : LDInst2<(outs IntRegs:$dst),
[]>,
Requires<[NoV4T]>;
-let neverHasSideEffects = 1 in
+let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def LDh_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst = memh(#$global)",
[]>,
Requires<[NoV4T]>;
-let neverHasSideEffects = 1 in
+let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def LDuh_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst = memuh(#$global)",
[]>,
Requires<[NoV4T]>;
-let isPredicable = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
-def POST_LDrih : LDInst2PI<(outs IntRegs:$dst, IntRegs:$dst2),
- (ins IntRegs:$src1, s4Imm:$offset),
- "$dst = memh($src1++#$offset)",
- [],
- "$src1 = $dst2">;
-
-// Load halfword conditionally.
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrih_cPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if ($src1) $dst = memh($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrih_cNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if (!$src1) $dst = memh($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrih_indexed_cPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3),
- "if ($src1) $dst = memh($src2+#$src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrih_indexed_cNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3),
- "if (!$src1) $dst = memh($src2+#$src3)",
- []>;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDrih_cPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
- "if ($src1) $dst1 = memh($src2++#$src3)",
- [],
- "$src2 = $dst2">;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDrih_cNotPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
- "if (!$src1) $dst1 = memh($src2++#$src3)",
- [],
- "$src2 = $dst2">;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrih_cdnPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if ($src1.new) $dst = memh($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrih_cdnNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if (!$src1.new) $dst = memh($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrih_indexed_cdnPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3),
- "if ($src1.new) $dst = memh($src2+#$src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDrih_indexed_cdnNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3),
- "if (!$src1.new) $dst = memh($src2+#$src3)",
- []>;
-
-// Load unsigned byte.
-let isPredicable = 1 in
-def LDriub : LDInst<(outs IntRegs:$dst),
- (ins MEMri:$addr),
- "$dst = memub($addr)",
- [(set (i32 IntRegs:$dst), (i32 (zextloadi8 ADDRriS11_0:$addr)))]>;
-
+let AddedComplexity = 10 in
def : Pat < (i32 (zextloadi1 ADDRriS11_0:$addr)),
(i32 (LDriub ADDRriS11_0:$addr))>;
-let isPredicable = 1, AddedComplexity = 20 in
-def LDriub_indexed : LDInst<(outs IntRegs:$dst),
- (ins IntRegs:$src1, s11_0Imm:$offset),
- "$dst = memub($src1+#$offset)",
- [(set (i32 IntRegs:$dst),
- (i32 (zextloadi8 (add (i32 IntRegs:$src1),
- s11_0ImmPred:$offset))))]>;
-
let AddedComplexity = 20 in
def : Pat < (i32 (zextloadi1 (add IntRegs:$src1, s11_0ImmPred:$offset))),
(i32 (LDriub_indexed IntRegs:$src1, s11_0ImmPred:$offset))>;
@@ -1282,92 +1133,7 @@ def LDriub_GP : LDInst2<(outs IntRegs:$dst),
[]>,
Requires<[NoV4T]>;
-let isPredicable = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
-def POST_LDriub : LDInst2PI<(outs IntRegs:$dst, IntRegs:$dst2),
- (ins IntRegs:$src1, s4Imm:$offset),
- "$dst = memub($src1++#$offset)",
- [],
- "$src1 = $dst2">;
-
-// Load unsigned byte conditionally.
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriub_cPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if ($src1) $dst = memub($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriub_cNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if (!$src1) $dst = memub($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriub_indexed_cPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3),
- "if ($src1) $dst = memub($src2+#$src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriub_indexed_cNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3),
- "if (!$src1) $dst = memub($src2+#$src3)",
- []>;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDriub_cPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
- "if ($src1) $dst1 = memub($src2++#$src3)",
- [],
- "$src2 = $dst2">;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDriub_cNotPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
- "if (!$src1) $dst1 = memub($src2++#$src3)",
- [],
- "$src2 = $dst2">;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriub_cdnPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if ($src1.new) $dst = memub($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriub_cdnNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if (!$src1.new) $dst = memub($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriub_indexed_cdnPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3),
- "if ($src1.new) $dst = memub($src2+#$src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriub_indexed_cdnNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3),
- "if (!$src1.new) $dst = memub($src2+#$src3)",
- []>;
-
// Load unsigned halfword.
-let isPredicable = 1 in
-def LDriuh : LDInst<(outs IntRegs:$dst),
- (ins MEMri:$addr),
- "$dst = memuh($addr)",
- [(set (i32 IntRegs:$dst), (i32 (zextloadi16 ADDRriS11_1:$addr)))]>;
-
-// Indexed load unsigned halfword.
-let isPredicable = 1, AddedComplexity = 20 in
-def LDriuh_indexed : LDInst<(outs IntRegs:$dst),
- (ins IntRegs:$src1, s11_1Imm:$offset),
- "$dst = memuh($src1+#$offset)",
- [(set (i32 IntRegs:$dst),
- (i32 (zextloadi16 (add (i32 IntRegs:$src1),
- s11_1ImmPred:$offset))))]>;
-
let neverHasSideEffects = 1 in
def LDriuh_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global, u16Imm:$offset),
@@ -1375,98 +1141,15 @@ def LDriuh_GP : LDInst2<(outs IntRegs:$dst),
[]>,
Requires<[NoV4T]>;
-let isPredicable = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
-def POST_LDriuh : LDInst2PI<(outs IntRegs:$dst, IntRegs:$dst2),
- (ins IntRegs:$src1, s4Imm:$offset),
- "$dst = memuh($src1++#$offset)",
- [],
- "$src1 = $dst2">;
-
-// Load unsigned halfword conditionally.
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriuh_cPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if ($src1) $dst = memuh($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriuh_cNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if (!$src1) $dst = memuh($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriuh_indexed_cPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3),
- "if ($src1) $dst = memuh($src2+#$src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriuh_indexed_cNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3),
- "if (!$src1) $dst = memuh($src2+#$src3)",
- []>;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDriuh_cPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
- "if ($src1) $dst1 = memuh($src2++#$src3)",
- [],
- "$src2 = $dst2">;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDriuh_cNotPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
- "if (!$src1) $dst1 = memuh($src2++#$src3)",
- [],
- "$src2 = $dst2">;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriuh_cdnPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if ($src1.new) $dst = memuh($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriuh_cdnNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if (!$src1.new) $dst = memuh($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriuh_indexed_cdnPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3),
- "if ($src1.new) $dst = memuh($src2+#$src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriuh_indexed_cdnNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3),
- "if (!$src1.new) $dst = memuh($src2+#$src3)",
- []>;
-
-
-// Load word.
-let isPredicable = 1 in
-def LDriw : LDInst<(outs IntRegs:$dst),
- (ins MEMri:$addr), "$dst = memw($addr)",
- [(set IntRegs:$dst, (i32 (load ADDRriS11_2:$addr)))]>;
-
// Load predicate.
-let Defs = [R10,R11,D5], neverHasSideEffects = 1 in
-def LDriw_pred : LDInst<(outs PredRegs:$dst),
+let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13,
+isPseudo = 1, Defs = [R10,R11,D5], neverHasSideEffects = 1 in
+def LDriw_pred : LDInst2<(outs PredRegs:$dst),
(ins MEMri:$addr),
"Error; should not emit",
[]>;
// Indexed load.
-let isPredicable = 1, AddedComplexity = 20 in
-def LDriw_indexed : LDInst<(outs IntRegs:$dst),
- (ins IntRegs:$src1, s11_2Imm:$offset),
- "$dst = memw($src1+#$offset)",
- [(set IntRegs:$dst, (i32 (load (add IntRegs:$src1,
- s11_2ImmPred:$offset))))]>;
-
let neverHasSideEffects = 1 in
def LDriw_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global, u16Imm:$offset),
@@ -1474,87 +1157,16 @@ def LDriw_GP : LDInst2<(outs IntRegs:$dst),
[]>,
Requires<[NoV4T]>;
-let neverHasSideEffects = 1 in
+let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def LDw_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst = memw(#$global)",
[]>,
Requires<[NoV4T]>;
-let isPredicable = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
-def POST_LDriw : LDInst2PI<(outs IntRegs:$dst, IntRegs:$dst2),
- (ins IntRegs:$src1, s4Imm:$offset),
- "$dst = memw($src1++#$offset)",
- [],
- "$src1 = $dst2">;
-
-// Load word conditionally.
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriw_cPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if ($src1) $dst = memw($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriw_cNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if (!$src1) $dst = memw($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriw_indexed_cPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3),
- "if ($src1) $dst = memw($src2+#$src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriw_indexed_cNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3),
- "if (!$src1) $dst = memw($src2+#$src3)",
- []>;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDriw_cPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_2Imm:$src3),
- "if ($src1) $dst1 = memw($src2++#$src3)",
- [],
- "$src2 = $dst2">;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDriw_cNotPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_2Imm:$src3),
- "if (!$src1) $dst1 = memw($src2++#$src3)",
- [],
- "$src2 = $dst2">;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriw_cdnPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if ($src1.new) $dst = memw($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriw_cdnNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- "if (!$src1.new) $dst = memw($addr)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriw_indexed_cdnPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3),
- "if ($src1.new) $dst = memw($src2+#$src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def LDriw_indexed_cdnNotPt : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3),
- "if (!$src1.new) $dst = memw($src2+#$src3)",
- []>;
-
// Deallocate stack frame.
let Defs = [R29, R30, R31], Uses = [R29], neverHasSideEffects = 1 in {
- def DEALLOCFRAME : LDInst2<(outs), (ins i32imm:$amt1),
+ def DEALLOCFRAME : LDInst2<(outs), (ins),
"deallocframe",
[]>;
}
@@ -1778,19 +1390,6 @@ def SUBri_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1,
/// last operand.
///
// Store doubleword.
-let isPredicable = 1 in
-def STrid : STInst<(outs),
- (ins MEMri:$addr, DoubleRegs:$src1),
- "memd($addr) = $src1",
- [(store (i64 DoubleRegs:$src1), ADDRriS11_3:$addr)]>;
-
-// Indexed store double word.
-let AddedComplexity = 10, isPredicable = 1 in
-def STrid_indexed : STInst<(outs),
- (ins IntRegs:$src1, s11_3Imm:$src2, DoubleRegs:$src3),
- "memd($src1+#$src2) = $src3",
- [(store (i64 DoubleRegs:$src3),
- (add (i32 IntRegs:$src1), s11_3ImmPred:$src2))]>;
let neverHasSideEffects = 1 in
def STrid_GP : STInst2<(outs),
@@ -1799,7 +1398,7 @@ def STrid_GP : STInst2<(outs),
[]>,
Requires<[NoV4T]>;
-let neverHasSideEffects = 1 in
+let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def STd_GP : STInst2<(outs),
(ins globaladdress:$global, DoubleRegs:$src),
"memd(#$global) = $src",
@@ -1815,42 +1414,6 @@ def POST_STdri : STInstPI<(outs IntRegs:$dst),
s4_3ImmPred:$offset))],
"$src2 = $dst">;
-// Store doubleword conditionally.
-// if ([!]Pv) memd(Rs+#u6:3)=Rtt
-// if (Pv) memd(Rs+#u6:3)=Rtt
-let AddedComplexity = 10, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrid_cPt : STInst2<(outs),
- (ins PredRegs:$src1, MEMri:$addr, DoubleRegs:$src2),
- "if ($src1) memd($addr) = $src2",
- []>;
-
-// if (!Pv) memd(Rs+#u6:3)=Rtt
-let AddedComplexity = 10, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrid_cNotPt : STInst2<(outs),
- (ins PredRegs:$src1, MEMri:$addr, DoubleRegs:$src2),
- "if (!$src1) memd($addr) = $src2",
- []>;
-
-// if (Pv) memd(Rs+#u6:3)=Rtt
-let AddedComplexity = 10, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrid_indexed_cPt : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_3Imm:$src3,
- DoubleRegs:$src4),
- "if ($src1) memd($src2+#$src3) = $src4",
- []>;
-
-// if (!Pv) memd(Rs+#u6:3)=Rtt
-let AddedComplexity = 10, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrid_indexed_cNotPt : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_3Imm:$src3,
- DoubleRegs:$src4),
- "if (!$src1) memd($src2+#$src3) = $src4",
- []>;
-
// if ([!]Pv) memd(Rx++#s4:3)=Rtt
// if (Pv) memd(Rx++#s4:3)=Rtt
let AddedComplexity = 10, neverHasSideEffects = 1,
@@ -1872,21 +1435,149 @@ def POST_STdri_cNotPt : STInst2PI<(outs IntRegs:$dst),
[],
"$src3 = $dst">;
+//===----------------------------------------------------------------------===//
+// multiclass for the store instructions with MEMri operand.
+//===----------------------------------------------------------------------===//
+multiclass ST_MEMri_Pbase<string mnemonic, RegisterClass RC, bit isNot,
+ bit isPredNew> {
+ let PNewValue = !if(isPredNew, "new", "") in
+ def NAME : STInst2<(outs),
+ (ins PredRegs:$src1, MEMri:$addr, RC: $src2),
+ !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
+ ") ")#mnemonic#"($addr) = $src2",
+ []>;
+}
+
+multiclass ST_MEMri_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
+ let PredSense = !if(PredNot, "false", "true") in {
+ defm _c#NAME : ST_MEMri_Pbase<mnemonic, RC, PredNot, 0>;
-// Store byte.
-// memb(Rs+#s11:0)=Rt
-let isPredicable = 1 in
-def STrib : STInst<(outs),
- (ins MEMri:$addr, IntRegs:$src1),
- "memb($addr) = $src1",
- [(truncstorei8 (i32 IntRegs:$src1), ADDRriS11_0:$addr)]>;
-
-let AddedComplexity = 10, isPredicable = 1 in
-def STrib_indexed : STInst<(outs),
- (ins IntRegs:$src1, s11_0Imm:$src2, IntRegs:$src3),
- "memb($src1+#$src2) = $src3",
- [(truncstorei8 (i32 IntRegs:$src3), (add (i32 IntRegs:$src1),
- s11_0ImmPred:$src2))]>;
+ // Predicate new
+ let validSubTargets = HasV4SubT, Predicates = [HasV4T] in
+ defm _cdn#NAME#_V4 : ST_MEMri_Pbase<mnemonic, RC, PredNot, 1>;
+ }
+}
+
+let isExtendable = 1, isNVStorable = 1, neverHasSideEffects = 1 in
+multiclass ST_MEMri<string mnemonic, string CextOp, RegisterClass RC,
+ bits<5> ImmBits, bits<5> PredImmBits> {
+
+ let CextOpcode = CextOp, BaseOpcode = CextOp in {
+ let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
+ isPredicable = 1 in
+ def NAME : STInst2<(outs),
+ (ins MEMri:$addr, RC:$src),
+ mnemonic#"($addr) = $src",
+ []>;
+
+ let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
+ isPredicated = 1 in {
+ defm Pt : ST_MEMri_Pred<mnemonic, RC, 0>;
+ defm NotPt : ST_MEMri_Pred<mnemonic, RC, 1>;
+ }
+ }
+}
+
+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 isNVStorable = 0 in
+ defm STrid: ST_MEMri < "memd", "STrid", DoubleRegs, 14, 9>, AddrModeRel;
+}
+
+def : Pat<(truncstorei8 (i32 IntRegs:$src1), ADDRriS11_0:$addr),
+ (STrib ADDRriS11_0:$addr, (i32 IntRegs:$src1))>;
+
+def : Pat<(truncstorei16 (i32 IntRegs:$src1), ADDRriS11_1:$addr),
+ (STrih ADDRriS11_1:$addr, (i32 IntRegs:$src1))>;
+
+def : Pat<(store (i32 IntRegs:$src1), ADDRriS11_2:$addr),
+ (STriw ADDRriS11_2:$addr, (i32 IntRegs:$src1))>;
+
+def : Pat<(store (i64 DoubleRegs:$src1), ADDRriS11_3:$addr),
+ (STrid ADDRriS11_3:$addr, (i64 DoubleRegs:$src1))>;
+
+
+//===----------------------------------------------------------------------===//
+// multiclass for the store instructions with base+immediate offset
+// addressing mode
+//===----------------------------------------------------------------------===//
+multiclass ST_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp,
+ bit isNot, bit isPredNew> {
+ let PNewValue = !if(isPredNew, "new", "") in
+ def NAME : STInst2<(outs),
+ (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4),
+ !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
+ ") ")#mnemonic#"($src2+#$src3) = $src4",
+ []>;
+}
+
+multiclass ST_Idxd_Pred<string mnemonic, RegisterClass RC, Operand predImmOp,
+ bit PredNot> {
+ let PredSense = !if(PredNot, "false", "true"), isPredicated = 1 in {
+ defm _c#NAME : ST_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 0>;
+
+ // Predicate new
+ let validSubTargets = HasV4SubT, Predicates = [HasV4T] in
+ defm _cdn#NAME#_V4 : ST_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 1>;
+ }
+}
+
+let isExtendable = 1, isNVStorable = 1, neverHasSideEffects = 1 in
+multiclass ST_Idxd<string mnemonic, string CextOp, RegisterClass RC,
+ Operand ImmOp, Operand predImmOp, bits<5> ImmBits,
+ bits<5> PredImmBits> {
+
+ let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
+ let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
+ isPredicable = 1 in
+ def NAME : STInst2<(outs),
+ (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
+ mnemonic#"($src1+#$src2) = $src3",
+ []>;
+
+ let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits in {
+ defm Pt : ST_Idxd_Pred<mnemonic, RC, predImmOp, 0>;
+ defm NotPt : ST_Idxd_Pred<mnemonic, RC, predImmOp, 1>;
+ }
+ }
+}
+
+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 AddedComplexity = 10 in {
+def : Pat<(truncstorei8 (i32 IntRegs:$src1), (add IntRegs:$src2,
+ s11_0ExtPred:$offset)),
+ (STrib_indexed IntRegs:$src2, s11_0ImmPred:$offset,
+ (i32 IntRegs:$src1))>;
+
+def : Pat<(truncstorei16 (i32 IntRegs:$src1), (add IntRegs:$src2,
+ s11_1ExtPred:$offset)),
+ (STrih_indexed IntRegs:$src2, s11_1ImmPred:$offset,
+ (i32 IntRegs:$src1))>;
+
+def : Pat<(store (i32 IntRegs:$src1), (add IntRegs:$src2,
+ s11_2ExtPred:$offset)),
+ (STriw_indexed IntRegs:$src2, s11_2ImmPred:$offset,
+ (i32 IntRegs:$src1))>;
+
+def : Pat<(store (i64 DoubleRegs:$src1), (add IntRegs:$src2,
+ s11_3ExtPred:$offset)),
+ (STrid_indexed IntRegs:$src2, s11_3ImmPred:$offset,
+ (i64 DoubleRegs:$src1))>;
+}
// memb(gp+#u16:0)=Rt
let neverHasSideEffects = 1 in
@@ -1897,7 +1588,7 @@ def STrib_GP : STInst2<(outs),
Requires<[NoV4T]>;
// memb(#global)=Rt
-let neverHasSideEffects = 1 in
+let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def STb_GP : STInst2<(outs),
(ins globaladdress:$global, IntRegs:$src),
"memb(#$global) = $src",
@@ -1915,36 +1606,6 @@ def POST_STbri : STInstPI<(outs IntRegs:$dst), (ins IntRegs:$src1,
s4_0ImmPred:$offset))],
"$src2 = $dst">;
-// Store byte conditionally.
-// if ([!]Pv) memb(Rs+#u6:0)=Rt
-// if (Pv) memb(Rs+#u6:0)=Rt
-let neverHasSideEffects = 1, isPredicated = 1 in
-def STrib_cPt : STInst2<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if ($src1) memb($addr) = $src2",
- []>;
-
-// if (!Pv) memb(Rs+#u6:0)=Rt
-let neverHasSideEffects = 1, isPredicated = 1 in
-def STrib_cNotPt : STInst2<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if (!$src1) memb($addr) = $src2",
- []>;
-
-// if (Pv) memb(Rs+#u6:0)=Rt
-let neverHasSideEffects = 1, isPredicated = 1 in
-def STrib_indexed_cPt : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, IntRegs:$src4),
- "if ($src1) memb($src2+#$src3) = $src4",
- []>;
-
-// if (!Pv) memb(Rs+#u6:0)=Rt
-let neverHasSideEffects = 1, isPredicated = 1 in
-def STrib_indexed_cNotPt : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, IntRegs:$src4),
- "if (!$src1) memb($src2+#$src3) = $src4",
- []>;
-
// if ([!]Pv) memb(Rx++#s4:0)=Rt
// if (Pv) memb(Rx++#s4:0)=Rt
let hasCtrlDep = 1, isPredicated = 1 in
@@ -1960,23 +1621,6 @@ def POST_STbri_cNotPt : STInst2PI<(outs IntRegs:$dst),
"if (!$src1) memb($src3++#$offset) = $src2",
[],"$src3 = $dst">;
-
-// Store halfword.
-// memh(Rs+#s11:1)=Rt
-let isPredicable = 1 in
-def STrih : STInst<(outs),
- (ins MEMri:$addr, IntRegs:$src1),
- "memh($addr) = $src1",
- [(truncstorei16 (i32 IntRegs:$src1), ADDRriS11_1:$addr)]>;
-
-
-let AddedComplexity = 10, isPredicable = 1 in
-def STrih_indexed : STInst<(outs),
- (ins IntRegs:$src1, s11_1Imm:$src2, IntRegs:$src3),
- "memh($src1+#$src2) = $src3",
- [(truncstorei16 (i32 IntRegs:$src3), (add (i32 IntRegs:$src1),
- s11_1ImmPred:$src2))]>;
-
let neverHasSideEffects = 1 in
def STrih_GP : STInst2<(outs),
(ins globaladdress:$global, u16Imm:$offset, IntRegs:$src),
@@ -1984,7 +1628,7 @@ def STrih_GP : STInst2<(outs),
[]>,
Requires<[NoV4T]>;
-let neverHasSideEffects = 1 in
+let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def STh_GP : STInst2<(outs),
(ins globaladdress:$global, IntRegs:$src),
"memh(#$global) = $src",
@@ -2002,36 +1646,6 @@ def POST_SThri : STInstPI<(outs IntRegs:$dst),
s4_1ImmPred:$offset))],
"$src2 = $dst">;
-// Store halfword conditionally.
-// if ([!]Pv) memh(Rs+#u6:1)=Rt
-// if (Pv) memh(Rs+#u6:1)=Rt
-let neverHasSideEffects = 1, isPredicated = 1 in
-def STrih_cPt : STInst2<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if ($src1) memh($addr) = $src2",
- []>;
-
-// if (!Pv) memh(Rs+#u6:1)=Rt
-let neverHasSideEffects = 1, isPredicated = 1 in
-def STrih_cNotPt : STInst2<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if (!$src1) memh($addr) = $src2",
- []>;
-
-// if (Pv) memh(Rs+#u6:1)=Rt
-let neverHasSideEffects = 1, isPredicated = 1 in
-def STrih_indexed_cPt : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, IntRegs:$src4),
- "if ($src1) memh($src2+#$src3) = $src4",
- []>;
-
-// if (!Pv) memh(Rs+#u6:1)=Rt
-let neverHasSideEffects = 1, isPredicated = 1 in
-def STrih_indexed_cNotPt : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, IntRegs:$src4),
- "if (!$src1) memh($src2+#$src3) = $src4",
- []>;
-
// if ([!]Pv) memh(Rx++#s4:1)=Rt
// if (Pv) memh(Rx++#s4:1)=Rt
let hasCtrlDep = 1, isPredicated = 1 in
@@ -2056,20 +1670,6 @@ def STriw_pred : STInst2<(outs),
"Error; should not emit",
[]>;
-// memw(Rs+#s11:2)=Rt
-let isPredicable = 1 in
-def STriw : STInst<(outs),
- (ins MEMri:$addr, IntRegs:$src1),
- "memw($addr) = $src1",
- [(store (i32 IntRegs:$src1), ADDRriS11_2:$addr)]>;
-
-let AddedComplexity = 10, isPredicable = 1 in
-def STriw_indexed : STInst<(outs),
- (ins IntRegs:$src1, s11_2Imm:$src2, IntRegs:$src3),
- "memw($src1+#$src2) = $src3",
- [(store (i32 IntRegs:$src3),
- (add (i32 IntRegs:$src1), s11_2ImmPred:$src2))]>;
-
let neverHasSideEffects = 1 in
def STriw_GP : STInst2<(outs),
(ins globaladdress:$global, u16Imm:$offset, IntRegs:$src),
@@ -2077,7 +1677,7 @@ def STriw_GP : STInst2<(outs),
[]>,
Requires<[NoV4T]>;
-let neverHasSideEffects = 1 in
+let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
def STw_GP : STInst2<(outs),
(ins globaladdress:$global, IntRegs:$src),
"memw(#$global) = $src",
@@ -2093,36 +1693,6 @@ def POST_STwri : STInstPI<(outs IntRegs:$dst),
s4_2ImmPred:$offset))],
"$src2 = $dst">;
-// Store word conditionally.
-// if ([!]Pv) memw(Rs+#u6:2)=Rt
-// if (Pv) memw(Rs+#u6:2)=Rt
-let neverHasSideEffects = 1, isPredicated = 1 in
-def STriw_cPt : STInst2<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if ($src1) memw($addr) = $src2",
- []>;
-
-// if (!Pv) memw(Rs+#u6:2)=Rt
-let neverHasSideEffects = 1, isPredicated = 1 in
-def STriw_cNotPt : STInst2<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if (!$src1) memw($addr) = $src2",
- []>;
-
-// if (Pv) memw(Rs+#u6:2)=Rt
-let neverHasSideEffects = 1, isPredicated = 1 in
-def STriw_indexed_cPt : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, IntRegs:$src4),
- "if ($src1) memw($src2+#$src3) = $src4",
- []>;
-
-// if (!Pv) memw(Rs+#u6:2)=Rt
-let neverHasSideEffects = 1, isPredicated = 1 in
-def STriw_indexed_cNotPt : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, IntRegs:$src4),
- "if (!$src1) memw($src2+#$src3) = $src4",
- []>;
-
// if ([!]Pv) memw(Rx++#s4:2)=Rt
// if (Pv) memw(Rx++#s4:2)=Rt
let hasCtrlDep = 1, isPredicated = 1 in
@@ -3545,5 +3115,3 @@ include "HexagonInstrInfoV5.td"
//===----------------------------------------------------------------------===//
// V5 Instructions -
//===----------------------------------------------------------------------===//
-
-
diff --git a/lib/Target/Hexagon/HexagonInstrInfoV4.td b/lib/Target/Hexagon/HexagonInstrInfoV4.td
index 70448fc..372de9a 100644
--- a/lib/Target/Hexagon/HexagonInstrInfoV4.td
+++ b/lib/Target/Hexagon/HexagonInstrInfoV4.td
@@ -12,10 +12,14 @@
//===----------------------------------------------------------------------===//
let neverHasSideEffects = 1 in
-def IMMEXT : Immext<(outs), (ins),
- "/* immext #... */",
- []>,
- Requires<[HasV4T]>;
+class T_Immext<dag ins> :
+ EXTENDERInst<(outs), ins, "immext(#$imm)", []>,
+ Requires<[HasV4T]>;
+
+def IMMEXT_b : T_Immext<(ins brtarget:$imm)>;
+def IMMEXT_c : T_Immext<(ins calltarget:$imm)>;
+def IMMEXT_g : T_Immext<(ins globaladdress:$imm)>;
+def IMMEXT_i : T_Immext<(ins u26_6Imm:$imm)>;
// Hexagon V4 Architecture spec defines 8 instruction classes:
// LD ST ALU32 XTYPE J JR MEMOP NV CR SYSTEM(system is not implemented in the
@@ -83,86 +87,77 @@ def IMMEXT : Immext<(outs), (ins),
// Shift halfword.
-let isPredicated = 1 in
+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]>;
-let isPredicated = 1 in
def ASLH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if (!$src1) $dst = aslh($src2)",
[]>,
Requires<[HasV4T]>;
-let isPredicated = 1 in
def ASLH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if ($src1.new) $dst = aslh($src2)",
[]>,
Requires<[HasV4T]>;
-let isPredicated = 1 in
def ASLH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if (!$src1.new) $dst = aslh($src2)",
[]>,
Requires<[HasV4T]>;
-let isPredicated = 1 in
def ASRH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if ($src1) $dst = asrh($src2)",
[]>,
Requires<[HasV4T]>;
-let isPredicated = 1 in
def ASRH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if (!$src1) $dst = asrh($src2)",
[]>,
Requires<[HasV4T]>;
-let isPredicated = 1 in
def ASRH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if ($src1.new) $dst = asrh($src2)",
[]>,
Requires<[HasV4T]>;
-let isPredicated = 1 in
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 in
+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]>;
-let isPredicated = 1 in
def SXTB_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if (!$src1) $dst = sxtb($src2)",
[]>,
Requires<[HasV4T]>;
-let isPredicated = 1 in
def SXTB_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if ($src1.new) $dst = sxtb($src2)",
[]>,
Requires<[HasV4T]>;
-let isPredicated = 1 in
def SXTB_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if (!$src1.new) $dst = sxtb($src2)",
@@ -170,94 +165,86 @@ def SXTB_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
Requires<[HasV4T]>;
-let isPredicated = 1 in
def SXTH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if ($src1) $dst = sxth($src2)",
[]>,
Requires<[HasV4T]>;
-let isPredicated = 1 in
def SXTH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if (!$src1) $dst = sxth($src2)",
[]>,
Requires<[HasV4T]>;
-let isPredicated = 1 in
def SXTH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if ($src1.new) $dst = sxth($src2)",
[]>,
Requires<[HasV4T]>;
-let isPredicated = 1 in
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 in
+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]>;
-let neverHasSideEffects = 1, isPredicated = 1 in
def ZXTB_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if (!$src1) $dst = zxtb($src2)",
[]>,
Requires<[HasV4T]>;
-let neverHasSideEffects = 1, isPredicated = 1 in
def ZXTB_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if ($src1.new) $dst = zxtb($src2)",
[]>,
Requires<[HasV4T]>;
-let neverHasSideEffects = 1, isPredicated = 1 in
def ZXTB_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if (!$src1.new) $dst = zxtb($src2)",
[]>,
Requires<[HasV4T]>;
-let neverHasSideEffects = 1, isPredicated = 1 in
def ZXTH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if ($src1) $dst = zxth($src2)",
[]>,
Requires<[HasV4T]>;
-let neverHasSideEffects = 1, isPredicated = 1 in
def ZXTH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if (!$src1) $dst = zxth($src2)",
[]>,
Requires<[HasV4T]>;
-let neverHasSideEffects = 1, isPredicated = 1 in
def ZXTH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if ($src1.new) $dst = zxth($src2)",
[]>,
Requires<[HasV4T]>;
-let neverHasSideEffects = 1, isPredicated = 1 in
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 in
+let neverHasSideEffects = 1, isReMaterializable = 1,
+isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in
def TFR_FI_immext_V4 : ALU32_ri<(outs IntRegs:$dst),
(ins IntRegs:$src1, s32Imm:$offset),
"$dst = add($src1, ##$offset)",
@@ -276,19 +263,31 @@ def TFR_FI_immext_V4 : ALU32_ri<(outs IntRegs:$dst),
// Combine
// Rdd=combine(Rs, #s8)
-let neverHasSideEffects = 1 in
-def COMBINE_ri_V4 : ALU32_ri<(outs DoubleRegs:$dst),
- (ins IntRegs:$src1, s8Imm:$src2),
+let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8,
+ neverHasSideEffects = 1, validSubTargets = HasV4SubT in
+def COMBINE_rI_V4 : ALU32_ri<(outs DoubleRegs:$dst),
+ (ins IntRegs:$src1, s8Ext:$src2),
"$dst = combine($src1, #$src2)",
[]>,
Requires<[HasV4T]>;
+
// Rdd=combine(#s8, Rs)
-let neverHasSideEffects = 1 in
-def COMBINE_ir_V4 : ALU32_ir<(outs DoubleRegs:$dst),
- (ins s8Imm:$src1, IntRegs:$src2),
+let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 8,
+ neverHasSideEffects = 1, validSubTargets = HasV4SubT in
+def COMBINE_Ir_V4 : ALU32_ir<(outs DoubleRegs:$dst),
+ (ins s8Ext:$src1, IntRegs:$src2),
"$dst = combine(#$src1, $src2)",
[]>,
Requires<[HasV4T]>;
+
+let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 6,
+ neverHasSideEffects = 1, validSubTargets = HasV4SubT in
+def COMBINE_iI_V4 : ALU32_ii<(outs DoubleRegs:$dst),
+ (ins s8Imm:$src1, u6Ext:$src2),
+ "$dst = combine(#$src1, #$src2)",
+ []>,
+ Requires<[HasV4T]>;
+
//===----------------------------------------------------------------------===//
// ALU32/PERM +
//===----------------------------------------------------------------------===//
@@ -415,15 +414,103 @@ def LDrid_indexed_V4 : LDInst<(outs DoubleRegs:$dst),
(i32 IntRegs:$src2)))))]>,
Requires<[HasV4T]>;
-let AddedComplexity = 40, isPredicable = 1 in
-def LDrid_indexed_shl_V4 : LDInst<(outs DoubleRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset),
- "$dst=memd($src1+$src2<<#$offset)",
- [(set (i64 DoubleRegs:$dst),
- (i64 (load (add (i32 IntRegs:$src1),
- (shl (i32 IntRegs:$src2),
- u2ImmPred:$offset)))))]>,
- 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
+ def NAME : LDInst2<(outs RC:$dst),
+ (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset),
+ !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
+ ") ")#"$dst = "#mnemonic#"($src2+$src3<<#$offset)",
+ []>, Requires<[HasV4T]>;
+}
+
+multiclass ld_idxd_shl_pred<string mnemonic, RegisterClass RC, bit PredNot> {
+ let PredSense = !if(PredNot, "false", "true") 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>;
+ }
+}
+
+let neverHasSideEffects = 1 in
+multiclass ld_idxd_shl<string mnemonic, string CextOp, RegisterClass RC> {
+ let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
+ let isPredicable = 1 in
+ def NAME#_V4 : LDInst2<(outs RC:$dst),
+ (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset),
+ "$dst = "#mnemonic#"($src1+$src2<<#$offset)",
+ []>, Requires<[HasV4T]>;
+
+ let isPredicated = 1 in {
+ defm Pt_V4 : ld_idxd_shl_pred<mnemonic, RC, 0 >;
+ defm NotPt_V4 : ld_idxd_shl_pred<mnemonic, RC, 1>;
+ }
+ }
+}
+
+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;
+}
+
+// 'def pats' for load instructions with base + register offset and non-zero
+// immediate value. Immediate value is used to left-shift the second
+// register operand.
+let AddedComplexity = 40 in {
+def : Pat <(i32 (sextloadi8 (add IntRegs:$src1,
+ (shl IntRegs:$src2, u2ImmPred:$offset)))),
+ (LDrib_indexed_shl_V4 IntRegs:$src1,
+ IntRegs:$src2, u2ImmPred:$offset)>,
+ Requires<[HasV4T]>;
+
+def : Pat <(i32 (zextloadi8 (add IntRegs:$src1,
+ (shl IntRegs:$src2, u2ImmPred:$offset)))),
+ (LDriub_indexed_shl_V4 IntRegs:$src1,
+ IntRegs:$src2, u2ImmPred:$offset)>,
+ Requires<[HasV4T]>;
+
+def : Pat <(i32 (extloadi8 (add IntRegs:$src1,
+ (shl IntRegs:$src2, u2ImmPred:$offset)))),
+ (LDriub_indexed_shl_V4 IntRegs:$src1,
+ IntRegs:$src2, u2ImmPred:$offset)>,
+ Requires<[HasV4T]>;
+
+def : Pat <(i32 (sextloadi16 (add IntRegs:$src1,
+ (shl IntRegs:$src2, u2ImmPred:$offset)))),
+ (LDrih_indexed_shl_V4 IntRegs:$src1,
+ IntRegs:$src2, u2ImmPred:$offset)>,
+ Requires<[HasV4T]>;
+
+def : Pat <(i32 (zextloadi16 (add IntRegs:$src1,
+ (shl IntRegs:$src2, u2ImmPred:$offset)))),
+ (LDriuh_indexed_shl_V4 IntRegs:$src1,
+ IntRegs:$src2, u2ImmPred:$offset)>,
+ Requires<[HasV4T]>;
+
+def : Pat <(i32 (extloadi16 (add IntRegs:$src1,
+ (shl IntRegs:$src2, u2ImmPred:$offset)))),
+ (LDriuh_indexed_shl_V4 IntRegs:$src1,
+ IntRegs:$src2, u2ImmPred:$offset)>,
+ Requires<[HasV4T]>;
+
+def : Pat <(i32 (load (add IntRegs:$src1,
+ (shl IntRegs:$src2, u2ImmPred:$offset)))),
+ (LDriw_indexed_shl_V4 IntRegs:$src1,
+ IntRegs:$src2, u2ImmPred:$offset)>,
+ Requires<[HasV4T]>;
+
+def : Pat <(i64 (load (add IntRegs:$src1,
+ (shl IntRegs:$src2, u2ImmPred:$offset)))),
+ (LDrid_indexed_shl_V4 IntRegs:$src1,
+ IntRegs:$src2, u2ImmPred:$offset)>,
+ Requires<[HasV4T]>;
+}
//// Load doubleword conditionally.
// if ([!]Pv[.new]) Rd=memd(Rs+Rt<<#u2)
@@ -459,42 +546,6 @@ def LDrid_indexed_cdnNotPt_V4 : LDInst2<(outs DoubleRegs:$dst),
[]>,
Requires<[HasV4T]>;
-// if (Pv) Rd=memd(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDrid_indexed_shl_cPt_V4 : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if ($src1) $dst=memd($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) Rd=memd(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDrid_indexed_shl_cdnPt_V4 : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if ($src1.new) $dst=memd($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) Rd=memd(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDrid_indexed_shl_cNotPt_V4 : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if (!$src1) $dst=memd($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) Rd=memd(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDrid_indexed_shl_cdnNotPt_V4 : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if (!$src1.new) $dst=memd($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
// Rdd=memd(Rt<<#u2+#U6)
//// Load byte.
@@ -527,26 +578,6 @@ def LDriub_ae_indexed_V4 : LDInst<(outs IntRegs:$dst),
Requires<[HasV4T]>;
let AddedComplexity = 40, isPredicable = 1 in
-def LDrib_indexed_shl_V4 : LDInst<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset),
- "$dst=memb($src1+$src2<<#$offset)",
- [(set (i32 IntRegs:$dst),
- (i32 (sextloadi8 (add (i32 IntRegs:$src1),
- (shl (i32 IntRegs:$src2),
- u2ImmPred:$offset)))))]>,
- Requires<[HasV4T]>;
-
-let AddedComplexity = 40, isPredicable = 1 in
-def LDriub_indexed_shl_V4 : LDInst<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset),
- "$dst=memub($src1+$src2<<#$offset)",
- [(set (i32 IntRegs:$dst),
- (i32 (zextloadi8 (add (i32 IntRegs:$src1),
- (shl (i32 IntRegs:$src2),
- u2ImmPred:$offset)))))]>,
- Requires<[HasV4T]>;
-
-let AddedComplexity = 40, isPredicable = 1 in
def LDriub_ae_indexed_shl_V4 : LDInst<(outs IntRegs:$dst),
(ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset),
"$dst=memub($src1+$src2<<#$offset)",
@@ -590,42 +621,6 @@ def LDrib_indexed_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
[]>,
Requires<[HasV4T]>;
-// if (Pv) Rd=memb(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDrib_indexed_shl_cPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if ($src1) $dst=memb($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) Rd=memb(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDrib_indexed_shl_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if ($src1.new) $dst=memb($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) Rd=memb(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDrib_indexed_shl_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if (!$src1) $dst=memb($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) Rd=memb(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDrib_indexed_shl_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if (!$src1.new) $dst=memb($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
//// Load unsigned byte conditionally.
// if ([!]Pv[.new]) Rd=memub(Rs+Rt<<#u2)
// if (Pv) Rd=memub(Rs+Rt<<#u2)
@@ -660,42 +655,6 @@ def LDriub_indexed_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
[]>,
Requires<[HasV4T]>;
-// if (Pv) Rd=memub(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDriub_indexed_shl_cPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if ($src1) $dst=memub($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) Rd=memub(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDriub_indexed_shl_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if ($src1.new) $dst=memub($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) Rd=memub(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDriub_indexed_shl_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if (!$src1) $dst=memub($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) Rd=memub(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDriub_indexed_shl_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if (!$src1.new) $dst=memub($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
// Rd=memb(Rt<<#u2+#U6)
//// Load halfword
@@ -727,27 +686,6 @@ def LDriuh_ae_indexed_V4 : LDInst<(outs IntRegs:$dst),
(i32 IntRegs:$src2)))))]>,
Requires<[HasV4T]>;
-// Rd=memh(Rs+Rt<<#u2)
-let AddedComplexity = 40, isPredicable = 1 in
-def LDrih_indexed_shl_V4 : LDInst<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset),
- "$dst=memh($src1+$src2<<#$offset)",
- [(set (i32 IntRegs:$dst),
- (i32 (sextloadi16 (add (i32 IntRegs:$src1),
- (shl (i32 IntRegs:$src2),
- u2ImmPred:$offset)))))]>,
- Requires<[HasV4T]>;
-
-let AddedComplexity = 40, isPredicable = 1 in
-def LDriuh_indexed_shl_V4 : LDInst<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset),
- "$dst=memuh($src1+$src2<<#$offset)",
- [(set (i32 IntRegs:$dst),
- (i32 (zextloadi16 (add (i32 IntRegs:$src1),
- (shl (i32 IntRegs:$src2),
- u2ImmPred:$offset)))))]>,
- Requires<[HasV4T]>;
-
let AddedComplexity = 40, isPredicable = 1 in
def LDriuh_ae_indexed_shl_V4 : LDInst<(outs IntRegs:$dst),
(ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset),
@@ -792,42 +730,6 @@ def LDrih_indexed_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
[]>,
Requires<[HasV4T]>;
-// if (Pv) Rd=memh(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDrih_indexed_shl_cPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if ($src1) $dst=memh($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) Rd=memh(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDrih_indexed_shl_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if ($src1.new) $dst=memh($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) Rd=memh(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDrih_indexed_shl_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if (!$src1) $dst=memh($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) Rd=memh(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDrih_indexed_shl_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if (!$src1.new) $dst=memh($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
//// Load unsigned halfword conditionally.
// if ([!]Pv[.new]) Rd=memuh(Rs+Rt<<#u2)
// if (Pv) Rd=memuh(Rs+Rt<<#u2)
@@ -862,42 +764,6 @@ def LDriuh_indexed_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
[]>,
Requires<[HasV4T]>;
-// if (Pv) Rd=memuh(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDriuh_indexed_shl_cPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if ($src1) $dst=memuh($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) Rd=memuh(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDriuh_indexed_shl_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if ($src1.new) $dst=memuh($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) Rd=memuh(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDriuh_indexed_shl_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if (!$src1) $dst=memuh($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) Rd=memuh(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDriuh_indexed_shl_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if (!$src1.new) $dst=memuh($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
// Rd=memh(Rt<<#u2+#U6)
//// Load word.
@@ -921,17 +787,6 @@ def LDriw_indexed_V4 : LDInst<(outs IntRegs:$dst),
(i32 IntRegs:$src2)))))]>,
Requires<[HasV4T]>;
-// Rd=memw(Rs+Rt<<#u2)
-let AddedComplexity = 40, isPredicable = 1 in
-def LDriw_indexed_shl_V4 : LDInst<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset),
- "$dst=memw($src1+$src2<<#$offset)",
- [(set (i32 IntRegs:$dst),
- (i32 (load (add (i32 IntRegs:$src1),
- (shl (i32 IntRegs:$src2),
- u2ImmPred:$offset)))))]>,
- Requires<[HasV4T]>;
-
//// Load word conditionally.
// if ([!]Pv[.new]) Rd=memw(Rs+Rt<<#u2)
// if (Pv) Rd=memw(Rs+Rt<<#u2)
@@ -966,144 +821,6 @@ def LDriw_indexed_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
[]>,
Requires<[HasV4T]>;
-// if (Pv) Rd=memh(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDriw_indexed_shl_cPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if ($src1) $dst=memw($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) Rd=memh(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDriw_indexed_shl_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if ($src1.new) $dst=memw($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) Rd=memh(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDriw_indexed_shl_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if (!$src1) $dst=memw($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) Rd=memh(Rs+Rt<<#u2)
-let AddedComplexity = 45, isPredicated = 1 in
-def LDriw_indexed_shl_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3,
- u2Imm:$offset),
- "if (!$src1.new) $dst=memw($src2+$src3<<#$offset)",
- []>,
- Requires<[HasV4T]>;
-
-// Rd=memw(Rt<<#u2+#U6)
-
-
-// Post-inc Load, Predicated, Dot new
-
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDrid_cdnPt_V4 : LDInst2PI<(outs DoubleRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_3Imm:$src3),
- "if ($src1.new) $dst1 = memd($src2++#$src3)",
- [],
- "$src2 = $dst2">,
- Requires<[HasV4T]>;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDrid_cdnNotPt_V4 : LDInst2PI<(outs DoubleRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_3Imm:$src3),
- "if (!$src1.new) $dst1 = memd($src2++#$src3)",
- [],
- "$src2 = $dst2">,
- Requires<[HasV4T]>;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDrib_cdnPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
- "if ($src1.new) $dst1 = memb($src2++#$src3)",
- [],
- "$src2 = $dst2">,
- Requires<[HasV4T]>;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDrib_cdnNotPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
- "if (!$src1.new) $dst1 = memb($src2++#$src3)",
- [],
- "$src2 = $dst2">,
- Requires<[HasV4T]>;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDrih_cdnPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
- "if ($src1.new) $dst1 = memh($src2++#$src3)",
- [],
- "$src2 = $dst2">,
- Requires<[HasV4T]>;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDrih_cdnNotPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
- "if (!$src1.new) $dst1 = memh($src2++#$src3)",
- [],
- "$src2 = $dst2">,
- Requires<[HasV4T]>;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDriub_cdnPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
- "if ($src1.new) $dst1 = memub($src2++#$src3)",
- [],
- "$src2 = $dst2">,
- Requires<[HasV4T]>;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDriub_cdnNotPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
- "if (!$src1.new) $dst1 = memub($src2++#$src3)",
- [],
- "$src2 = $dst2">,
- Requires<[HasV4T]>;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDriuh_cdnPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
- "if ($src1.new) $dst1 = memuh($src2++#$src3)",
- [],
- "$src2 = $dst2">,
- Requires<[HasV4T]>;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDriuh_cdnNotPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
- "if (!$src1.new) $dst1 = memuh($src2++#$src3)",
- [],
- "$src2 = $dst2">,
- Requires<[HasV4T]>;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDriw_cdnPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_2Imm:$src3),
- "if ($src1.new) $dst1 = memw($src2++#$src3)",
- [],
- "$src2 = $dst2">,
- Requires<[HasV4T]>;
-
-let hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in
-def POST_LDriw_cdnNotPt_V4 : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, s4_2Imm:$src3),
- "if (!$src1.new) $dst1 = memw($src2++#$src3)",
- [],
- "$src2 = $dst2">,
- Requires<[HasV4T]>;
-
/// Load from global offset
let isPredicable = 1, neverHasSideEffects = 1 in
@@ -1324,7 +1041,7 @@ def LDriw_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
Requires<[HasV4T]>;
-let isPredicable = 1, neverHasSideEffects = 1 in
+let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
def LDd_GP_V4 : LDInst2<(outs DoubleRegs:$dst),
(ins globaladdress:$global),
"$dst=memd(#$global)",
@@ -1332,7 +1049,8 @@ def LDd_GP_V4 : LDInst2<(outs DoubleRegs:$dst),
Requires<[HasV4T]>;
// if (Pv) Rtt=memd(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
+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)",
@@ -1341,7 +1059,6 @@ def LDd_GP_cPt_V4 : LDInst2<(outs DoubleRegs:$dst),
// if (!Pv) Rtt=memd(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
def LDd_GP_cNotPt_V4 : LDInst2<(outs DoubleRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if (!$src1) $dst=memd(##$global)",
@@ -1349,7 +1066,6 @@ def LDd_GP_cNotPt_V4 : LDInst2<(outs DoubleRegs:$dst),
Requires<[HasV4T]>;
// if (Pv) Rtt=memd(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
def LDd_GP_cdnPt_V4 : LDInst2<(outs DoubleRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if ($src1.new) $dst=memd(##$global)",
@@ -1358,14 +1074,14 @@ def LDd_GP_cdnPt_V4 : LDInst2<(outs DoubleRegs:$dst),
// if (!Pv) Rtt=memd(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
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 in
+let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
def LDb_GP_V4 : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst=memb(#$global)",
@@ -1373,7 +1089,8 @@ def LDb_GP_V4 : LDInst2<(outs IntRegs:$dst),
Requires<[HasV4T]>;
// if (Pv) Rt=memb(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
+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)",
@@ -1381,7 +1098,6 @@ def LDb_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
Requires<[HasV4T]>;
// if (!Pv) Rt=memb(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
def LDb_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if (!$src1) $dst=memb(##$global)",
@@ -1389,7 +1105,6 @@ def LDb_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
Requires<[HasV4T]>;
// if (Pv) Rt=memb(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
def LDb_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if ($src1.new) $dst=memb(##$global)",
@@ -1397,14 +1112,14 @@ def LDb_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
Requires<[HasV4T]>;
// if (!Pv) Rt=memb(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
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 in
+let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
def LDub_GP_V4 : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst=memub(#$global)",
@@ -1412,7 +1127,8 @@ def LDub_GP_V4 : LDInst2<(outs IntRegs:$dst),
Requires<[HasV4T]>;
// if (Pv) Rt=memub(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
+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)",
@@ -1421,7 +1137,6 @@ def LDub_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
// if (!Pv) Rt=memub(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
def LDub_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if (!$src1) $dst=memub(##$global)",
@@ -1429,7 +1144,6 @@ def LDub_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
Requires<[HasV4T]>;
// if (Pv) Rt=memub(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
def LDub_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if ($src1.new) $dst=memub(##$global)",
@@ -1438,14 +1152,14 @@ def LDub_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
// if (!Pv) Rt=memub(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
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 in
+let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
def LDh_GP_V4 : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst=memh(#$global)",
@@ -1453,7 +1167,8 @@ def LDh_GP_V4 : LDInst2<(outs IntRegs:$dst),
Requires<[HasV4T]>;
// if (Pv) Rt=memh(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
+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)",
@@ -1461,7 +1176,6 @@ def LDh_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
Requires<[HasV4T]>;
// if (!Pv) Rt=memh(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
def LDh_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if (!$src1) $dst=memh(##$global)",
@@ -1469,7 +1183,6 @@ def LDh_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
Requires<[HasV4T]>;
// if (Pv) Rt=memh(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
def LDh_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if ($src1.new) $dst=memh(##$global)",
@@ -1477,14 +1190,14 @@ def LDh_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
Requires<[HasV4T]>;
// if (!Pv) Rt=memh(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
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 in
+let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
def LDuh_GP_V4 : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst=memuh(#$global)",
@@ -1492,7 +1205,8 @@ def LDuh_GP_V4 : LDInst2<(outs IntRegs:$dst),
Requires<[HasV4T]>;
// if (Pv) Rt=memuh(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
+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)",
@@ -1500,7 +1214,6 @@ def LDuh_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
Requires<[HasV4T]>;
// if (!Pv) Rt=memuh(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
def LDuh_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if (!$src1) $dst=memuh(##$global)",
@@ -1508,7 +1221,6 @@ def LDuh_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
Requires<[HasV4T]>;
// if (Pv) Rt=memuh(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
def LDuh_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if ($src1.new) $dst=memuh(##$global)",
@@ -1516,14 +1228,14 @@ def LDuh_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
Requires<[HasV4T]>;
// if (!Pv) Rt=memuh(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
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 in
+let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
def LDw_GP_V4 : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst=memw(#$global)",
@@ -1531,7 +1243,8 @@ def LDw_GP_V4 : LDInst2<(outs IntRegs:$dst),
Requires<[HasV4T]>;
// if (Pv) Rt=memw(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
+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)",
@@ -1540,7 +1253,6 @@ def LDw_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
// if (!Pv) Rt=memw(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
def LDw_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if (!$src1) $dst=memw(##$global)",
@@ -1548,7 +1260,6 @@ def LDw_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
Requires<[HasV4T]>;
// if (Pv) Rt=memw(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
def LDw_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$global),
"if ($src1.new) $dst=memw(##$global)",
@@ -1557,13 +1268,12 @@ def LDw_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
// if (!Pv) Rt=memw(##global)
-let neverHasSideEffects = 1, isPredicated = 1 in
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)),
@@ -1803,16 +1513,124 @@ def STriw_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
[]>,
Requires<[HasV4T]>;
-// memd(Rs+Ru<<#u2)=Rtt
-let AddedComplexity = 10, isPredicable = 1 in
-def STrid_indexed_shl_V4 : STInst<(outs),
- (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, DoubleRegs:$src4),
- "memd($src1+$src2<<#$src3) = $src4",
- [(store (i64 DoubleRegs:$src4),
- (add (i32 IntRegs:$src1),
- (shl (i32 IntRegs:$src2), u2ImmPred:$src3)))]>,
+
+// 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
+ def NAME : STInst2<(outs),
+ (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
+ RC:$src5),
+ !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
+ ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5",
+ []>,
+ Requires<[HasV4T]>;
+}
+
+multiclass ST_Idxd_shl_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
+ let PredSense = !if(PredNot, "false", "true") 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>;
+ }
+}
+
+let isNVStorable = 1 in
+multiclass ST_Idxd_shl<string mnemonic, string CextOp, RegisterClass RC> {
+ let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
+ let isPredicable = 1 in
+ def NAME#_V4 : STInst2<(outs),
+ (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4),
+ mnemonic#"($src1+$src2<<#$src3) = $src4",
+ []>,
+ Requires<[HasV4T]>;
+
+ let isPredicated = 1 in {
+ defm Pt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 0 >;
+ defm NotPt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 1>;
+ }
+ }
+}
+
+// multiclass for new-value store instructions with base + register offset
+// addressing mode.
+multiclass ST_Idxd_shl_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
+ bit isPredNew> {
+ let PNewValue = !if(isPredNew, "new", "") in
+ def NAME#_nv_V4 : NVInst_V4<(outs),
+ (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
+ RC:$src5),
+ !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
+ ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5.new",
+ []>,
+ Requires<[HasV4T]>;
+}
+
+multiclass ST_Idxd_shl_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
+ let PredSense = !if(PredNot, "false", "true") 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>;
+ }
+}
+
+let mayStore = 1, isNVStore = 1 in
+multiclass ST_Idxd_shl_nv<string mnemonic, string CextOp, RegisterClass RC> {
+ let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
+ let isPredicable = 1 in
+ def NAME#_nv_V4 : NVInst_V4<(outs),
+ (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4),
+ mnemonic#"($src1+$src2<<#$src3) = $src4.new",
+ []>,
Requires<[HasV4T]>;
+ let isPredicated = 1 in {
+ defm Pt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 0 >;
+ defm NotPt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 1>;
+ }
+ }
+}
+
+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;
+
+ 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 isNVStorable = 0 in
+ defm STrid_indexed_shl: ST_Idxd_shl<"memd", "STrid", DoubleRegs>, AddrModeRel;
+}
+
+let Predicates = [HasV4T], AddedComplexity = 10 in {
+def : Pat<(truncstorei8 (i32 IntRegs:$src4),
+ (add IntRegs:$src1, (shl IntRegs:$src2,
+ u2ImmPred:$src3))),
+ (STrib_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
+ u2ImmPred:$src3, IntRegs:$src4)>;
+
+def : Pat<(truncstorei16 (i32 IntRegs:$src4),
+ (add IntRegs:$src1, (shl IntRegs:$src2,
+ u2ImmPred:$src3))),
+ (STrih_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
+ u2ImmPred:$src3, IntRegs:$src4)>;
+
+def : Pat<(store (i32 IntRegs:$src4),
+ (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))),
+ (STriw_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
+ u2ImmPred:$src3, IntRegs:$src4)>;
+
+def : Pat<(store (i64 DoubleRegs:$src4),
+ (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))),
+ (STrid_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
+ u2ImmPred:$src3, DoubleRegs:$src4)>;
+}
+
// memd(Ru<<#u2+#U6)=Rtt
let AddedComplexity = 10 in
def STrid_shl_V4 : STInst<(outs),
@@ -1834,88 +1652,6 @@ def STrid_shl_V4 : STInst<(outs),
// if ([!]Pv[.new]) memd(#u6)=Rtt
// TODO: needs to be implemented.
-// if ([!]Pv[.new]) memd(Rs+#u6:3)=Rtt
-// if (Pv) memd(Rs+#u6:3)=Rtt
-// if (Pv.new) memd(Rs+#u6:3)=Rtt
-let AddedComplexity = 10, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrid_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, MEMri:$addr, DoubleRegs:$src2),
- "if ($src1.new) memd($addr) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memd(Rs+#u6:3)=Rtt
-// if (!Pv.new) memd(Rs+#u6:3)=Rtt
-let AddedComplexity = 10, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrid_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, MEMri:$addr, DoubleRegs:$src2),
- "if (!$src1.new) memd($addr) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memd(Rs+#u6:3)=Rtt
-// if (Pv.new) memd(Rs+#u6:3)=Rtt
-let AddedComplexity = 10, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrid_indexed_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_3Imm:$src3,
- DoubleRegs:$src4),
- "if ($src1.new) memd($src2+#$src3) = $src4",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memd(Rs+#u6:3)=Rtt
-// if (!Pv.new) memd(Rs+#u6:3)=Rtt
-let AddedComplexity = 10, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrid_indexed_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_3Imm:$src3,
- DoubleRegs:$src4),
- "if (!$src1.new) memd($src2+#$src3) = $src4",
- []>,
- Requires<[HasV4T]>;
-
-// if ([!]Pv[.new]) memd(Rs+Ru<<#u2)=Rtt
-// if (Pv) memd(Rs+Ru<<#u2)=Rtt
-let AddedComplexity = 10, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrid_indexed_shl_cPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- DoubleRegs:$src5),
- "if ($src1) memd($src2+$src3<<#$src4) = $src5",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) memd(Rs+Ru<<#u2)=Rtt
-let AddedComplexity = 10, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrid_indexed_shl_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- DoubleRegs:$src5),
- "if ($src1.new) memd($src2+$src3<<#$src4) = $src5",
- []>,
- Requires<[HasV4T]>;
-// if (!Pv) memd(Rs+Ru<<#u2)=Rtt
-let AddedComplexity = 10, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrid_indexed_shl_cNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- DoubleRegs:$src5),
- "if (!$src1) memd($src2+$src3<<#$src4) = $src5",
- []>,
- Requires<[HasV4T]>;
-// if (!Pv.new) memd(Rs+Ru<<#u2)=Rtt
-let AddedComplexity = 10, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrid_indexed_shl_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- DoubleRegs:$src5),
- "if (!$src1.new) memd($src2+$src3<<#$src4) = $src5",
- []>,
- Requires<[HasV4T]>;
-
// if ([!]Pv[.new]) memd(Rx++#s4:3)=Rtt
// if (Pv) memd(Rx++#s4:3)=Rtt
// if (Pv.new) memd(Rx++#s4:3)=Rtt
@@ -1942,27 +1678,68 @@ def POST_STdri_cdnNotPt_V4 : STInst2PI<(outs IntRegs:$dst),
Requires<[HasV4T]>;
-// Store byte.
-// memb(Rs+#u6:0)=#S8
-let AddedComplexity = 10, isPredicable = 1 in
-def STrib_imm_V4 : STInst<(outs),
- (ins IntRegs:$src1, u6_0Imm:$src2, s8Imm:$src3),
- "memb($src1+#$src2) = #$src3",
- [(truncstorei8 s8ImmPred:$src3, (add (i32 IntRegs:$src1),
- u6_0ImmPred:$src2))]>,
+// multiclass for store instructions with base + immediate offset
+// addressing mode and immediate stored value.
+multiclass ST_Imm_Pbase<string mnemonic, Operand OffsetOp, bit isNot,
+ bit isPredNew> {
+ let PNewValue = !if(isPredNew, "new", "") in
+ def NAME : STInst2<(outs),
+ (ins PredRegs:$src1, IntRegs:$src2, OffsetOp:$src3, s6Ext:$src4),
+ !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
+ ") ")#mnemonic#"($src2+#$src3) = #$src4",
+ []>,
Requires<[HasV4T]>;
+}
-// memb(Rs+Ru<<#u2)=Rt
-let AddedComplexity = 10, isPredicable = 1 in
-def STrib_indexed_shl_V4 : STInst<(outs),
- (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, IntRegs:$src4),
- "memb($src1+$src2<<#$src3) = $src4",
- [(truncstorei8 (i32 IntRegs:$src4),
- (add (i32 IntRegs:$src1),
- (shl (i32 IntRegs:$src2),
- u2ImmPred:$src3)))]>,
+multiclass ST_Imm_Pred<string mnemonic, Operand OffsetOp, bit PredNot> {
+ let PredSense = !if(PredNot, "false", "true") in {
+ defm _c#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 0>;
+ // Predicate new
+ defm _cdn#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 1>;
+ }
+}
+
+let isExtendable = 1, isExtentSigned = 1, neverHasSideEffects = 1 in
+multiclass ST_Imm<string mnemonic, string CextOp, Operand OffsetOp> {
+ let CextOpcode = CextOp, BaseOpcode = CextOp#_imm in {
+ let opExtendable = 2, opExtentBits = 8, isPredicable = 1 in
+ def NAME#_V4 : STInst2<(outs),
+ (ins IntRegs:$src1, OffsetOp:$src2, s8Ext:$src3),
+ mnemonic#"($src1+#$src2) = #$src3",
+ []>,
Requires<[HasV4T]>;
+ let opExtendable = 3, opExtentBits = 6, isPredicated = 1 in {
+ defm Pt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 0>;
+ defm NotPt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 1 >;
+ }
+ }
+}
+
+let addrMode = BaseImmOffset, InputType = "imm",
+ validSubTargets = HasV4SubT in {
+ defm STrib_imm : ST_Imm<"memb", "STrib", u6_0Imm>, ImmRegRel;
+ defm STrih_imm : ST_Imm<"memh", "STrih", u6_1Imm>, ImmRegRel;
+ defm STriw_imm : ST_Imm<"memw", "STriw", u6_2Imm>, ImmRegRel;
+}
+
+let Predicates = [HasV4T], AddedComplexity = 10 in {
+def: Pat<(truncstorei8 s8ExtPred:$src3, (add IntRegs:$src1, u6_0ImmPred:$src2)),
+ (STrib_imm_V4 IntRegs:$src1, u6_0ImmPred:$src2, s8ExtPred:$src3)>;
+
+def: Pat<(truncstorei16 s8ExtPred:$src3, (add IntRegs:$src1,
+ u6_1ImmPred:$src2)),
+ (STrih_imm_V4 IntRegs:$src1, u6_1ImmPred:$src2, s8ExtPred:$src3)>;
+
+def: Pat<(store s8ExtPred:$src3, (add IntRegs:$src1, u6_2ImmPred:$src2)),
+ (STriw_imm_V4 IntRegs:$src1, u6_2ImmPred:$src2, s8ExtPred:$src3)>;
+}
+
+let AddedComplexity = 6 in
+def : Pat <(truncstorei8 s8ExtPred:$src2, (i32 IntRegs:$src1)),
+ (STrib_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
+ Requires<[HasV4T]>;
+
// memb(Ru<<#u2+#U6)=Rt
let AddedComplexity = 10 in
def STrib_shl_V4 : STInst<(outs),
@@ -1982,125 +1759,6 @@ def STrib_shl_V4 : STInst<(outs),
// Store byte conditionally.
// if ([!]Pv[.new]) memb(#u6)=Rt
-// if ([!]Pv[.new]) memb(Rs+#u6:0)=#S6
-// if (Pv) memb(Rs+#u6:0)=#S6
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrib_imm_cPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, s6Imm:$src4),
- "if ($src1) memb($src2+#$src3) = #$src4",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) memb(Rs+#u6:0)=#S6
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrib_imm_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, s6Imm:$src4),
- "if ($src1.new) memb($src2+#$src3) = #$src4",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memb(Rs+#u6:0)=#S6
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrib_imm_cNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, s6Imm:$src4),
- "if (!$src1) memb($src2+#$src3) = #$src4",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) memb(Rs+#u6:0)=#S6
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrib_imm_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, s6Imm:$src4),
- "if (!$src1.new) memb($src2+#$src3) = #$src4",
- []>,
- Requires<[HasV4T]>;
-
-// if ([!]Pv[.new]) memb(Rs+#u6:0)=Rt
-// if (Pv) memb(Rs+#u6:0)=Rt
-// if (Pv.new) memb(Rs+#u6:0)=Rt
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrib_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if ($src1.new) memb($addr) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memb(Rs+#u6:0)=Rt
-// if (!Pv.new) memb(Rs+#u6:0)=Rt
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrib_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if (!$src1.new) memb($addr) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memb(Rs+#u6:0)=Rt
-// if (!Pv) memb(Rs+#u6:0)=Rt
-// if (Pv.new) memb(Rs+#u6:0)=Rt
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrib_indexed_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, IntRegs:$src4),
- "if ($src1.new) memb($src2+#$src3) = $src4",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) memb(Rs+#u6:0)=Rt
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrib_indexed_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, IntRegs:$src4),
- "if (!$src1.new) memb($src2+#$src3) = $src4",
- []>,
- Requires<[HasV4T]>;
-
-// if ([!]Pv[.new]) memb(Rs+Ru<<#u2)=Rt
-// if (Pv) memb(Rs+Ru<<#u2)=Rt
-let AddedComplexity = 10,
- isPredicated = 1 in
-def STrib_indexed_shl_cPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if ($src1) memb($src2+$src3<<#$src4) = $src5",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) memb(Rs+Ru<<#u2)=Rt
-let AddedComplexity = 10,
- isPredicated = 1 in
-def STrib_indexed_shl_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if ($src1.new) memb($src2+$src3<<#$src4) = $src5",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memb(Rs+Ru<<#u2)=Rt
-let AddedComplexity = 10,
- isPredicated = 1 in
-def STrib_indexed_shl_cNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if (!$src1) memb($src2+$src3<<#$src4) = $src5",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) memb(Rs+Ru<<#u2)=Rt
-let AddedComplexity = 10,
- isPredicated = 1 in
-def STrib_indexed_shl_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if (!$src1.new) memb($src2+$src3<<#$src4) = $src5",
- []>,
- Requires<[HasV4T]>;
-
// if ([!]Pv[.new]) memb(Rx++#s4:0)=Rt
// if (Pv) memb(Rx++#s4:0)=Rt
// if (Pv.new) memb(Rx++#s4:0)=Rt
@@ -2127,29 +1785,14 @@ def POST_STbri_cdnNotPt_V4 : STInst2PI<(outs IntRegs:$dst),
// TODO: needs to be implemented
// memh(Re=#U6)=Rt.H
// memh(Rs+#s11:1)=Rt.H
-// memh(Rs+#u6:1)=#S8
-let AddedComplexity = 10, isPredicable = 1 in
-def STrih_imm_V4 : STInst<(outs),
- (ins IntRegs:$src1, u6_1Imm:$src2, s8Imm:$src3),
- "memh($src1+#$src2) = #$src3",
- [(truncstorei16 s8ImmPred:$src3, (add (i32 IntRegs:$src1),
- u6_1ImmPred:$src2))]>,
- Requires<[HasV4T]>;
+let AddedComplexity = 6 in
+def : Pat <(truncstorei16 s8ExtPred:$src2, (i32 IntRegs:$src1)),
+ (STrih_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
+ Requires<[HasV4T]>;
// memh(Rs+Ru<<#u2)=Rt.H
// TODO: needs to be implemented.
-// memh(Rs+Ru<<#u2)=Rt
-let AddedComplexity = 10, isPredicable = 1 in
-def STrih_indexed_shl_V4 : STInst<(outs),
- (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, IntRegs:$src4),
- "memh($src1+$src2<<#$src3) = $src4",
- [(truncstorei16 (i32 IntRegs:$src4),
- (add (i32 IntRegs:$src1),
- (shl (i32 IntRegs:$src2),
- u2ImmPred:$src3)))]>,
- Requires<[HasV4T]>;
-
// memh(Ru<<#u2+#U6)=Rt.H
// memh(Ru<<#u2+#U6)=Rt
let AddedComplexity = 10 in
@@ -2173,127 +1816,10 @@ def STrih_shl_V4 : STInst<(outs),
// if ([!]Pv[.new]) memh(#u6)=Rt.H
// if ([!]Pv[.new]) memh(#u6)=Rt
-// if ([!]Pv[.new]) memh(Rs+#u6:1)=#S6
-// if (Pv) memh(Rs+#u6:1)=#S6
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrih_imm_cPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, s6Imm:$src4),
- "if ($src1) memh($src2+#$src3) = #$src4",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) memh(Rs+#u6:1)=#S6
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrih_imm_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, s6Imm:$src4),
- "if ($src1.new) memh($src2+#$src3) = #$src4",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memh(Rs+#u6:1)=#S6
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrih_imm_cNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, s6Imm:$src4),
- "if (!$src1) memh($src2+#$src3) = #$src4",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) memh(Rs+#u6:1)=#S6
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrih_imm_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, s6Imm:$src4),
- "if (!$src1.new) memh($src2+#$src3) = #$src4",
- []>,
- Requires<[HasV4T]>;
// if ([!]Pv[.new]) memh(Rs+#u6:1)=Rt.H
// TODO: needs to be implemented.
-// if ([!]Pv[.new]) memh(Rs+#u6:1)=Rt
-// if (Pv) memh(Rs+#u6:1)=Rt
-// if (Pv.new) memh(Rs+#u6:1)=Rt
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrih_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if ($src1.new) memh($addr) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memh(Rs+#u6:1)=Rt
-// if (!Pv.new) memh(Rs+#u6:1)=Rt
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrih_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if (!$src1.new) memh($addr) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) memh(Rs+#u6:1)=Rt
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrih_indexed_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, IntRegs:$src4),
- "if ($src1.new) memh($src2+#$src3) = $src4",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) memh(Rs+#u6:1)=Rt
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrih_indexed_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, IntRegs:$src4),
- "if (!$src1.new) memh($src2+#$src3) = $src4",
- []>,
- Requires<[HasV4T]>;
-
-// if ([!]Pv[.new]) memh(Rs+Ru<<#u2)=Rt.H
-// if ([!]Pv[.new]) memh(Rs+Ru<<#u2)=Rt
-// if (Pv) memh(Rs+Ru<<#u2)=Rt
-let AddedComplexity = 10,
- isPredicated = 1 in
-def STrih_indexed_shl_cPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if ($src1) memh($src2+$src3<<#$src4) = $src5",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) memh(Rs+Ru<<#u2)=Rt
-let AddedComplexity = 10,
- isPredicated = 1 in
-def STrih_indexed_shl_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if ($src1.new) memh($src2+$src3<<#$src4) = $src5",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memh(Rs+Ru<<#u2)=Rt
-let AddedComplexity = 10,
- isPredicated = 1 in
-def STrih_indexed_shl_cNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if (!$src1) memh($src2+$src3<<#$src4) = $src5",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) memh(Rs+Ru<<#u2)=Rt
-let AddedComplexity = 10,
- isPredicated = 1 in
-def STrih_indexed_shl_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if (!$src1.new) memh($src2+$src3<<#$src4) = $src5",
- []>,
- Requires<[HasV4T]>;
-
// if ([!]Pv[.new]) memh(Rx++#s4:1)=Rt.H
// TODO: Needs to be implemented.
@@ -2331,25 +1857,10 @@ def STriw_pred_V4 : STInst2<(outs),
[]>,
Requires<[HasV4T]>;
-
-// memw(Rs+#u6:2)=#S8
-let AddedComplexity = 10, isPredicable = 1 in
-def STriw_imm_V4 : STInst<(outs),
- (ins IntRegs:$src1, u6_2Imm:$src2, s8Imm:$src3),
- "memw($src1+#$src2) = #$src3",
- [(store s8ImmPred:$src3, (add (i32 IntRegs:$src1),
- u6_2ImmPred:$src2))]>,
- Requires<[HasV4T]>;
-
-// memw(Rs+Ru<<#u2)=Rt
-let AddedComplexity = 10, isPredicable = 1 in
-def STriw_indexed_shl_V4 : STInst<(outs),
- (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, IntRegs:$src4),
- "memw($src1+$src2<<#$src3) = $src4",
- [(store (i32 IntRegs:$src4), (add (i32 IntRegs:$src1),
- (shl (i32 IntRegs:$src2),
- u2ImmPred:$src3)))]>,
- Requires<[HasV4T]>;
+let AddedComplexity = 6 in
+def : Pat <(store s8ExtPred:$src2, (i32 IntRegs:$src1)),
+ (STriw_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
+ Requires<[HasV4T]>;
// memw(Ru<<#u2+#U6)=Rt
let AddedComplexity = 10 in
@@ -2369,127 +1880,6 @@ def STriw_shl_V4 : STInst<(outs),
// memw(gp+#u16:2)=Rt
-// Store word conditionally.
-
-// if ([!]Pv[.new]) memw(Rs+#u6:2)=#S6
-// if (Pv) memw(Rs+#u6:2)=#S6
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STriw_imm_cPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, s6Imm:$src4),
- "if ($src1) memw($src2+#$src3) = #$src4",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) memw(Rs+#u6:2)=#S6
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STriw_imm_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, s6Imm:$src4),
- "if ($src1.new) memw($src2+#$src3) = #$src4",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memw(Rs+#u6:2)=#S6
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STriw_imm_cNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, s6Imm:$src4),
- "if (!$src1) memw($src2+#$src3) = #$src4",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) memw(Rs+#u6:2)=#S6
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STriw_imm_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, s6Imm:$src4),
- "if (!$src1.new) memw($src2+#$src3) = #$src4",
- []>,
- Requires<[HasV4T]>;
-
-// if ([!]Pv[.new]) memw(Rs+#u6:2)=Rt
-// if (Pv) memw(Rs+#u6:2)=Rt
-// if (Pv.new) memw(Rs+#u6:2)=Rt
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STriw_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if ($src1.new) memw($addr) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memw(Rs+#u6:2)=Rt
-// if (!Pv.new) memw(Rs+#u6:2)=Rt
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STriw_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if (!$src1.new) memw($addr) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memw(Rs+#u6:2)=Rt
-// if (!Pv) memw(Rs+#u6:2)=Rt
-// if (Pv.new) memw(Rs+#u6:2)=Rt
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STriw_indexed_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, IntRegs:$src4),
- "if ($src1.new) memw($src2+#$src3) = $src4",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) memw(Rs+#u6:2)=Rt
-let neverHasSideEffects = 1,
- isPredicated = 1 in
-def STriw_indexed_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, IntRegs:$src4),
- "if (!$src1.new) memw($src2+#$src3) = $src4",
- []>,
- Requires<[HasV4T]>;
-
-// if ([!]Pv[.new]) memw(Rs+Ru<<#u2)=Rt
-// if (Pv) memw(Rs+Ru<<#u2)=Rt
-let AddedComplexity = 10,
- isPredicated = 1 in
-def STriw_indexed_shl_cPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if ($src1) memw($src2+$src3<<#$src4) = $src5",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) memw(Rs+Ru<<#u2)=Rt
-let AddedComplexity = 10,
- isPredicated = 1 in
-def STriw_indexed_shl_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if ($src1.new) memw($src2+$src3<<#$src4) = $src5",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memw(Rs+Ru<<#u2)=Rt
-let AddedComplexity = 10,
- isPredicated = 1 in
-def STriw_indexed_shl_cNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if (!$src1) memw($src2+$src3<<#$src4) = $src5",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) memw(Rs+Ru<<#u2)=Rt
-let AddedComplexity = 10,
- isPredicated = 1 in
-def STriw_indexed_shl_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if (!$src1.new) memw($src2+$src3<<#$src4) = $src5",
- []>,
- Requires<[HasV4T]>;
-
// if ([!]Pv[.new]) memw(Rx++#s4:2)=Rt
// if (Pv) memw(Rx++#s4:2)=Rt
// if (Pv.new) memw(Rx++#s4:2)=Rt
@@ -2962,31 +2352,109 @@ def : Pat<(store (i32 IntRegs:$src1),
// NV/ST +
//===----------------------------------------------------------------------===//
-// Store new-value byte.
+// multiclass for new-value store instructions with base + immediate offset.
+//
+multiclass ST_Idxd_Pbase_nv<string mnemonic, RegisterClass RC,
+ Operand predImmOp, bit isNot, bit isPredNew> {
+ let PNewValue = !if(isPredNew, "new", "") 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) ",
+ ") ")#mnemonic#"($src2+#$src3) = $src4.new",
+ []>,
+ Requires<[HasV4T]>;
+}
+
+multiclass ST_Idxd_Pred_nv<string mnemonic, RegisterClass RC, Operand predImmOp,
+ bit PredNot> {
+ let PredSense = !if(PredNot, "false", "true") 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>;
+ }
+}
-// memb(Re=#U6)=Nt.new
-// memb(Rs+#s11:0)=Nt.new
-let mayStore = 1, isPredicable = 1 in
-def STrib_nv_V4 : NVInst_V4<(outs), (ins MEMri:$addr, IntRegs:$src1),
- "memb($addr) = $src1.new",
+let mayStore = 1, isNVStore = 1, neverHasSideEffects = 1, isExtendable = 1 in
+multiclass ST_Idxd_nv<string mnemonic, string CextOp, RegisterClass RC,
+ Operand ImmOp, Operand predImmOp, bits<5> ImmBits,
+ bits<5> PredImmBits> {
+
+ let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
+ let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
+ isPredicable = 1 in
+ def NAME#_nv_V4 : NVInst_V4<(outs),
+ (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
+ mnemonic#"($src1+#$src2) = $src3.new",
[]>,
Requires<[HasV4T]>;
-let mayStore = 1, isPredicable = 1 in
-def STrib_indexed_nv_V4 : NVInst_V4<(outs),
- (ins IntRegs:$src1, s11_0Imm:$src2, IntRegs:$src3),
- "memb($src1+#$src2) = $src3.new",
+ let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
+ isPredicated = 1 in {
+ defm Pt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 0>;
+ defm NotPt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 1>;
+ }
+ }
+}
+
+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;
+}
+
+// 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
+ def NAME#_nv_V4 : NVInst_V4<(outs),
+ (ins PredRegs:$src1, MEMri:$addr, RC: $src2),
+ !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
+ ") ")#mnemonic#"($addr) = $src2.new",
[]>,
Requires<[HasV4T]>;
+}
+
+multiclass ST_MEMri_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
+ let PredSense = !if(PredNot, "false", "true") in {
+ defm _c#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 0>;
+
+ // Predicate new
+ defm _cdn#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 1>;
+ }
+}
+
+let mayStore = 1, isNVStore = 1, isExtendable = 1, neverHasSideEffects = 1 in
+multiclass ST_MEMri_nv<string mnemonic, string CextOp, RegisterClass RC,
+ bits<5> ImmBits, bits<5> PredImmBits> {
-// memb(Rs+Ru<<#u2)=Nt.new
-let mayStore = 1, AddedComplexity = 10, isPredicable = 1 in
-def STrib_indexed_shl_nv_V4 : NVInst_V4<(outs),
- (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, IntRegs:$src4),
- "memb($src1+$src2<<#$src3) = $src4.new",
+ let CextOpcode = CextOp, BaseOpcode = CextOp in {
+ let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
+ isPredicable = 1 in
+ def NAME#_nv_V4 : NVInst_V4<(outs),
+ (ins MEMri:$addr, RC:$src),
+ mnemonic#"($addr) = $src.new",
[]>,
Requires<[HasV4T]>;
+ let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
+ neverHasSideEffects = 1, isPredicated = 1 in {
+ defm Pt : ST_MEMri_Pred_nv<mnemonic, RC, 0>;
+ defm NotPt : ST_MEMri_Pred_nv<mnemonic, RC, 1>;
+ }
+ }
+}
+
+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;
+}
+
// memb(Ru<<#u2+#U6)=Nt.new
let mayStore = 1, AddedComplexity = 10 in
def STrib_shl_nv_V4 : NVInst_V4<(outs),
@@ -3025,122 +2493,6 @@ def STb_GP_nv_V4 : NVInst_V4<(outs),
[]>,
Requires<[HasV4T]>;
-// Store new-value byte conditionally.
-// if ([!]Pv[.new]) memb(#u6)=Nt.new
-// if (Pv) memb(Rs+#u6:0)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrib_cPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if ($src1) memb($addr) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) memb(Rs+#u6:0)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrib_cdnPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if ($src1.new) memb($addr) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memb(Rs+#u6:0)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrib_cNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if (!$src1) memb($addr) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) memb(Rs+#u6:0)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrib_cdnNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if (!$src1.new) memb($addr) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memb(Rs+#u6:0)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrib_indexed_cPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, IntRegs:$src4),
- "if ($src1) memb($src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) memb(Rs+#u6:0)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrib_indexed_cdnPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, IntRegs:$src4),
- "if ($src1.new) memb($src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memb(Rs+#u6:0)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrib_indexed_cNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, IntRegs:$src4),
- "if (!$src1) memb($src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) memb(Rs+#u6:0)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrib_indexed_cdnNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, IntRegs:$src4),
- "if (!$src1.new) memb($src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
-
-// if ([!]Pv[.new]) memb(Rs+Ru<<#u2)=Nt.new
-// if (Pv) memb(Rs+Ru<<#u2)=Nt.new
-let mayStore = 1, AddedComplexity = 10,
- isPredicated = 1 in
-def STrib_indexed_shl_cPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if ($src1) memb($src2+$src3<<#$src4) = $src5.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) memb(Rs+Ru<<#u2)=Nt.new
-let mayStore = 1, AddedComplexity = 10,
- isPredicated = 1 in
-def STrib_indexed_shl_cdnPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if ($src1.new) memb($src2+$src3<<#$src4) = $src5.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memb(Rs+Ru<<#u2)=Nt.new
-let mayStore = 1, AddedComplexity = 10,
- isPredicated = 1 in
-def STrib_indexed_shl_cNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if (!$src1) memb($src2+$src3<<#$src4) = $src5.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) memb(Rs+Ru<<#u2)=Nt.new
-let mayStore = 1, AddedComplexity = 10,
- isPredicated = 1 in
-def STrib_indexed_shl_cdnNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if (!$src1.new) memb($src2+$src3<<#$src4) = $src5.new",
- []>,
- Requires<[HasV4T]>;
-
// if ([!]Pv[.new]) memb(Rx++#s4:0)=Nt.new
// if (Pv) memb(Rx++#s4:0)=Nt.new
let mayStore = 1, hasCtrlDep = 1,
@@ -3178,31 +2530,6 @@ def POST_STbri_cdnNotPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst),
[],"$src3 = $dst">,
Requires<[HasV4T]>;
-
-// Store new-value halfword.
-// memh(Re=#U6)=Nt.new
-// memh(Rs+#s11:1)=Nt.new
-let mayStore = 1, isPredicable = 1 in
-def STrih_nv_V4 : NVInst_V4<(outs), (ins MEMri:$addr, IntRegs:$src1),
- "memh($addr) = $src1.new",
- []>,
- Requires<[HasV4T]>;
-
-let mayStore = 1, isPredicable = 1 in
-def STrih_indexed_nv_V4 : NVInst_V4<(outs),
- (ins IntRegs:$src1, s11_1Imm:$src2, IntRegs:$src3),
- "memh($src1+#$src2) = $src3.new",
- []>,
- Requires<[HasV4T]>;
-
-// memh(Rs+Ru<<#u2)=Nt.new
-let mayStore = 1, AddedComplexity = 10, isPredicable = 1 in
-def STrih_indexed_shl_nv_V4 : NVInst_V4<(outs),
- (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, IntRegs:$src4),
- "memh($src1+$src2<<#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
// memh(Ru<<#u2+#U6)=Nt.new
let mayStore = 1, AddedComplexity = 10 in
def STrih_shl_nv_V4 : NVInst_V4<(outs),
@@ -3242,124 +2569,6 @@ def STh_GP_nv_V4 : NVInst_V4<(outs),
Requires<[HasV4T]>;
-// Store new-value halfword conditionally.
-
-// if ([!]Pv[.new]) memh(#u6)=Nt.new
-
-// if ([!]Pv[.new]) memh(Rs+#u6:1)=Nt.new
-// if (Pv) memh(Rs+#u6:1)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrih_cPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if ($src1) memh($addr) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) memh(Rs+#u6:1)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrih_cdnPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if ($src1.new) memh($addr) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memh(Rs+#u6:1)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrih_cNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if (!$src1) memh($addr) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) memh(Rs+#u6:1)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrih_cdnNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if (!$src1.new) memh($addr) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memh(Rs+#u6:1)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrih_indexed_cPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, IntRegs:$src4),
- "if ($src1) memh($src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) memh(Rs+#u6:1)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrih_indexed_cdnPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, IntRegs:$src4),
- "if ($src1.new) memh($src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memh(Rs+#u6:1)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrih_indexed_cNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, IntRegs:$src4),
- "if (!$src1) memh($src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) memh(Rs+#u6:1)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STrih_indexed_cdnNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, IntRegs:$src4),
- "if (!$src1.new) memh($src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
-// if ([!]Pv[.new]) memh(Rs+Ru<<#u2)=Nt.new
-// if (Pv) memh(Rs+Ru<<#u2)=Nt.new
-let mayStore = 1, AddedComplexity = 10,
- isPredicated = 1 in
-def STrih_indexed_shl_cPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if ($src1) memh($src2+$src3<<#$src4) = $src5.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) memh(Rs+Ru<<#u2)=Nt.new
-let mayStore = 1, AddedComplexity = 10,
- isPredicated = 1 in
-def STrih_indexed_shl_cdnPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if ($src1.new) memh($src2+$src3<<#$src4) = $src5.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memh(Rs+Ru<<#u2)=Nt.new
-let mayStore = 1, AddedComplexity = 10,
- isPredicated = 1 in
-def STrih_indexed_shl_cNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if (!$src1) memh($src2+$src3<<#$src4) = $src5.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) memh(Rs+Ru<<#u2)=Nt.new
-let mayStore = 1, AddedComplexity = 10,
- isPredicated = 1 in
-def STrih_indexed_shl_cdnNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if (!$src1.new) memh($src2+$src3<<#$src4) = $src5.new",
- []>,
- Requires<[HasV4T]>;
-
// if ([!]Pv[]) memh(Rx++#s4:1)=Nt.new
// if (Pv) memh(Rx++#s4:1)=Nt.new
let mayStore = 1, hasCtrlDep = 1,
@@ -3397,33 +2606,6 @@ def POST_SThri_cdnNotPt_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst),
[],"$src3 = $dst">,
Requires<[HasV4T]>;
-
-// Store new-value word.
-
-// memw(Re=#U6)=Nt.new
-// memw(Rs+#s11:2)=Nt.new
-let mayStore = 1, isPredicable = 1 in
-def STriw_nv_V4 : NVInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$src1),
- "memw($addr) = $src1.new",
- []>,
- Requires<[HasV4T]>;
-
-let mayStore = 1, isPredicable = 1 in
-def STriw_indexed_nv_V4 : NVInst_V4<(outs),
- (ins IntRegs:$src1, s11_2Imm:$src2, IntRegs:$src3),
- "memw($src1+#$src2) = $src3.new",
- []>,
- Requires<[HasV4T]>;
-
-// memw(Rs+Ru<<#u2)=Nt.new
-let mayStore = 1, AddedComplexity = 10, isPredicable = 1 in
-def STriw_indexed_shl_nv_V4 : NVInst_V4<(outs),
- (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, IntRegs:$src4),
- "memw($src1+$src2<<#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
// memw(Ru<<#u2+#U6)=Nt.new
let mayStore = 1, AddedComplexity = 10 in
def STriw_shl_nv_V4 : NVInst_V4<(outs),
@@ -3460,125 +2642,6 @@ def STw_GP_nv_V4 : NVInst_V4<(outs),
[]>,
Requires<[HasV4T]>;
-// Store new-value word conditionally.
-
-// if ([!]Pv[.new]) memw(#u6)=Nt.new
-
-// if ([!]Pv[.new]) memw(Rs+#u6:2)=Nt.new
-// if (Pv) memw(Rs+#u6:2)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STriw_cPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if ($src1) memw($addr) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) memw(Rs+#u6:2)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STriw_cdnPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if ($src1.new) memw($addr) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memw(Rs+#u6:2)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STriw_cNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if (!$src1) memw($addr) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) memw(Rs+#u6:2)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STriw_cdnNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
- "if (!$src1.new) memw($addr) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memw(Rs+#u6:2)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STriw_indexed_cPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, IntRegs:$src4),
- "if ($src1) memw($src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) memw(Rs+#u6:2)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STriw_indexed_cdnPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, IntRegs:$src4),
- "if ($src1.new) memw($src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memw(Rs+#u6:2)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STriw_indexed_cNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, IntRegs:$src4),
- "if (!$src1) memw($src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) memw(Rs+#u6:2)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1,
- isPredicated = 1 in
-def STriw_indexed_cdnNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, IntRegs:$src4),
- "if (!$src1.new) memw($src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
-
-// if ([!]Pv[.new]) memw(Rs+Ru<<#u2)=Nt.new
-// if (Pv) memw(Rs+Ru<<#u2)=Nt.new
-let mayStore = 1, AddedComplexity = 10,
- isPredicated = 1 in
-def STriw_indexed_shl_cPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if ($src1) memw($src2+$src3<<#$src4) = $src5.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv.new) memw(Rs+Ru<<#u2)=Nt.new
-let mayStore = 1, AddedComplexity = 10,
- isPredicated = 1 in
-def STriw_indexed_shl_cdnPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if ($src1.new) memw($src2+$src3<<#$src4) = $src5.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memw(Rs+Ru<<#u2)=Nt.new
-let mayStore = 1, AddedComplexity = 10,
- isPredicated = 1 in
-def STriw_indexed_shl_cNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if (!$src1) memw($src2+$src3<<#$src4) = $src5.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv.new) memw(Rs+Ru<<#u2)=Nt.new
-let mayStore = 1, AddedComplexity = 10,
- isPredicated = 1 in
-def STriw_indexed_shl_cdnNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- IntRegs:$src5),
- "if (!$src1.new) memw($src2+$src3<<#$src4) = $src5.new",
- []>,
- Requires<[HasV4T]>;
-
// if ([!]Pv[.new]) memw(Rx++#s4:2)=Nt.new
// if (Pv) memw(Rx++#s4:2)=Nt.new
let mayStore = 1, hasCtrlDep = 1,
@@ -4519,18 +3582,6 @@ def LSRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
//===----------------------------------------------------------------------===//
-// MEMw_ADDSUBi_indexed_V4:
-// pseudo operation for MEMw_ADDi_indexed_V4 and
-// MEMw_SUBi_indexed_V4 a later pass will change it
-// to the corresponding pattern.
-let AddedComplexity = 30 in
-def MEMw_ADDSUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_2Imm:$offset, m6Imm:$addend),
- "Error; should not emit",
- [(store (add (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
- m6ImmPred:$addend),
- (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
// memw(Rs+#u6:2) += #U5
let AddedComplexity = 30 in
@@ -4588,17 +3639,6 @@ def MEMw_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
(add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
Requires<[HasV4T, UseMEMOP]>;
-// MEMw_ADDSUBi_V4:
-// Pseudo operation for MEMw_ADDi_V4 and MEMw_SUBi_V4
-// a later pass will change it to the right pattern.
-let AddedComplexity = 30 in
-def MEMw_ADDSUBi_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, m6Imm:$addend),
- "Error; should not emit",
- [(store (add (load ADDRriU6_2:$addr), m6ImmPred:$addend),
- ADDRriU6_2:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
// memw(Rs+#u6:2) += #U5
let AddedComplexity = 30 in
def MEMw_ADDi_MEM_V4 : MEMInst_V4<(outs),
@@ -4676,20 +3716,6 @@ def MEMw_ORr_MEM_V4 : MEMInst_V4<(outs),
//===----------------------------------------------------------------------===//
-// MEMh_ADDSUBi_indexed_V4:
-// Pseudo operation for MEMh_ADDi_indexed_V4 and
-// MEMh_SUBi_indexed_V4 a later pass will change it
-// to the corresponding pattern.
-let AddedComplexity = 30 in
-def MEMh_ADDSUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_1Imm:$offset, m6Imm:$addend),
- "Error; should not emit",
- [(truncstorei16 (add (sextloadi16 (add (i32 IntRegs:$base),
- u6_1ImmPred:$offset)),
- m6ImmPred:$addend),
- (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
// memh(Rs+#u6:1) += #U5
let AddedComplexity = 30 in
def MEMh_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
@@ -4750,17 +3776,6 @@ def MEMh_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
(add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
Requires<[HasV4T, UseMEMOP]>;
-// MEMh_ADDSUBi_V4:
-// Pseudo operation for MEMh_ADDi_V4 and MEMh_SUBi_V4
-// a later pass will change it to the right pattern.
-let AddedComplexity = 30 in
-def MEMh_ADDSUBi_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, m6Imm:$addend),
- "Error; should not emit",
- [(truncstorei16 (add (sextloadi16 ADDRriU6_1:$addr),
- m6ImmPred:$addend), ADDRriU6_1:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
// memh(Rs+#u6:1) += #U5
let AddedComplexity = 30 in
def MEMh_ADDi_MEM_V4 : MEMInst_V4<(outs),
@@ -4838,21 +3853,6 @@ def MEMh_ORr_MEM_V4 : MEMInst_V4<(outs),
// MEMb_SETi_V4 : memb(Rs+#u6:0)=setbit(#U5)
//===----------------------------------------------------------------------===//
-
-// MEMb_ADDSUBi_indexed_V4:
-// Pseudo operation for MEMb_ADDi_indexed_V4 and
-// MEMb_SUBi_indexed_V4 a later pass will change it
-// to the corresponding pattern.
-let AddedComplexity = 30 in
-def MEMb_ADDSUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_0Imm:$offset, m6Imm:$addend),
- "Error; should not emit",
- [(truncstorei8 (add (sextloadi8 (add (i32 IntRegs:$base),
- u6_0ImmPred:$offset)),
- m6ImmPred:$addend),
- (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
// memb(Rs+#u6:0) += #U5
let AddedComplexity = 30 in
def MEMb_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
@@ -4913,17 +3913,6 @@ def MEMb_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
(add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
Requires<[HasV4T, UseMEMOP]>;
-// MEMb_ADDSUBi_V4:
-// Pseudo operation for MEMb_ADDi_V4 and MEMb_SUBi_V4
-// a later pass will change it to the right pattern.
-let AddedComplexity = 30 in
-def MEMb_ADDSUBi_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, m6Imm:$addend),
- "Error; should not emit",
- [(truncstorei8 (add (sextloadi8 ADDRriU6_0:$addr),
- m6ImmPred:$addend), ADDRriU6_0:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
// memb(Rs+#u6:0) += #U5
let AddedComplexity = 30 in
def MEMb_ADDi_MEM_V4 : MEMInst_V4<(outs),
diff --git a/lib/Target/Hexagon/HexagonMCInst.h b/lib/Target/Hexagon/HexagonMCInst.h
index 7a16c24..e16636e 100644
--- a/lib/Target/Hexagon/HexagonMCInst.h
+++ b/lib/Target/Hexagon/HexagonMCInst.h
@@ -14,8 +14,8 @@
#ifndef HEXAGONMCINST_H
#define HEXAGONMCINST_H
-#include "llvm/MC/MCInst.h"
#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/MC/MCInst.h"
namespace llvm {
class HexagonMCInst: public MCInst {
diff --git a/lib/Target/Hexagon/HexagonMCInstLower.cpp b/lib/Target/Hexagon/HexagonMCInstLower.cpp
index 70bddcc..db36ac0 100644
--- a/lib/Target/Hexagon/HexagonMCInstLower.cpp
+++ b/lib/Target/Hexagon/HexagonMCInstLower.cpp
@@ -15,8 +15,8 @@
#include "Hexagon.h"
#include "HexagonAsmPrinter.h"
#include "HexagonMachineFunctionInfo.h"
-#include "llvm/Constants.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/IR/Constants.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/Target/Mangler.h"
diff --git a/lib/Target/Hexagon/HexagonMachineScheduler.cpp b/lib/Target/Hexagon/HexagonMachineScheduler.cpp
index b131a8f..aef6830 100644
--- a/lib/Target/Hexagon/HexagonMachineScheduler.cpp
+++ b/lib/Target/Hexagon/HexagonMachineScheduler.cpp
@@ -15,205 +15,22 @@
#define DEBUG_TYPE "misched"
#include "HexagonMachineScheduler.h"
-
#include <queue>
using namespace llvm;
-static cl::opt<bool> ForceTopDown("vliw-misched-topdown", cl::Hidden,
- cl::desc("Force top-down list scheduling"));
-static cl::opt<bool> ForceBottomUp("vliw-misched-bottomup", cl::Hidden,
- cl::desc("Force bottom-up list scheduling"));
-
-#ifndef NDEBUG
-static cl::opt<bool> ViewMISchedDAGs("vliw-view-misched-dags", cl::Hidden,
- cl::desc("Pop up a window to show MISched dags after they are processed"));
-
-static cl::opt<unsigned> MISchedCutoff("vliw-misched-cutoff", cl::Hidden,
- cl::desc("Stop scheduling after N instructions"), cl::init(~0U));
-#else
-static bool ViewMISchedDAGs = false;
-#endif // NDEBUG
-
-/// Decrement this iterator until reaching the top or a non-debug instr.
-static MachineBasicBlock::iterator
-priorNonDebug(MachineBasicBlock::iterator I, MachineBasicBlock::iterator Beg) {
- assert(I != Beg && "reached the top of the region, cannot decrement");
- while (--I != Beg) {
- if (!I->isDebugValue())
- break;
- }
- return I;
-}
-
-/// If this iterator is a debug value, increment until reaching the End or a
-/// non-debug instruction.
-static MachineBasicBlock::iterator
-nextIfDebug(MachineBasicBlock::iterator I, MachineBasicBlock::iterator End) {
- for(; I != End; ++I) {
- if (!I->isDebugValue())
- break;
- }
- return I;
-}
-
-/// ReleaseSucc - Decrement the NumPredsLeft count of a successor. When
-/// NumPredsLeft reaches zero, release the successor node.
-///
-/// FIXME: Adjust SuccSU height based on MinLatency.
-void VLIWMachineScheduler::releaseSucc(SUnit *SU, SDep *SuccEdge) {
- SUnit *SuccSU = SuccEdge->getSUnit();
-
-#ifndef NDEBUG
- if (SuccSU->NumPredsLeft == 0) {
- dbgs() << "*** Scheduling failed! ***\n";
- SuccSU->dump(this);
- dbgs() << " has been released too many times!\n";
- llvm_unreachable(0);
- }
-#endif
- --SuccSU->NumPredsLeft;
- if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU)
- SchedImpl->releaseTopNode(SuccSU);
-}
-
-/// releaseSuccessors - Call releaseSucc on each of SU's successors.
-void VLIWMachineScheduler::releaseSuccessors(SUnit *SU) {
- for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
- I != E; ++I) {
- releaseSucc(SU, &*I);
- }
-}
-
-/// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. When
-/// NumSuccsLeft reaches zero, release the predecessor node.
-///
-/// FIXME: Adjust PredSU height based on MinLatency.
-void VLIWMachineScheduler::releasePred(SUnit *SU, SDep *PredEdge) {
- SUnit *PredSU = PredEdge->getSUnit();
-
-#ifndef NDEBUG
- if (PredSU->NumSuccsLeft == 0) {
- dbgs() << "*** Scheduling failed! ***\n";
- PredSU->dump(this);
- dbgs() << " has been released too many times!\n";
- llvm_unreachable(0);
- }
-#endif
- --PredSU->NumSuccsLeft;
- if (PredSU->NumSuccsLeft == 0 && PredSU != &EntrySU)
- SchedImpl->releaseBottomNode(PredSU);
-}
-
-/// releasePredecessors - Call releasePred on each of SU's predecessors.
-void VLIWMachineScheduler::releasePredecessors(SUnit *SU) {
- for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
- I != E; ++I) {
- releasePred(SU, &*I);
- }
-}
-
-void VLIWMachineScheduler::moveInstruction(MachineInstr *MI,
- MachineBasicBlock::iterator InsertPos) {
- // Advance RegionBegin if the first instruction moves down.
- if (&*RegionBegin == MI)
- ++RegionBegin;
-
- // Update the instruction stream.
- BB->splice(InsertPos, BB, MI);
-
- // Update LiveIntervals
- LIS->handleMove(MI);
-
- // Recede RegionBegin if an instruction moves above the first.
- if (RegionBegin == InsertPos)
- RegionBegin = MI;
-}
-
-bool VLIWMachineScheduler::checkSchedLimit() {
-#ifndef NDEBUG
- if (NumInstrsScheduled == MISchedCutoff && MISchedCutoff != ~0U) {
- CurrentTop = CurrentBottom;
- return false;
- }
- ++NumInstrsScheduled;
-#endif
- return true;
-}
-
-/// enterRegion - Called back from MachineScheduler::runOnMachineFunction after
-/// crossing a scheduling boundary. [begin, end) includes all instructions in
-/// the region, including the boundary itself and single-instruction regions
-/// that don't get scheduled.
-void VLIWMachineScheduler::enterRegion(MachineBasicBlock *bb,
- MachineBasicBlock::iterator begin,
- MachineBasicBlock::iterator end,
- unsigned endcount)
-{
- ScheduleDAGInstrs::enterRegion(bb, begin, end, endcount);
-
- // For convenience remember the end of the liveness region.
- LiveRegionEnd =
- (RegionEnd == bb->end()) ? RegionEnd : llvm::next(RegionEnd);
-}
-
-// Setup the register pressure trackers for the top scheduled top and bottom
-// scheduled regions.
-void VLIWMachineScheduler::initRegPressure() {
- TopRPTracker.init(&MF, RegClassInfo, LIS, BB, RegionBegin);
- BotRPTracker.init(&MF, RegClassInfo, LIS, BB, LiveRegionEnd);
-
- // Close the RPTracker to finalize live ins.
- RPTracker.closeRegion();
-
- DEBUG(RPTracker.getPressure().dump(TRI));
-
- // Initialize the live ins and live outs.
- TopRPTracker.addLiveRegs(RPTracker.getPressure().LiveInRegs);
- BotRPTracker.addLiveRegs(RPTracker.getPressure().LiveOutRegs);
-
- // Close one end of the tracker so we can call
- // getMaxUpward/DownwardPressureDelta before advancing across any
- // instructions. This converts currently live regs into live ins/outs.
- TopRPTracker.closeTop();
- BotRPTracker.closeBottom();
-
- // Account for liveness generated by the region boundary.
- if (LiveRegionEnd != RegionEnd)
- BotRPTracker.recede();
-
- assert(BotRPTracker.getPos() == RegionEnd && "Can't find the region bottom");
-
- // Cache the list of excess pressure sets in this region. This will also track
- // the max pressure in the scheduled code for these sets.
- RegionCriticalPSets.clear();
- std::vector<unsigned> RegionPressure = RPTracker.getPressure().MaxSetPressure;
- for (unsigned i = 0, e = RegionPressure.size(); i < e; ++i) {
- unsigned Limit = TRI->getRegPressureSetLimit(i);
- DEBUG(dbgs() << TRI->getRegPressureSetName(i)
- << "Limit " << Limit
- << " Actual " << RegionPressure[i] << "\n");
- if (RegionPressure[i] > Limit)
- RegionCriticalPSets.push_back(PressureElement(i, 0));
- }
- DEBUG(dbgs() << "Excess PSets: ";
- for (unsigned i = 0, e = RegionCriticalPSets.size(); i != e; ++i)
- dbgs() << TRI->getRegPressureSetName(
- RegionCriticalPSets[i].PSetID) << " ";
- dbgs() << "\n");
-
- TotalPackets = 0;
-}
-
-// FIXME: When the pressure tracker deals in pressure differences then we won't
-// iterate over all RegionCriticalPSets[i].
-void VLIWMachineScheduler::
-updateScheduledPressure(std::vector<unsigned> NewMaxPressure) {
- for (unsigned i = 0, e = RegionCriticalPSets.size(); i < e; ++i) {
- unsigned ID = RegionCriticalPSets[i].PSetID;
- int &MaxUnits = RegionCriticalPSets[i].UnitIncrease;
- if ((int)NewMaxPressure[ID] > MaxUnits)
- MaxUnits = NewMaxPressure[ID];
+/// Platform specific modifications to DAG.
+void VLIWMachineScheduler::postprocessDAG() {
+ SUnit* LastSequentialCall = NULL;
+ // Currently we only catch the situation when compare gets scheduled
+ // before preceding call.
+ for (unsigned su = 0, e = SUnits.size(); su != e; ++su) {
+ // Remember the call.
+ if (SUnits[su].getInstr()->isCall())
+ LastSequentialCall = &(SUnits[su]);
+ // Look for a compare that defines a predicate.
+ else if (SUnits[su].getInstr()->isCompare() && LastSequentialCall)
+ SUnits[su].addPred(SDep(LastSequentialCall, SDep::Barrier));
}
}
@@ -264,6 +81,13 @@ bool VLIWResourceModel::isResourceAvailable(SUnit *SU) {
/// Keep track of available resources.
bool VLIWResourceModel::reserveResources(SUnit *SU) {
bool startNewCycle = false;
+ // Artificially reset state.
+ if (!SU) {
+ ResourcesModel->clearResources();
+ Packet.clear();
+ TotalPackets++;
+ return false;
+ }
// If this SU does not fit in the packet
// start a new one.
if (!isResourceAvailable(SU)) {
@@ -302,7 +126,7 @@ bool VLIWResourceModel::reserveResources(SUnit *SU) {
// If packet is now full, reset the state so in the next cycle
// we start fresh.
- if (Packet.size() >= InstrItins->SchedModel->IssueWidth) {
+ if (Packet.size() >= SchedModel->getIssueWidth()) {
ResourcesModel->clearResources();
Packet.clear();
TotalPackets++;
@@ -312,26 +136,6 @@ bool VLIWResourceModel::reserveResources(SUnit *SU) {
return startNewCycle;
}
-// Release all DAG roots for scheduling.
-void VLIWMachineScheduler::releaseRoots() {
- SmallVector<SUnit*, 16> BotRoots;
-
- for (std::vector<SUnit>::iterator
- I = SUnits.begin(), E = SUnits.end(); I != E; ++I) {
- // A SUnit is ready to top schedule if it has no predecessors.
- if (I->Preds.empty())
- SchedImpl->releaseTopNode(&(*I));
- // A SUnit is ready to bottom schedule if it has no successors.
- if (I->Succs.empty())
- BotRoots.push_back(&(*I));
- }
- // Release bottom roots in reverse order so the higher priority nodes appear
- // first. This is more natural and slightly more efficient.
- for (SmallVectorImpl<SUnit*>::const_reverse_iterator
- I = BotRoots.rbegin(), E = BotRoots.rend(); I != E; ++I)
- SchedImpl->releaseBottomNode(*I);
-}
-
/// schedule - Called back from MachineScheduler::runOnMachineFunction
/// after setting up the current scheduling region. [RegionBegin, RegionEnd)
/// only includes instructions that have DAG nodes, not scheduling boundaries.
@@ -340,21 +144,13 @@ void VLIWMachineScheduler::schedule() {
<< "********** MI Converging Scheduling VLIW BB#" << BB->getNumber()
<< " " << BB->getName()
<< " in_func " << BB->getParent()->getFunction()->getName()
- << " at loop depth " << MLI->getLoopDepth(BB)
+ << " at loop depth " << MLI.getLoopDepth(BB)
<< " \n");
- // Initialize the register pressure tracker used by buildSchedGraph.
- RPTracker.init(&MF, RegClassInfo, LIS, BB, LiveRegionEnd);
-
- // Account for liveness generate by the region boundary.
- if (LiveRegionEnd != RegionEnd)
- RPTracker.recede();
+ buildDAGWithRegPressure();
- // Build the DAG, and compute current register pressure.
- buildSchedGraph(AA, &RPTracker);
-
- // Initialize top/bottom trackers after computing region pressure.
- initRegPressure();
+ // Postprocess the DAG to add platform specific artificial dependencies.
+ postprocessDAG();
// To view Height/Depth correctly, they should be accessed at least once.
DEBUG(unsigned maxH = 0;
@@ -370,110 +166,40 @@ void VLIWMachineScheduler::schedule() {
DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
SUnits[su].dumpAll(this));
- if (ViewMISchedDAGs) viewGraph();
-
- SchedImpl->initialize(this);
-
- // Release edges from the special Entry node or to the special Exit node.
- releaseSuccessors(&EntrySU);
- releasePredecessors(&ExitSU);
-
- // Release all DAG roots for scheduling.
- releaseRoots();
+ initQueues();
- CurrentTop = nextIfDebug(RegionBegin, RegionEnd);
- CurrentBottom = RegionEnd;
bool IsTopNode = false;
while (SUnit *SU = SchedImpl->pickNode(IsTopNode)) {
if (!checkSchedLimit())
break;
- // Move the instruction to its new location in the instruction stream.
- MachineInstr *MI = SU->getInstr();
-
- if (IsTopNode) {
- assert(SU->isTopReady() && "node still has unscheduled dependencies");
- if (&*CurrentTop == MI)
- CurrentTop = nextIfDebug(++CurrentTop, CurrentBottom);
- else {
- moveInstruction(MI, CurrentTop);
- TopRPTracker.setPos(MI);
- }
-
- // Update top scheduled pressure.
- TopRPTracker.advance();
- assert(TopRPTracker.getPos() == CurrentTop && "out of sync");
- updateScheduledPressure(TopRPTracker.getPressure().MaxSetPressure);
-
- // Release dependent instructions for scheduling.
- releaseSuccessors(SU);
- } else {
- assert(SU->isBottomReady() && "node still has unscheduled dependencies");
- MachineBasicBlock::iterator priorII =
- priorNonDebug(CurrentBottom, CurrentTop);
- if (&*priorII == MI)
- CurrentBottom = priorII;
- else {
- if (&*CurrentTop == MI) {
- CurrentTop = nextIfDebug(++CurrentTop, priorII);
- TopRPTracker.setPos(CurrentTop);
- }
- moveInstruction(MI, CurrentBottom);
- CurrentBottom = MI;
- }
- // Update bottom scheduled pressure.
- BotRPTracker.recede();
- assert(BotRPTracker.getPos() == CurrentBottom && "out of sync");
- updateScheduledPressure(BotRPTracker.getPressure().MaxSetPressure);
-
- // Release dependent instructions for scheduling.
- releasePredecessors(SU);
- }
- SU->isScheduled = true;
- SchedImpl->schedNode(SU, IsTopNode);
+ scheduleMI(SU, IsTopNode);
+
+ updateQueues(SU, IsTopNode);
}
assert(CurrentTop == CurrentBottom && "Nonempty unscheduled zone.");
placeDebugValues();
}
-/// Reinsert any remaining debug_values, just like the PostRA scheduler.
-void VLIWMachineScheduler::placeDebugValues() {
- // If first instruction was a DBG_VALUE then put it back.
- if (FirstDbgValue) {
- BB->splice(RegionBegin, BB, FirstDbgValue);
- RegionBegin = FirstDbgValue;
- }
-
- for (std::vector<std::pair<MachineInstr *, MachineInstr *> >::iterator
- DI = DbgValues.end(), DE = DbgValues.begin(); DI != DE; --DI) {
- std::pair<MachineInstr *, MachineInstr *> P = *prior(DI);
- MachineInstr *DbgValue = P.first;
- MachineBasicBlock::iterator OrigPrevMI = P.second;
- BB->splice(++OrigPrevMI, BB, DbgValue);
- if (OrigPrevMI == llvm::prior(RegionEnd))
- RegionEnd = DbgValue;
- }
- DbgValues.clear();
- FirstDbgValue = NULL;
-}
-
-void ConvergingVLIWScheduler::initialize(VLIWMachineScheduler *dag) {
- DAG = dag;
+void ConvergingVLIWScheduler::initialize(ScheduleDAGMI *dag) {
+ DAG = static_cast<VLIWMachineScheduler*>(dag);
+ SchedModel = DAG->getSchedModel();
TRI = DAG->TRI;
- Top.DAG = dag;
- Bot.DAG = dag;
+ Top.init(DAG, SchedModel);
+ Bot.init(DAG, SchedModel);
- // Initialize the HazardRecognizers.
+ // Initialize the HazardRecognizers. If itineraries don't exist, are empty, or
+ // are disabled, then these HazardRecs will be disabled.
+ const InstrItineraryData *Itin = DAG->getSchedModel()->getInstrItineraries();
const TargetMachine &TM = DAG->MF.getTarget();
- const InstrItineraryData *Itin = TM.getInstrItineraryData();
Top.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG);
Bot.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG);
- Top.ResourceModel = new VLIWResourceModel(TM);
- Bot.ResourceModel = new VLIWResourceModel(TM);
+ Top.ResourceModel = new VLIWResourceModel(TM, DAG->getSchedModel());
+ Bot.ResourceModel = new VLIWResourceModel(TM, DAG->getSchedModel());
- assert((!ForceTopDown || !ForceBottomUp) &&
+ assert((!llvm::ForceTopDown || !llvm::ForceBottomUp) &&
"-misched-topdown incompatible with -misched-bottomup");
}
@@ -530,7 +256,8 @@ bool ConvergingVLIWScheduler::SchedBoundary::checkHazard(SUnit *SU) {
if (HazardRec->isEnabled())
return HazardRec->getHazardType(SU) != ScheduleHazardRecognizer::NoHazard;
- if (IssueCount + DAG->getNumMicroOps(SU->getInstr()) > DAG->getIssueWidth())
+ unsigned uops = SchedModel->getNumMicroOps(SU->getInstr());
+ if (IssueCount + uops > SchedModel->getIssueWidth())
return true;
return false;
@@ -552,7 +279,7 @@ void ConvergingVLIWScheduler::SchedBoundary::releaseNode(SUnit *SU,
/// Move the boundary of scheduled code by one cycle.
void ConvergingVLIWScheduler::SchedBoundary::bumpCycle() {
- unsigned Width = DAG->getIssueWidth();
+ unsigned Width = SchedModel->getIssueWidth();
IssueCount = (IssueCount <= Width) ? 0 : IssueCount - Width;
assert(MinReadyCycle < UINT_MAX && "MinReadyCycle uninitialized");
@@ -595,7 +322,7 @@ void ConvergingVLIWScheduler::SchedBoundary::bumpNode(SUnit *SU) {
// Check the instruction group dispatch limit.
// TODO: Check if this SU must end a dispatch group.
- IssueCount += DAG->getNumMicroOps(SU->getInstr());
+ IssueCount += SchedModel->getNumMicroOps(SU->getInstr());
if (startNewCycle) {
DEBUG(dbgs() << "*** Max instrs at cycle " << CurrCycle << '\n');
bumpCycle();
@@ -654,6 +381,7 @@ SUnit *ConvergingVLIWScheduler::SchedBoundary::pickOnlyChoice() {
for (unsigned i = 0; Available.empty(); ++i) {
assert(i <= (HazardRec->getMaxLookAhead() + MaxMinLatency) &&
"permanent hazard"); (void)i;
+ ResourceModel->reserveResources(0);
bumpCycle();
releasePending();
}
@@ -899,7 +627,7 @@ SUnit *ConvergingVLIWScheduler::pickNode(bool &IsTopNode) {
return NULL;
}
SUnit *SU;
- if (ForceTopDown) {
+ if (llvm::ForceTopDown) {
SU = Top.pickOnlyChoice();
if (!SU) {
SchedCandidate TopCand;
@@ -910,7 +638,7 @@ SUnit *ConvergingVLIWScheduler::pickNode(bool &IsTopNode) {
SU = TopCand.SU;
}
IsTopNode = true;
- } else if (ForceBottomUp) {
+ } else if (llvm::ForceBottomUp) {
SU = Bot.pickOnlyChoice();
if (!SU) {
SchedCandidate BotCand;
diff --git a/lib/Target/Hexagon/HexagonMachineScheduler.h b/lib/Target/Hexagon/HexagonMachineScheduler.h
index f3643d6..f68dadf 100644
--- a/lib/Target/Hexagon/HexagonMachineScheduler.h
+++ b/lib/Target/Hexagon/HexagonMachineScheduler.h
@@ -14,6 +14,9 @@
#ifndef HEXAGONASMPRINTER_H
#define HEXAGONASMPRINTER_H
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/PriorityQueue.h"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/MachineScheduler.h"
#include "llvm/CodeGen/Passes.h"
@@ -22,115 +25,27 @@
#include "llvm/CodeGen/ResourcePriorityQueue.h"
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/PriorityQueue.h"
+#include "llvm/Target/TargetInstrInfo.h"
using namespace llvm;
-//===----------------------------------------------------------------------===//
-// MachineSchedStrategy - Interface to a machine scheduling algorithm.
-//===----------------------------------------------------------------------===//
-
namespace llvm {
-class VLIWMachineScheduler;
-
-/// MachineSchedStrategy - Interface used by VLIWMachineScheduler to drive
-/// the selected scheduling algorithm.
-///
-/// TODO: Move this to ScheduleDAGInstrs.h
-class MachineSchedStrategy {
-public:
- virtual ~MachineSchedStrategy() {}
-
- /// Initialize the strategy after building the DAG for a new region.
- virtual void initialize(VLIWMachineScheduler *DAG) = 0;
-
- /// Pick the next node to schedule, or return NULL. Set IsTopNode to true to
- /// schedule the node at the top of the unscheduled region. Otherwise it will
- /// be scheduled at the bottom.
- virtual SUnit *pickNode(bool &IsTopNode) = 0;
-
- /// Notify MachineSchedStrategy that VLIWMachineScheduler has
- /// scheduled a node.
- virtual void schedNode(SUnit *SU, bool IsTopNode) = 0;
-
- /// When all predecessor dependencies have been resolved, free this node for
- /// top-down scheduling.
- virtual void releaseTopNode(SUnit *SU) = 0;
- /// When all successor dependencies have been resolved, free this node for
- /// bottom-up scheduling.
- virtual void releaseBottomNode(SUnit *SU) = 0;
-};
-
//===----------------------------------------------------------------------===//
// ConvergingVLIWScheduler - Implementation of the standard
// MachineSchedStrategy.
//===----------------------------------------------------------------------===//
-/// ReadyQueue encapsulates vector of "ready" SUnits with basic convenience
-/// methods for pushing and removing nodes. ReadyQueue's are uniquely identified
-/// by an ID. SUnit::NodeQueueId is a mask of the ReadyQueues the SUnit is in.
-class ReadyQueue {
- unsigned ID;
- std::string Name;
- std::vector<SUnit*> Queue;
-
-public:
- ReadyQueue(unsigned id, const Twine &name): ID(id), Name(name.str()) {}
-
- unsigned getID() const { return ID; }
-
- StringRef getName() const { return Name; }
-
- // SU is in this queue if it's NodeQueueID is a superset of this ID.
- bool isInQueue(SUnit *SU) const { return (SU->NodeQueueId & ID); }
-
- bool empty() const { return Queue.empty(); }
-
- unsigned size() const { return Queue.size(); }
-
- typedef std::vector<SUnit*>::iterator iterator;
-
- iterator begin() { return Queue.begin(); }
-
- iterator end() { return Queue.end(); }
-
- iterator find(SUnit *SU) {
- return std::find(Queue.begin(), Queue.end(), SU);
- }
-
- void push(SUnit *SU) {
- Queue.push_back(SU);
- SU->NodeQueueId |= ID;
- }
-
- void remove(iterator I) {
- (*I)->NodeQueueId &= ~ID;
- *I = Queue.back();
- Queue.pop_back();
- }
-
- void dump() {
- dbgs() << Name << ": ";
- for (unsigned i = 0, e = Queue.size(); i < e; ++i)
- dbgs() << Queue[i]->NodeNum << " ";
- dbgs() << "\n";
- }
-};
-
class VLIWResourceModel {
/// ResourcesModel - Represents VLIW state.
/// Not limited to VLIW targets per say, but assumes
/// definition of DFA by a target.
DFAPacketizer *ResourcesModel;
- const InstrItineraryData *InstrItins;
+ const TargetSchedModel *SchedModel;
/// Local packet/bundle model. Purely
/// internal to the MI schedulre at the time.
@@ -140,29 +55,15 @@ class VLIWResourceModel {
unsigned TotalPackets;
public:
- VLIWResourceModel(MachineSchedContext *C, const InstrItineraryData *IID) :
- InstrItins(IID), TotalPackets(0) {
- const TargetMachine &TM = C->MF->getTarget();
- ResourcesModel = TM.getInstrInfo()->CreateTargetScheduleState(&TM,NULL);
-
- // This hard requirement could be relaxed,
- // but for now do not let it proceed.
- assert(ResourcesModel && "Unimplemented CreateTargetScheduleState.");
-
- Packet.resize(InstrItins->SchedModel->IssueWidth);
- Packet.clear();
- ResourcesModel->clearResources();
- }
-
- VLIWResourceModel(const TargetMachine &TM) :
- InstrItins(TM.getInstrItineraryData()), TotalPackets(0) {
+VLIWResourceModel(const TargetMachine &TM, const TargetSchedModel *SM) :
+ SchedModel(SM), TotalPackets(0) {
ResourcesModel = TM.getInstrInfo()->CreateTargetScheduleState(&TM,NULL);
// This hard requirement could be relaxed,
// but for now do not let it proceed.
assert(ResourcesModel && "Unimplemented CreateTargetScheduleState.");
- Packet.resize(InstrItins->SchedModel->IssueWidth);
+ Packet.resize(SchedModel->getIssueWidth());
Packet.clear();
ResourcesModel->clearResources();
}
@@ -189,124 +90,18 @@ public:
unsigned getTotalPackets() const { return TotalPackets; }
};
-class VLIWMachineScheduler : public ScheduleDAGInstrs {
- /// AA - AliasAnalysis for making memory reference queries.
- AliasAnalysis *AA;
-
- RegisterClassInfo *RegClassInfo;
- MachineSchedStrategy *SchedImpl;
-
- MachineBasicBlock::iterator LiveRegionEnd;
-
- /// Register pressure in this region computed by buildSchedGraph.
- IntervalPressure RegPressure;
- RegPressureTracker RPTracker;
-
- /// List of pressure sets that exceed the target's pressure limit before
- /// scheduling, listed in increasing set ID order. Each pressure set is paired
- /// with its max pressure in the currently scheduled regions.
- std::vector<PressureElement> RegionCriticalPSets;
-
- /// The top of the unscheduled zone.
- MachineBasicBlock::iterator CurrentTop;
- IntervalPressure TopPressure;
- RegPressureTracker TopRPTracker;
-
- /// The bottom of the unscheduled zone.
- MachineBasicBlock::iterator CurrentBottom;
- IntervalPressure BotPressure;
- RegPressureTracker BotRPTracker;
-
-#ifndef NDEBUG
- /// The number of instructions scheduled so far. Used to cut off the
- /// scheduler at the point determined by misched-cutoff.
- unsigned NumInstrsScheduled;
-#endif
-
- /// Total packets in the region.
- unsigned TotalPackets;
-
- const MachineLoopInfo *MLI;
+/// Extend the standard ScheduleDAGMI to provide more context and override the
+/// top-level schedule() driver.
+class VLIWMachineScheduler : public ScheduleDAGMI {
public:
VLIWMachineScheduler(MachineSchedContext *C, MachineSchedStrategy *S):
- ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
- AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S),
- RPTracker(RegPressure), CurrentTop(), TopRPTracker(TopPressure),
- CurrentBottom(), BotRPTracker(BotPressure), MLI(C->MLI) {
-#ifndef NDEBUG
- NumInstrsScheduled = 0;
-#endif
- TotalPackets = 0;
- }
-
- virtual ~VLIWMachineScheduler() {
- delete SchedImpl;
- }
-
- MachineBasicBlock::iterator top() const { return CurrentTop; }
- MachineBasicBlock::iterator bottom() const { return CurrentBottom; }
-
- /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
- /// region. This covers all instructions in a block, while schedule() may only
- /// cover a subset.
- void enterRegion(MachineBasicBlock *bb,
- MachineBasicBlock::iterator begin,
- MachineBasicBlock::iterator end,
- unsigned endcount);
+ ScheduleDAGMI(C, S) {}
/// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's
/// time to do some work.
- void schedule();
-
- unsigned CurCycle;
-
- /// Get current register pressure for the top scheduled instructions.
- const IntervalPressure &getTopPressure() const { return TopPressure; }
- const RegPressureTracker &getTopRPTracker() const { return TopRPTracker; }
-
- /// Get current register pressure for the bottom scheduled instructions.
- const IntervalPressure &getBotPressure() const { return BotPressure; }
- const RegPressureTracker &getBotRPTracker() const { return BotRPTracker; }
-
- /// Get register pressure for the entire scheduling region before scheduling.
- const IntervalPressure &getRegPressure() const { return RegPressure; }
-
- const std::vector<PressureElement> &getRegionCriticalPSets() const {
- return RegionCriticalPSets;
- }
-
- /// getIssueWidth - Return the max instructions per scheduling group.
- unsigned getIssueWidth() const {
- return (InstrItins && InstrItins->SchedModel)
- ? InstrItins->SchedModel->IssueWidth : 1;
- }
-
- /// getNumMicroOps - Return the number of issue slots required for this MI.
- unsigned getNumMicroOps(MachineInstr *MI) const {
- return 1;
- //if (!InstrItins) return 1;
- //int UOps = InstrItins->getNumMicroOps(MI->getDesc().getSchedClass());
- //return (UOps >= 0) ? UOps : TII->getNumMicroOps(InstrItins, MI);
- }
-
-private:
- void scheduleNodeTopDown(SUnit *SU);
- void listScheduleTopDown();
-
- void initRegPressure();
- void updateScheduledPressure(std::vector<unsigned> NewMaxPressure);
-
- void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
- bool checkSchedLimit();
-
- void releaseRoots();
-
- void releaseSucc(SUnit *SU, SDep *SuccEdge);
- void releaseSuccessors(SUnit *SU);
- void releasePred(SUnit *SU, SDep *PredEdge);
- void releasePredecessors(SUnit *SU);
-
- void placeDebugValues();
+ virtual void schedule();
+ /// Perform platform specific DAG postprocessing.
+ void postprocessDAG();
};
/// ConvergingVLIWScheduler shrinks the unscheduled zone using heuristics
@@ -337,6 +132,7 @@ class ConvergingVLIWScheduler : public MachineSchedStrategy {
/// of "hazards" and other interlocks at the current cycle.
struct SchedBoundary {
VLIWMachineScheduler *DAG;
+ const TargetSchedModel *SchedModel;
ReadyQueue Available;
ReadyQueue Pending;
@@ -357,7 +153,7 @@ class ConvergingVLIWScheduler : public MachineSchedStrategy {
/// Pending queues extend the ready queues with the same ID and the
/// PendingFlag set.
SchedBoundary(unsigned ID, const Twine &Name):
- DAG(0), Available(ID, Name+".A"),
+ DAG(0), SchedModel(0), Available(ID, Name+".A"),
Pending(ID << ConvergingVLIWScheduler::LogMaxQID, Name+".P"),
CheckPending(false), HazardRec(0), ResourceModel(0),
CurrCycle(0), IssueCount(0),
@@ -368,6 +164,11 @@ class ConvergingVLIWScheduler : public MachineSchedStrategy {
delete HazardRec;
}
+ void init(VLIWMachineScheduler *dag, const TargetSchedModel *smodel) {
+ DAG = dag;
+ SchedModel = smodel;
+ }
+
bool isTop() const {
return Available.getID() == ConvergingVLIWScheduler::TopQID;
}
@@ -388,6 +189,7 @@ class ConvergingVLIWScheduler : public MachineSchedStrategy {
};
VLIWMachineScheduler *DAG;
+ const TargetSchedModel *SchedModel;
const TargetRegisterInfo *TRI;
// State of the top and bottom scheduled instruction boundaries.
@@ -403,9 +205,9 @@ public:
};
ConvergingVLIWScheduler():
- DAG(0), TRI(0), Top(TopQID, "TopQ"), Bot(BotQID, "BotQ") {}
+ DAG(0), SchedModel(0), TRI(0), Top(TopQID, "TopQ"), Bot(BotQID, "BotQ") {}
- virtual void initialize(VLIWMachineScheduler *dag);
+ virtual void initialize(ScheduleDAGMI *dag);
virtual SUnit *pickNode(bool &IsTopNode);
@@ -415,6 +217,11 @@ public:
virtual void releaseBottomNode(SUnit *SU);
+ unsigned ReportPackets() {
+ return Top.ResourceModel->getTotalPackets() +
+ Bot.ResourceModel->getTotalPackets();
+ }
+
protected:
SUnit *pickNodeBidrectional(bool &IsTopNode);
diff --git a/lib/Target/Hexagon/HexagonNewValueJump.cpp b/lib/Target/Hexagon/HexagonNewValueJump.cpp
index 1e91c39..cd3d289 100644
--- a/lib/Target/Hexagon/HexagonNewValueJump.cpp
+++ b/lib/Target/Hexagon/HexagonNewValueJump.cpp
@@ -22,31 +22,29 @@
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "hexagon-nvj"
-#include "llvm/PassSupport.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Debug.h"
+#include "Hexagon.h"
+#include "HexagonInstrInfo.h"
+#include "HexagonMachineFunctionInfo.h"
+#include "HexagonRegisterInfo.h"
+#include "HexagonSubtarget.h"
+#include "HexagonTargetMachine.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/ScheduleDAGInstrs.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/LiveVariables.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
-#include "llvm/Target/TargetMachine.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/ScheduleDAGInstrs.h"
+#include "llvm/PassSupport.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
-#include "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");
diff --git a/lib/Target/Hexagon/HexagonOperands.td b/lib/Target/Hexagon/HexagonOperands.td
new file mode 100644
index 0000000..c79d78f
--- /dev/null
+++ b/lib/Target/Hexagon/HexagonOperands.td
@@ -0,0 +1,858 @@
+//===- HexagonOperands.td - Hexagon immediate processing -*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illnois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Immediate operands.
+
+let PrintMethod = "printImmOperand" in {
+ // f32Ext type is used to identify constant extended floating point immediates.
+ def f32Ext : Operand<f32>;
+ def s32Imm : Operand<i32>;
+ def s26_6Imm : Operand<i32>;
+ def s16Imm : Operand<i32>;
+ def s12Imm : Operand<i32>;
+ def s11Imm : Operand<i32>;
+ def s11_0Imm : Operand<i32>;
+ def s11_1Imm : Operand<i32>;
+ def s11_2Imm : Operand<i32>;
+ def s11_3Imm : Operand<i32>;
+ def s10Imm : Operand<i32>;
+ def s9Imm : Operand<i32>;
+ def m9Imm : Operand<i32>;
+ def s8Imm : Operand<i32>;
+ def s8Imm64 : Operand<i64>;
+ def s6Imm : Operand<i32>;
+ def s4Imm : Operand<i32>;
+ def s4_0Imm : Operand<i32>;
+ def s4_1Imm : Operand<i32>;
+ def s4_2Imm : Operand<i32>;
+ def s4_3Imm : Operand<i32>;
+ def u64Imm : Operand<i64>;
+ def u32Imm : Operand<i32>;
+ def u26_6Imm : Operand<i32>;
+ def u16Imm : Operand<i32>;
+ def u16_0Imm : Operand<i32>;
+ def u16_1Imm : Operand<i32>;
+ def u16_2Imm : Operand<i32>;
+ def u11_3Imm : Operand<i32>;
+ def u10Imm : Operand<i32>;
+ def u9Imm : Operand<i32>;
+ def u8Imm : Operand<i32>;
+ def u7Imm : Operand<i32>;
+ def u6Imm : Operand<i32>;
+ def u6_0Imm : Operand<i32>;
+ def u6_1Imm : Operand<i32>;
+ def u6_2Imm : Operand<i32>;
+ def u6_3Imm : Operand<i32>;
+ def u5Imm : Operand<i32>;
+ def u4Imm : Operand<i32>;
+ def u3Imm : Operand<i32>;
+ def u2Imm : Operand<i32>;
+ def u1Imm : Operand<i32>;
+ def n8Imm : Operand<i32>;
+ def m6Imm : Operand<i32>;
+}
+
+let PrintMethod = "printNOneImmOperand" in
+def nOneImm : Operand<i32>;
+
+//
+// Immediate predicates
+//
+def s32ImmPred : PatLeaf<(i32 imm), [{
+ // s32ImmPred predicate - True if the immediate fits in a 32-bit sign extended
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isInt<32>(v);
+}]>;
+
+def s32_24ImmPred : PatLeaf<(i32 imm), [{
+ // s32_24ImmPred predicate - True if the immediate fits in a 32-bit sign
+ // extended field that is a multiple of 0x1000000.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isShiftedInt<32,24>(v);
+}]>;
+
+def s32_16s8ImmPred : PatLeaf<(i32 imm), [{
+ // s32_16s8ImmPred predicate - True if the immediate fits in a 32-bit sign
+ // extended field that is a multiple of 0x10000.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isShiftedInt<24,16>(v);
+}]>;
+
+def s26_6ImmPred : PatLeaf<(i32 imm), [{
+ // s26_6ImmPred predicate - True if the immediate fits in a 32-bit
+ // sign extended field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isShiftedInt<26,6>(v);
+}]>;
+
+
+def s16ImmPred : PatLeaf<(i32 imm), [{
+ // s16ImmPred predicate - True if the immediate fits in a 16-bit sign extended
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isInt<16>(v);
+}]>;
+
+
+def s13ImmPred : PatLeaf<(i32 imm), [{
+ // s13ImmPred predicate - True if the immediate fits in a 13-bit sign extended
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isInt<13>(v);
+}]>;
+
+
+def s12ImmPred : PatLeaf<(i32 imm), [{
+ // s12ImmPred predicate - True if the immediate fits in a 12-bit
+ // sign extended field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isInt<12>(v);
+}]>;
+
+def s11_0ImmPred : PatLeaf<(i32 imm), [{
+ // s11_0ImmPred predicate - True if the immediate fits in a 11-bit
+ // sign extended field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isInt<11>(v);
+}]>;
+
+
+def s11_1ImmPred : PatLeaf<(i32 imm), [{
+ // s11_1ImmPred predicate - True if the immediate fits in a 12-bit
+ // sign extended field and is a multiple of 2.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isShiftedInt<11,1>(v);
+}]>;
+
+
+def s11_2ImmPred : PatLeaf<(i32 imm), [{
+ // s11_2ImmPred predicate - True if the immediate fits in a 13-bit
+ // sign extended field and is a multiple of 4.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isShiftedInt<11,2>(v);
+}]>;
+
+
+def s11_3ImmPred : PatLeaf<(i32 imm), [{
+ // s11_3ImmPred predicate - True if the immediate fits in a 14-bit
+ // sign extended field and is a multiple of 8.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isShiftedInt<11,3>(v);
+}]>;
+
+
+def s10ImmPred : PatLeaf<(i32 imm), [{
+ // s10ImmPred predicate - True if the immediate fits in a 10-bit sign extended
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isInt<10>(v);
+}]>;
+
+
+def s9ImmPred : PatLeaf<(i32 imm), [{
+ // s9ImmPred predicate - True if the immediate fits in a 9-bit sign extended
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isInt<9>(v);
+}]>;
+
+def m9ImmPred : PatLeaf<(i32 imm), [{
+ // m9ImmPred predicate - True if the immediate fits in a 9-bit magnitude
+ // field. The range of m9 is -255 to 255.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isInt<9>(v) && (v != -256);
+}]>;
+
+def s8ImmPred : PatLeaf<(i32 imm), [{
+ // s8ImmPred predicate - True if the immediate fits in a 8-bit sign extended
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isInt<8>(v);
+}]>;
+
+
+def s8Imm64Pred : PatLeaf<(i64 imm), [{
+ // s8ImmPred predicate - True if the immediate fits in a 8-bit sign extended
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isInt<8>(v);
+}]>;
+
+
+def s6ImmPred : PatLeaf<(i32 imm), [{
+ // s6ImmPred predicate - True if the immediate fits in a 6-bit sign extended
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isInt<6>(v);
+}]>;
+
+
+def s4_0ImmPred : PatLeaf<(i32 imm), [{
+ // s4_0ImmPred predicate - True if the immediate fits in a 4-bit sign extended
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isInt<4>(v);
+}]>;
+
+
+def s4_1ImmPred : PatLeaf<(i32 imm), [{
+ // s4_1ImmPred predicate - True if the immediate fits in a 4-bit sign extended
+ // field of 2.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isShiftedInt<4,1>(v);
+}]>;
+
+
+def s4_2ImmPred : PatLeaf<(i32 imm), [{
+ // s4_2ImmPred predicate - True if the immediate fits in a 4-bit sign extended
+ // field that is a multiple of 4.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isShiftedInt<4,2>(v);
+}]>;
+
+
+def s4_3ImmPred : PatLeaf<(i32 imm), [{
+ // s4_3ImmPred predicate - True if the immediate fits in a 4-bit sign extended
+ // field that is a multiple of 8.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isShiftedInt<4,3>(v);
+}]>;
+
+
+def u64ImmPred : PatLeaf<(i64 imm), [{
+ // Adding "N ||" to suppress gcc unused warning.
+ return (N || true);
+}]>;
+
+def u32ImmPred : PatLeaf<(i32 imm), [{
+ // u32ImmPred predicate - True if the immediate fits in a 32-bit field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isUInt<32>(v);
+}]>;
+
+def u26_6ImmPred : PatLeaf<(i32 imm), [{
+ // u26_6ImmPred - True if the immediate fits in a 32-bit field and
+ // is a multiple of 64.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isShiftedUInt<26,6>(v);
+}]>;
+
+def u16ImmPred : PatLeaf<(i32 imm), [{
+ // u16ImmPred predicate - True if the immediate fits in a 16-bit unsigned
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isUInt<16>(v);
+}]>;
+
+def u16_s8ImmPred : PatLeaf<(i32 imm), [{
+ // u16_s8ImmPred predicate - True if the immediate fits in a 16-bit sign
+ // extended s8 field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isShiftedUInt<16,8>(v);
+}]>;
+
+def u9ImmPred : PatLeaf<(i32 imm), [{
+ // u9ImmPred predicate - True if the immediate fits in a 9-bit unsigned
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isUInt<9>(v);
+}]>;
+
+
+def u8ImmPred : PatLeaf<(i32 imm), [{
+ // u8ImmPred predicate - True if the immediate fits in a 8-bit unsigned
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isUInt<8>(v);
+}]>;
+
+def u7StrictPosImmPred : ImmLeaf<i32, [{
+ // u7StrictPosImmPred predicate - True if the immediate fits in an 7-bit
+ // unsigned field and is strictly greater than 0.
+ return isUInt<7>(Imm) && Imm > 0;
+}]>;
+
+def u7ImmPred : PatLeaf<(i32 imm), [{
+ // u7ImmPred predicate - True if the immediate fits in a 7-bit unsigned
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isUInt<7>(v);
+}]>;
+
+
+def u6ImmPred : PatLeaf<(i32 imm), [{
+ // u6ImmPred predicate - True if the immediate fits in a 6-bit unsigned
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isUInt<6>(v);
+}]>;
+
+def u6_0ImmPred : PatLeaf<(i32 imm), [{
+ // u6_0ImmPred predicate - True if the immediate fits in a 6-bit unsigned
+ // field. Same as u6ImmPred.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isUInt<6>(v);
+}]>;
+
+def u6_1ImmPred : PatLeaf<(i32 imm), [{
+ // u6_1ImmPred predicate - True if the immediate fits in a 7-bit unsigned
+ // field that is 1 bit alinged - multiple of 2.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isShiftedUInt<6,1>(v);
+}]>;
+
+def u6_2ImmPred : PatLeaf<(i32 imm), [{
+ // u6_2ImmPred predicate - True if the immediate fits in a 8-bit unsigned
+ // field that is 2 bits alinged - multiple of 4.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isShiftedUInt<6,2>(v);
+}]>;
+
+def u6_3ImmPred : PatLeaf<(i32 imm), [{
+ // u6_3ImmPred predicate - True if the immediate fits in a 9-bit unsigned
+ // field that is 3 bits alinged - multiple of 8.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isShiftedUInt<6,3>(v);
+}]>;
+
+def u5ImmPred : PatLeaf<(i32 imm), [{
+ // u5ImmPred predicate - True if the immediate fits in a 5-bit unsigned
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isUInt<5>(v);
+}]>;
+
+
+def u3ImmPred : PatLeaf<(i32 imm), [{
+ // u3ImmPred predicate - True if the immediate fits in a 3-bit unsigned
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isUInt<3>(v);
+}]>;
+
+
+def u2ImmPred : PatLeaf<(i32 imm), [{
+ // u2ImmPred predicate - True if the immediate fits in a 2-bit unsigned
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isUInt<2>(v);
+}]>;
+
+
+def u1ImmPred : PatLeaf<(i1 imm), [{
+ // u1ImmPred predicate - True if the immediate fits in a 1-bit unsigned
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isUInt<1>(v);
+}]>;
+
+def m5BImmPred : PatLeaf<(i32 imm), [{
+ // m5BImmPred predicate - True if the (char) number is in range -1 .. -31
+ // and will fit in a 5 bit field when made positive, for use in memops.
+ // this is specific to the zero extending of a negative by CombineInstr
+ int8_t v = (int8_t)N->getSExtValue();
+ return (-31 <= v && v <= -1);
+}]>;
+
+def m5HImmPred : PatLeaf<(i32 imm), [{
+ // m5HImmPred predicate - True if the (short) number is in range -1 .. -31
+ // and will fit in a 5 bit field when made positive, for use in memops.
+ // this is specific to the zero extending of a negative by CombineInstr
+ int16_t v = (int16_t)N->getSExtValue();
+ return (-31 <= v && v <= -1);
+}]>;
+
+def m5ImmPred : PatLeaf<(i32 imm), [{
+ // m5ImmPred predicate - True if the number is in range -1 .. -31
+ // and will fit in a 5 bit field when made positive, for use in memops.
+ int64_t v = (int64_t)N->getSExtValue();
+ return (-31 <= v && v <= -1);
+}]>;
+
+//InN means negative integers in [-(2^N - 1), 0]
+def n8ImmPred : PatLeaf<(i32 imm), [{
+ // n8ImmPred predicate - True if the immediate fits in a 8-bit signed
+ // field.
+ int64_t v = (int64_t)N->getSExtValue();
+ return (-255 <= v && v <= 0);
+}]>;
+
+def nOneImmPred : PatLeaf<(i32 imm), [{
+ // nOneImmPred predicate - True if the immediate is -1.
+ int64_t v = (int64_t)N->getSExtValue();
+ return (-1 == v);
+}]>;
+
+def Set5ImmPred : PatLeaf<(i32 imm), [{
+ // Set5ImmPred predicate - True if the number is in the series of values.
+ // [ 2^0, 2^1, ... 2^31 ]
+ // For use in setbit immediate.
+ uint32_t v = (int32_t)N->getSExtValue();
+ // Constrain to 32 bits, and then check for single bit.
+ return ImmIsSingleBit(v);
+}]>;
+
+def Clr5ImmPred : PatLeaf<(i32 imm), [{
+ // Clr5ImmPred predicate - True if the number is in the series of
+ // bit negated values.
+ // [ 2^0, 2^1, ... 2^31 ]
+ // For use in clrbit immediate.
+ // Note: we are bit NOTing the value.
+ uint32_t v = ~ (int32_t)N->getSExtValue();
+ // Constrain to 32 bits, and then check for single bit.
+ return ImmIsSingleBit(v);
+}]>;
+
+def SetClr5ImmPred : PatLeaf<(i32 imm), [{
+ // SetClr5ImmPred predicate - True if the immediate is in range 0..31.
+ int32_t v = (int32_t)N->getSExtValue();
+ return (v >= 0 && v <= 31);
+}]>;
+
+def Set4ImmPred : PatLeaf<(i32 imm), [{
+ // Set4ImmPred predicate - True if the number is in the series of values:
+ // [ 2^0, 2^1, ... 2^15 ].
+ // For use in setbit immediate.
+ uint16_t v = (int16_t)N->getSExtValue();
+ // Constrain to 16 bits, and then check for single bit.
+ return ImmIsSingleBit(v);
+}]>;
+
+def Clr4ImmPred : PatLeaf<(i32 imm), [{
+ // Clr4ImmPred predicate - True if the number is in the series of
+ // bit negated values:
+ // [ 2^0, 2^1, ... 2^15 ].
+ // For use in setbit and clrbit immediate.
+ uint16_t v = ~ (int16_t)N->getSExtValue();
+ // Constrain to 16 bits, and then check for single bit.
+ return ImmIsSingleBit(v);
+}]>;
+
+def SetClr4ImmPred : PatLeaf<(i32 imm), [{
+ // SetClr4ImmPred predicate - True if the immediate is in the range 0..15.
+ int16_t v = (int16_t)N->getSExtValue();
+ return (v >= 0 && v <= 15);
+}]>;
+
+def Set3ImmPred : PatLeaf<(i32 imm), [{
+ // Set3ImmPred predicate - True if the number is in the series of values:
+ // [ 2^0, 2^1, ... 2^7 ].
+ // For use in setbit immediate.
+ uint8_t v = (int8_t)N->getSExtValue();
+ // Constrain to 8 bits, and then check for single bit.
+ return ImmIsSingleBit(v);
+}]>;
+
+def Clr3ImmPred : PatLeaf<(i32 imm), [{
+ // Clr3ImmPred predicate - True if the number is in the series of
+ // bit negated values:
+ // [ 2^0, 2^1, ... 2^7 ].
+ // For use in setbit and clrbit immediate.
+ uint8_t v = ~ (int8_t)N->getSExtValue();
+ // Constrain to 8 bits, and then check for single bit.
+ return ImmIsSingleBit(v);
+}]>;
+
+def SetClr3ImmPred : PatLeaf<(i32 imm), [{
+ // SetClr3ImmPred predicate - True if the immediate is in the range 0..7.
+ int8_t v = (int8_t)N->getSExtValue();
+ return (v >= 0 && v <= 7);
+}]>;
+
+
+// Extendable immediate operands.
+
+let PrintMethod = "printExtOperand" in {
+ def s16Ext : Operand<i32>;
+ def s12Ext : Operand<i32>;
+ def s10Ext : Operand<i32>;
+ def s9Ext : Operand<i32>;
+ def s8Ext : Operand<i32>;
+ def s6Ext : Operand<i32>;
+ def s11_0Ext : Operand<i32>;
+ def s11_1Ext : Operand<i32>;
+ def s11_2Ext : Operand<i32>;
+ def s11_3Ext : Operand<i32>;
+ def u6Ext : Operand<i32>;
+ def u7Ext : Operand<i32>;
+ def u8Ext : Operand<i32>;
+ def u9Ext : Operand<i32>;
+ def u10Ext : Operand<i32>;
+ def u6_0Ext : Operand<i32>;
+ def u6_1Ext : Operand<i32>;
+ def u6_2Ext : Operand<i32>;
+ def u6_3Ext : Operand<i32>;
+}
+
+let PrintMethod = "printImmOperand" in
+def u0AlwaysExt : Operand<i32>;
+
+// Predicates for constant extendable operands
+def s16ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate can fit in a 16-bit sign extended field.
+ return isInt<16>(v);
+ else {
+ if (isInt<16>(v))
+ return true;
+
+ // Return true if extending this immediate is profitable and the value
+ // can fit in a 32-bit signed field.
+ return isConstExtProfitable(Node) && isInt<32>(v);
+ }
+}]>;
+
+def s10ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate can fit in a 10-bit sign extended field.
+ return isInt<10>(v);
+ else {
+ if (isInt<10>(v))
+ return true;
+
+ // Return true if extending this immediate is profitable and the value
+ // can fit in a 32-bit signed field.
+ return isConstExtProfitable(Node) && isInt<32>(v);
+ }
+}]>;
+
+def s9ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate can fit in a 9-bit sign extended field.
+ return isInt<9>(v);
+ else {
+ if (isInt<9>(v))
+ return true;
+
+ // Return true if extending this immediate is profitable and the value
+ // can fit in a 32-bit unsigned field.
+ return isConstExtProfitable(Node) && isInt<32>(v);
+ }
+}]>;
+
+def s8ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate can fit in a 8-bit sign extended field.
+ return isInt<8>(v);
+ else {
+ if (isInt<8>(v))
+ return true;
+
+ // Return true if extending this immediate is profitable and the value
+ // can fit in a 32-bit signed field.
+ return isConstExtProfitable(Node) && isInt<32>(v);
+ }
+}]>;
+
+def s8_16ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate fits in a 8-bit sign extended field.
+ return isInt<8>(v);
+ else {
+ if (isInt<8>(v))
+ return true;
+
+ // Return true if extending this immediate is profitable and the value
+ // can't fit in a 16-bit signed field. This is required to avoid
+ // unnecessary constant extenders.
+ return isConstExtProfitable(Node) && !isInt<16>(v);
+ }
+}]>;
+
+def s6ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate can fit in a 6-bit sign extended field.
+ return isInt<6>(v);
+ else {
+ if (isInt<6>(v))
+ return true;
+
+ // Return true if extending this immediate is profitable and the value
+ // can fit in a 32-bit unsigned field.
+ return isConstExtProfitable(Node) && isInt<32>(v);
+ }
+}]>;
+
+def s6_16ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate fits in a 6-bit sign extended field.
+ return isInt<6>(v);
+ else {
+ if (isInt<6>(v))
+ return true;
+
+ // Return true if extending this immediate is profitable and the value
+ // can't fit in a 16-bit signed field. This is required to avoid
+ // unnecessary constant extenders.
+ return isConstExtProfitable(Node) && !isInt<16>(v);
+ }
+}]>;
+
+def s6_10ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate can fit in a 6-bit sign extended field.
+ return isInt<6>(v);
+ else {
+ if (isInt<6>(v))
+ return true;
+
+ // Return true if extending this immediate is profitable and the value
+ // can't fit in a 10-bit signed field. This is required to avoid
+ // unnecessary constant extenders.
+ return isConstExtProfitable(Node) && !isInt<10>(v);
+ }
+}]>;
+
+def s11_0ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate can fit in a 11-bit sign extended field.
+ return isShiftedInt<11,0>(v);
+ else {
+ if (isInt<11>(v))
+ return true;
+
+ // Return true if extending this immediate is profitable and the value
+ // can fit in a 32-bit signed field.
+ return isConstExtProfitable(Node) && isInt<32>(v);
+ }
+}]>;
+
+def s11_1ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate can fit in a 12-bit sign extended field and
+ // is 2 byte aligned.
+ return isShiftedInt<11,1>(v);
+ else {
+ if (isInt<12>(v))
+ return isShiftedInt<11,1>(v);
+
+ // Return true if extending this immediate is profitable and the low 1 bit
+ // is zero (2-byte aligned).
+ return isConstExtProfitable(Node) && isInt<32>(v) && ((v % 2) == 0);
+ }
+}]>;
+
+def s11_2ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate can fit in a 13-bit sign extended field and
+ // is 4-byte aligned.
+ return isShiftedInt<11,2>(v);
+ else {
+ if (isInt<13>(v))
+ return isShiftedInt<11,2>(v);
+
+ // Return true if extending this immediate is profitable and the low 2-bits
+ // are zero (4-byte aligned).
+ return isConstExtProfitable(Node) && isInt<32>(v) && ((v % 4) == 0);
+ }
+}]>;
+
+def s11_3ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate can fit in a 14-bit sign extended field and
+ // is 8-byte aligned.
+ return isShiftedInt<11,3>(v);
+ else {
+ if (isInt<14>(v))
+ return isShiftedInt<11,3>(v);
+
+ // Return true if extending this immediate is profitable and the low 3-bits
+ // are zero (8-byte aligned).
+ return isConstExtProfitable(Node) && isInt<32>(v) && ((v % 8) == 0);
+ }
+}]>;
+
+def u0AlwaysExtPred : PatLeaf<(i32 imm), [{
+ // Predicate for an unsigned 32-bit value that always needs to be extended.
+ if (Subtarget.hasV4TOps()) {
+ if (isConstExtProfitable(Node)) {
+ int64_t v = (int64_t)N->getSExtValue();
+ return isUInt<32>(v);
+ }
+ }
+ return false;
+}]>;
+
+def u6ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate can fit in a 6-bit unsigned field.
+ return isUInt<6>(v);
+ else {
+ if (isUInt<6>(v))
+ return true;
+
+ // Return true if extending this immediate is profitable and the value
+ // can fit in a 32-bit unsigned field.
+ return isConstExtProfitable(Node) && isUInt<32>(v);
+ }
+}]>;
+
+def u7ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate can fit in a 7-bit unsigned field.
+ return isUInt<7>(v);
+ else {
+ if (isUInt<7>(v))
+ return true;
+
+ // Return true if extending this immediate is profitable and the value
+ // can fit in a 32-bit unsigned field.
+ return isConstExtProfitable(Node) && isUInt<32>(v);
+ }
+}]>;
+
+def u8ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate can fit in a 8-bit unsigned field.
+ return isUInt<8>(v);
+ else {
+ if (isUInt<8>(v))
+ return true;
+
+ // Return true if extending this immediate is profitable and the value
+ // can fit in a 32-bit unsigned field.
+ return isConstExtProfitable(Node) && isUInt<32>(v);
+ }
+}]>;
+
+def u9ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate can fit in a 9-bit unsigned field.
+ return isUInt<9>(v);
+ else {
+ if (isUInt<9>(v))
+ return true;
+
+ // Return true if extending this immediate is profitable and the value
+ // can fit in a 32-bit unsigned field.
+ return isConstExtProfitable(Node) && isUInt<32>(v);
+ }
+}]>;
+
+def u6_1ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate can fit in a 7-bit unsigned field and
+ // is 2-byte aligned.
+ return isShiftedUInt<6,1>(v);
+ else {
+ if (isUInt<7>(v))
+ return isShiftedUInt<6,1>(v);
+
+ // Return true if extending this immediate is profitable and the value
+ // can fit in a 32-bit unsigned field.
+ return isConstExtProfitable(Node) && isUInt<32>(v) && ((v % 2) == 0);
+ }
+}]>;
+
+def u6_2ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate can fit in a 8-bit unsigned field and
+ // is 4-byte aligned.
+ return isShiftedUInt<6,2>(v);
+ else {
+ if (isUInt<8>(v))
+ return isShiftedUInt<6,2>(v);
+
+ // Return true if extending this immediate is profitable and the value
+ // can fit in a 32-bit unsigned field.
+ return isConstExtProfitable(Node) && isUInt<32>(v) && ((v % 4) == 0);
+ }
+}]>;
+
+def u6_3ExtPred : PatLeaf<(i32 imm), [{
+ int64_t v = (int64_t)N->getSExtValue();
+ if (!Subtarget.hasV4TOps())
+ // Return true if the immediate can fit in a 9-bit unsigned field and
+ // is 8-byte aligned.
+ return isShiftedUInt<6,3>(v);
+ else {
+ if (isUInt<9>(v))
+ return isShiftedUInt<6,3>(v);
+
+ // Return true if extending this immediate is profitable and the value
+ // can fit in a 32-bit unsigned field.
+ return isConstExtProfitable(Node) && isUInt<32>(v) && ((v % 8) == 0);
+ }
+}]>;
+
+// Addressing modes.
+
+def ADDRrr : ComplexPattern<i32, 2, "SelectADDRrr", [], []>;
+def ADDRri : ComplexPattern<i32, 2, "SelectADDRri", [frameindex], []>;
+def ADDRriS11_0 : ComplexPattern<i32, 2, "SelectADDRriS11_0", [frameindex], []>;
+def ADDRriS11_1 : ComplexPattern<i32, 2, "SelectADDRriS11_1", [frameindex], []>;
+def ADDRriS11_2 : ComplexPattern<i32, 2, "SelectADDRriS11_2", [frameindex], []>;
+def ADDRriS11_3 : ComplexPattern<i32, 2, "SelectADDRriS11_3", [frameindex], []>;
+def ADDRriU6_0 : ComplexPattern<i32, 2, "SelectADDRriU6_0", [frameindex], []>;
+def ADDRriU6_1 : ComplexPattern<i32, 2, "SelectADDRriU6_1", [frameindex], []>;
+def ADDRriU6_2 : ComplexPattern<i32, 2, "SelectADDRriU6_2", [frameindex], []>;
+
+// Address operands.
+
+def MEMrr : Operand<i32> {
+ let PrintMethod = "printMEMrrOperand";
+ let MIOperandInfo = (ops IntRegs, IntRegs);
+}
+
+def MEMri : Operand<i32> {
+ let PrintMethod = "printMEMriOperand";
+ let MIOperandInfo = (ops IntRegs, IntRegs);
+}
+
+def MEMri_s11_2 : Operand<i32>,
+ ComplexPattern<i32, 2, "SelectMEMriS11_2", []> {
+ let PrintMethod = "printMEMriOperand";
+ let MIOperandInfo = (ops IntRegs, s11Imm);
+}
+
+def FrameIndex : Operand<i32> {
+ let PrintMethod = "printFrameIndexOperand";
+ let MIOperandInfo = (ops IntRegs, s11Imm);
+}
+
+let PrintMethod = "printGlobalOperand" in {
+ def globaladdress : Operand<i32>;
+ def globaladdressExt : Operand<i32>;
+}
+
+let PrintMethod = "printJumpTable" in
+def jumptablebase : Operand<i32>;
+
+def brtarget : Operand<OtherVT>;
+def brtargetExt : Operand<OtherVT>;
+def calltarget : Operand<i32>;
+
+def bblabel : Operand<i32>;
+def bbl : SDNode<"ISD::BasicBlock", SDTPtrLeaf , [], "BasicBlockSDNode">;
+
+def symbolHi32 : Operand<i32> {
+ let PrintMethod = "printSymbolHi";
+}
+def symbolLo32 : Operand<i32> {
+ let PrintMethod = "printSymbolLo";
+}
diff --git a/lib/Target/Hexagon/HexagonPeephole.cpp b/lib/Target/Hexagon/HexagonPeephole.cpp
index a295015..576f1d7 100644
--- a/lib/Target/Hexagon/HexagonPeephole.cpp
+++ b/lib/Target/Hexagon/HexagonPeephole.cpp
@@ -38,21 +38,21 @@
#define DEBUG_TYPE "hexagon-peephole"
#include "Hexagon.h"
#include "HexagonTargetMachine.h"
-#include "llvm/Constants.h"
-#include "llvm/PassSupport.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/PassSupport.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetInstrInfo.h"
#include <algorithm>
using namespace llvm;
diff --git a/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/lib/Target/Hexagon/HexagonRegisterInfo.cpp
index 3742486..d1882de 100644
--- a/lib/Target/Hexagon/HexagonRegisterInfo.cpp
+++ b/lib/Target/Hexagon/HexagonRegisterInfo.cpp
@@ -14,25 +14,25 @@
#include "HexagonRegisterInfo.h"
#include "Hexagon.h"
+#include "HexagonMachineFunctionInfo.h"
#include "HexagonSubtarget.h"
#include "HexagonTargetMachine.h"
-#include "HexagonMachineFunctionInfo.h"
-#include "llvm/Function.h"
-#include "llvm/Type.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.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;
diff --git a/lib/Target/Hexagon/HexagonRegisterInfo.h b/lib/Target/Hexagon/HexagonRegisterInfo.h
index 8820d13..e8f3cfb 100644
--- a/lib/Target/Hexagon/HexagonRegisterInfo.h
+++ b/lib/Target/Hexagon/HexagonRegisterInfo.h
@@ -15,8 +15,8 @@
#ifndef HexagonREGISTERINFO_H
#define HexagonREGISTERINFO_H
-#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/MC/MachineLocation.h"
+#include "llvm/Target/TargetRegisterInfo.h"
#define GET_REGINFO_HEADER
#include "HexagonGenRegisterInfo.inc"
diff --git a/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp b/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp
index 2468f0b..34bf4ea 100644
--- a/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp
+++ b/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp
@@ -12,11 +12,12 @@
//
//===----------------------------------------------------------------------===//
+#include "Hexagon.h"
#include "HexagonTargetMachine.h"
-#include "llvm/Function.h"
-#include "llvm/Instructions.h"
-#include "llvm/Pass.h"
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Pass.h"
#include "llvm/Transforms/Scalar.h"
using namespace llvm;
@@ -50,7 +51,7 @@ bool HexagonRemoveExtendArgs::runOnFunction(Function &F) {
unsigned Idx = 1;
for (Function::arg_iterator AI = F.arg_begin(), AE = F.arg_end(); AI != AE;
++AI, ++Idx) {
- if (F.paramHasAttr(Idx, Attribute::SExt)) {
+ if (F.getAttributes().hasAttribute(Idx, Attribute::SExt)) {
Argument* Arg = AI;
if (!isa<PointerType>(Arg->getType())) {
for (Instruction::use_iterator UI = Arg->use_begin();
diff --git a/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp b/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp
index a81cd91..814249f 100644
--- a/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp
+++ b/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp
@@ -27,24 +27,25 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "xfer"
-#include "HexagonTargetMachine.h"
-#include "HexagonSubtarget.h"
+#include "Hexagon.h"
#include "HexagonMachineFunctionInfo.h"
-#include "llvm/CodeGen/Passes.h"
+#include "HexagonSubtarget.h"
+#include "HexagonTargetMachine.h"
#include "llvm/CodeGen/LatencyPriorityQueue.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
diff --git a/lib/Target/Hexagon/HexagonSubtarget.h b/lib/Target/Hexagon/HexagonSubtarget.h
index 5d9d6d8..76a8fba 100644
--- a/lib/Target/Hexagon/HexagonSubtarget.h
+++ b/lib/Target/Hexagon/HexagonSubtarget.h
@@ -14,8 +14,8 @@
#ifndef Hexagon_SUBTARGET_H
#define Hexagon_SUBTARGET_H
-#include "llvm/Target/TargetSubtargetInfo.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
#include <string>
#define GET_SUBTARGETINFO_HEADER
diff --git a/lib/Target/Hexagon/HexagonTargetMachine.cpp b/lib/Target/Hexagon/HexagonTargetMachine.cpp
index 5688e9c..287b3d6 100644
--- a/lib/Target/Hexagon/HexagonTargetMachine.cpp
+++ b/lib/Target/Hexagon/HexagonTargetMachine.cpp
@@ -15,13 +15,13 @@
#include "Hexagon.h"
#include "HexagonISelLowering.h"
#include "HexagonMachineScheduler.h"
-#include "llvm/Module.h"
#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Module.h"
#include "llvm/PassManager.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
-#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/Transforms/Scalar.h"
using namespace llvm;
@@ -68,7 +68,7 @@ HexagonTargetMachine::HexagonTargetMachine(const Target &T, StringRef TT,
CodeModel::Model CM,
CodeGenOpt::Level OL)
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
- DataLayout("e-p:32:32:32-"
+ DL("e-p:32:32:32-"
"i64:64:64-i32:32:32-i16:16:16-i1:32:32-"
"f64:64:64-f32:32:32-a0:0-n32") ,
Subtarget(TT, CPU, FS), InstrInfo(Subtarget), TLInfo(*this),
@@ -87,7 +87,7 @@ bool HexagonTargetMachine::addPassesForOptimizations(PassManagerBase &PM) {
PM.add(createDeadCodeEliminationPass());
PM.add(createConstantPropagationPass());
PM.add(createLoopUnrollPass());
- PM.add(createLoopStrengthReducePass(getTargetLowering()));
+ PM.add(createLoopStrengthReducePass());
return true;
}
diff --git a/lib/Target/Hexagon/HexagonTargetMachine.h b/lib/Target/Hexagon/HexagonTargetMachine.h
index 0336965..cf8f9aa 100644
--- a/lib/Target/Hexagon/HexagonTargetMachine.h
+++ b/lib/Target/Hexagon/HexagonTargetMachine.h
@@ -14,20 +14,20 @@
#ifndef HexagonTARGETMACHINE_H
#define HexagonTARGETMACHINE_H
-#include "HexagonInstrInfo.h"
-#include "HexagonSubtarget.h"
+#include "HexagonFrameLowering.h"
#include "HexagonISelLowering.h"
+#include "HexagonInstrInfo.h"
#include "HexagonSelectionDAGInfo.h"
-#include "HexagonFrameLowering.h"
+#include "HexagonSubtarget.h"
+#include "llvm/IR/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetData.h"
namespace llvm {
class Module;
class HexagonTargetMachine : public LLVMTargetMachine {
- const TargetData DataLayout; // Calculates type size & alignment.
+ const DataLayout DL; // Calculates type size & alignment.
HexagonSubtarget Subtarget;
HexagonInstrInfo InstrInfo;
HexagonTargetLowering TLInfo;
@@ -68,7 +68,7 @@ public:
return &TSInfo;
}
- virtual const TargetData *getTargetData() const { return &DataLayout; }
+ virtual const DataLayout *getDataLayout() const { return &DL; }
static unsigned getModuleMatchQuality(const Module &M);
// Pass Pipeline Configuration.
diff --git a/lib/Target/Hexagon/HexagonTargetObjectFile.cpp b/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
index 32cc709..993fcfa 100644
--- a/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
+++ b/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
@@ -14,13 +14,13 @@
#include "HexagonTargetObjectFile.h"
#include "HexagonSubtarget.h"
#include "HexagonTargetMachine.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/DerivedTypes.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalVariable.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/Support/ELF.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ELF.h"
using namespace llvm;
@@ -73,7 +73,7 @@ IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
if (Kind.isBSS() || Kind.isDataNoRel() || Kind.isCommon()) {
Type *Ty = GV->getType()->getElementType();
- return IsInSmallSection(TM.getTargetData()->getTypeAllocSize(Ty));
+ return IsInSmallSection(TM.getDataLayout()->getTypeAllocSize(Ty));
}
return false;
diff --git a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
index 3d5f685..409a243 100644
--- a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
+++ b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
@@ -17,36 +17,35 @@
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "packets"
+#include "Hexagon.h"
+#include "HexagonMachineFunctionInfo.h"
+#include "HexagonRegisterInfo.h"
+#include "HexagonSubtarget.h"
+#include "HexagonTargetMachine.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/DFAPacketizer.h"
-#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/LatencyPriorityQueue.h"
#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
-#include "llvm/CodeGen/LatencyPriorityQueue.h"
-#include "llvm/CodeGen/SchedulerRegistry.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/MathExtras.h"
+#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/MC/MCInstrItineraries.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
-#include "Hexagon.h"
-#include "HexagonTargetMachine.h"
-#include "HexagonRegisterInfo.h"
-#include "HexagonSubtarget.h"
-#include "HexagonMachineFunctionInfo.h"
-
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegisterInfo.h"
#include <map>
using namespace llvm;
@@ -242,8 +241,9 @@ static bool IsIndirectCall(MachineInstr* MI) {
// reservation fail.
void HexagonPacketizerList::reserveResourcesForConstExt(MachineInstr* MI) {
const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
- MachineInstr *PseudoMI = MI->getParent()->getParent()->CreateMachineInstr(
- QII->get(Hexagon::IMMEXT), MI->getDebugLoc());
+ MachineFunction *MF = MI->getParent()->getParent();
+ MachineInstr *PseudoMI = MF->CreateMachineInstr(QII->get(Hexagon::IMMEXT_i),
+ MI->getDebugLoc());
if (ResourceTracker->canReserveResources(PseudoMI)) {
ResourceTracker->reserveResources(PseudoMI);
@@ -260,7 +260,7 @@ bool HexagonPacketizerList::canReserveResourcesForConstExt(MachineInstr *MI) {
assert(QII->isExtended(MI) &&
"Should only be called for constant extended instructions");
MachineFunction *MF = MI->getParent()->getParent();
- MachineInstr *PseudoMI = MF->CreateMachineInstr(QII->get(Hexagon::IMMEXT),
+ MachineInstr *PseudoMI = MF->CreateMachineInstr(QII->get(Hexagon::IMMEXT_i),
MI->getDebugLoc());
bool CanReserve = ResourceTracker->canReserveResources(PseudoMI);
MF->DeleteMachineInstr(PseudoMI);
@@ -271,8 +271,9 @@ bool HexagonPacketizerList::canReserveResourcesForConstExt(MachineInstr *MI) {
// true, otherwise, return false.
bool HexagonPacketizerList::tryAllocateResourcesForConstExt(MachineInstr* MI) {
const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
- MachineInstr *PseudoMI = MI->getParent()->getParent()->CreateMachineInstr(
- QII->get(Hexagon::IMMEXT), MI->getDebugLoc());
+ MachineFunction *MF = MI->getParent()->getParent();
+ MachineInstr *PseudoMI = MF->CreateMachineInstr(QII->get(Hexagon::IMMEXT_i),
+ MI->getDebugLoc());
if (ResourceTracker->canReserveResources(PseudoMI)) {
ResourceTracker->reserveResources(PseudoMI);
diff --git a/lib/Target/Hexagon/HexagonVarargsCallingConvention.h b/lib/Target/Hexagon/HexagonVarargsCallingConvention.h
index 9305c27..c607b5d 100644
--- a/lib/Target/Hexagon/HexagonVarargsCallingConvention.h
+++ b/lib/Target/Hexagon/HexagonVarargsCallingConvention.h
@@ -75,9 +75,9 @@ static bool CC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
const Type* ArgTy = LocVT.getTypeForEVT(State.getContext());
unsigned Alignment =
- State.getTarget().getTargetData()->getABITypeAlignment(ArgTy);
+ State.getTarget().getDataLayout()->getABITypeAlignment(ArgTy);
unsigned Size =
- State.getTarget().getTargetData()->getTypeSizeInBits(ArgTy) / 8;
+ State.getTarget().getDataLayout()->getTypeSizeInBits(ArgTy) / 8;
// If it's passed by value, then we need the size of the aggregate not of
// the pointer.
@@ -130,9 +130,9 @@ static bool RetCC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
const Type* ArgTy = LocVT.getTypeForEVT(State.getContext());
unsigned Alignment =
- State.getTarget().getTargetData()->getABITypeAlignment(ArgTy);
+ State.getTarget().getDataLayout()->getABITypeAlignment(ArgTy);
unsigned Size =
- State.getTarget().getTargetData()->getTypeSizeInBits(ArgTy) / 8;
+ State.getTarget().getDataLayout()->getTypeSizeInBits(ArgTy) / 8;
unsigned Offset3 = State.AllocateStack(Size, Alignment);
State.addLoc(CCValAssign::getMem(ValNo, ValVT.getSimpleVT(), Offset3,
diff --git a/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp b/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp
index 035afe8..c700354 100644
--- a/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp
+++ b/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp
@@ -12,14 +12,14 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "asm-printer"
+#include "HexagonInstPrinter.h"
#include "Hexagon.h"
#include "HexagonAsmPrinter.h"
-#include "HexagonInstPrinter.h"
#include "HexagonMCInst.h"
-#include "llvm/MC/MCInst.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCExpr.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/MC/MCInst.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdio>
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h b/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
index 7221e90..9fc826f 100644
--- a/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
@@ -43,7 +43,27 @@ namespace HexagonII {
TypeMARKER = 31 // Such as end of a HW loop.
};
+ enum SubTarget {
+ HasV2SubT = 0xf,
+ HasV2SubTOnly = 0x1,
+ NoV2SubT = 0x0,
+ HasV3SubT = 0xe,
+ HasV3SubTOnly = 0x2,
+ NoV3SubT = 0x1,
+ HasV4SubT = 0xc,
+ NoV4SubT = 0x3,
+ HasV5SubT = 0x8,
+ NoV5SubT = 0x7
+ };
+ enum AddrMode {
+ NoAddrMode = 0, // No addressing mode
+ Absolute = 1, // Absolute addressing mode
+ AbsoluteSet = 2, // Absolute set addressing mode
+ BaseImmOffset = 3, // Indirect with offset
+ BaseLongOffset = 4, // Indirect with long offset
+ BaseRegOffset = 5 // Indirect with register offset
+ };
// MCInstrDesc TSFlags
// *** Must match HexagonInstrFormat*.td ***
@@ -58,8 +78,47 @@ namespace HexagonII {
// Predicated instructions.
PredicatedPos = 6,
- PredicatedMask = 0x1
- };
+ PredicatedMask = 0x1,
+ PredicatedNewPos = 7,
+ PredicatedNewMask = 0x1,
+
+ // Stores that can be newified.
+ mayNVStorePos = 8,
+ mayNVStoreMask = 0x1,
+
+ // Dot new value store instructions.
+ NVStorePos = 9,
+ NVStoreMask = 0x1,
+
+ // Extendable insns.
+ ExtendablePos = 10,
+ ExtendableMask = 0x1,
+
+ // Insns must be extended.
+ ExtendedPos = 11,
+ ExtendedMask = 0x1,
+
+ // Which operand may be extended.
+ ExtendableOpPos = 12,
+ ExtendableOpMask = 0x7,
+
+ // Signed or unsigned range.
+ ExtentSignedPos = 15,
+ ExtentSignedMask = 0x1,
+
+ // Number of bits of range before extending operand.
+ ExtentBitsPos = 16,
+ ExtentBitsMask = 0x1f,
+
+ // Valid subtargets
+ validSubTargetPos = 21,
+ validSubTargetMask = 0xf,
+
+ // Addressing mode for load/store instructions
+ AddrModePos = 25,
+ AddrModeMask = 0xf
+
+ };
// *** The code above must match HexagonInstrFormat*.td *** //
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp
index 3cfa4fd..737789b 100644
--- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp
@@ -13,11 +13,11 @@
#include "HexagonMCTargetDesc.h"
#include "HexagonMCAsmInfo.h"
-#include "llvm/MC/MachineLocation.h"
#include "llvm/MC/MCCodeGenInfo.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MachineLocation.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
diff --git a/lib/Target/Hexagon/TargetInfo/HexagonTargetInfo.cpp b/lib/Target/Hexagon/TargetInfo/HexagonTargetInfo.cpp
index 7aa5dd3..40f6c8d 100644
--- a/lib/Target/Hexagon/TargetInfo/HexagonTargetInfo.cpp
+++ b/lib/Target/Hexagon/TargetInfo/HexagonTargetInfo.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
#include "Hexagon.h"
-#include "llvm/Module.h"
+#include "llvm/IR/Module.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;