diff options
| author | Stephen Hines <srhines@google.com> | 2013-01-21 13:15:17 -0800 |
|---|---|---|
| committer | Stephen Hines <srhines@google.com> | 2013-01-21 13:15:17 -0800 |
| commit | 059800f9e3fee2852672f846d91a2da14da7783a (patch) | |
| tree | a6ef16b7263252ae1b8069295ea9cbbae0d9467d /lib/Target/Hexagon | |
| parent | cbefa15de4821975bb99fc6d74b3bdb42b2df45c (diff) | |
| parent | b6714227eda5d499f7667fc865f931126a8dc488 (diff) | |
| download | external_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')
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; |
