aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/Hexagon
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Hexagon')
-rw-r--r--lib/Target/Hexagon/Hexagon.td2
-rw-r--r--lib/Target/Hexagon/HexagonCFGOptimizer.cpp24
-rw-r--r--lib/Target/Hexagon/HexagonFrameLowering.cpp2
-rw-r--r--lib/Target/Hexagon/HexagonHardwareLoops.cpp13
-rw-r--r--lib/Target/Hexagon/HexagonISelDAGToDAG.cpp61
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.cpp44
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.h5
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.cpp345
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.h18
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.td1102
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfoV3.td40
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfoV4.td2310
-rw-r--r--lib/Target/Hexagon/HexagonMCInst.h41
-rw-r--r--lib/Target/Hexagon/HexagonMachineFunctionInfo.h9
-rw-r--r--lib/Target/Hexagon/HexagonNewValueJump.cpp130
-rw-r--r--lib/Target/Hexagon/HexagonPeephole.cpp19
-rw-r--r--lib/Target/Hexagon/HexagonRegisterInfo.cpp66
-rw-r--r--lib/Target/Hexagon/HexagonSubtarget.cpp17
-rw-r--r--lib/Target/Hexagon/HexagonTargetMachine.cpp49
-rw-r--r--lib/Target/Hexagon/HexagonVLIWPacketizer.cpp288
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp1
21 files changed, 1627 insertions, 2959 deletions
diff --git a/lib/Target/Hexagon/Hexagon.td b/lib/Target/Hexagon/Hexagon.td
index 8a5ee40..af1c56b 100644
--- a/lib/Target/Hexagon/Hexagon.td
+++ b/lib/Target/Hexagon/Hexagon.td
@@ -89,7 +89,7 @@ def getPredOpcode : InstrMapping {
//
def getPredNewOpcode : InstrMapping {
let FilterClass = "PredNewRel";
- let RowFields = ["BaseOpcode", "PredSense", "isNVStore"];
+ let RowFields = ["BaseOpcode", "PredSense", "isNVStore", "isBrTaken"];
let ColFields = ["PNewValue"];
let KeyCol = [""];
let ValueCols = [["new"]];
diff --git a/lib/Target/Hexagon/HexagonCFGOptimizer.cpp b/lib/Target/Hexagon/HexagonCFGOptimizer.cpp
index d4078ad..b6022ca 100644
--- a/lib/Target/Hexagon/HexagonCFGOptimizer.cpp
+++ b/lib/Target/Hexagon/HexagonCFGOptimizer.cpp
@@ -52,8 +52,8 @@ private:
char HexagonCFGOptimizer::ID = 0;
static bool IsConditionalBranch(int Opc) {
- return (Opc == Hexagon::JMP_c) || (Opc == Hexagon::JMP_cNot)
- || (Opc == Hexagon::JMP_cdnPt) || (Opc == Hexagon::JMP_cdnNotPt);
+ return (Opc == Hexagon::JMP_t) || (Opc == Hexagon::JMP_f)
+ || (Opc == Hexagon::JMP_tnew_t) || (Opc == Hexagon::JMP_fnew_t);
}
@@ -68,20 +68,20 @@ HexagonCFGOptimizer::InvertAndChangeJumpTarget(MachineInstr* MI,
const HexagonInstrInfo *QII = QTM.getInstrInfo();
int NewOpcode = 0;
switch(MI->getOpcode()) {
- case Hexagon::JMP_c:
- NewOpcode = Hexagon::JMP_cNot;
+ case Hexagon::JMP_t:
+ NewOpcode = Hexagon::JMP_f;
break;
- case Hexagon::JMP_cNot:
- NewOpcode = Hexagon::JMP_c;
+ case Hexagon::JMP_f:
+ NewOpcode = Hexagon::JMP_t;
break;
- case Hexagon::JMP_cdnPt:
- NewOpcode = Hexagon::JMP_cdnNotPt;
+ case Hexagon::JMP_tnew_t:
+ NewOpcode = Hexagon::JMP_fnew_t;
break;
- case Hexagon::JMP_cdnNotPt:
- NewOpcode = Hexagon::JMP_cdnPt;
+ case Hexagon::JMP_fnew_t:
+ NewOpcode = Hexagon::JMP_tnew_t;
break;
default:
@@ -156,8 +156,8 @@ bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {
// The target of the unconditional branch must be JumpAroundTarget.
// TODO: If not, we should not invert the unconditional branch.
MachineBasicBlock* CondBranchTarget = NULL;
- if ((MI->getOpcode() == Hexagon::JMP_c) ||
- (MI->getOpcode() == Hexagon::JMP_cNot)) {
+ if ((MI->getOpcode() == Hexagon::JMP_t) ||
+ (MI->getOpcode() == Hexagon::JMP_f)) {
CondBranchTarget = MI->getOperand(1).getMBB();
}
diff --git a/lib/Target/Hexagon/HexagonFrameLowering.cpp b/lib/Target/Hexagon/HexagonFrameLowering.cpp
index d6a9329..de993ee8 100644
--- a/lib/Target/Hexagon/HexagonFrameLowering.cpp
+++ b/lib/Target/Hexagon/HexagonFrameLowering.cpp
@@ -189,7 +189,7 @@ void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
// Replace 'jumpr r31' instruction with dealloc_return for V4 and higher
// versions.
- if (STI.hasV4TOps() && MBBI->getOpcode() == Hexagon::JMPR
+ if (STI.hasV4TOps() && MBBI->getOpcode() == Hexagon::JMPret
&& !DisableDeallocRet) {
// Remove jumpr node.
MBB.erase(MBBI);
diff --git a/lib/Target/Hexagon/HexagonHardwareLoops.cpp b/lib/Target/Hexagon/HexagonHardwareLoops.cpp
index 62aed13..d002788 100644
--- a/lib/Target/Hexagon/HexagonHardwareLoops.cpp
+++ b/lib/Target/Hexagon/HexagonHardwareLoops.cpp
@@ -541,12 +541,6 @@ CountValue *HexagonHardwareLoops::getLoopTripCount(MachineLoop *L,
case Hexagon::CMPEQrr:
Cmp = !Negated ? Comparison::EQ : Comparison::NE;
break;
- case Hexagon::CMPLTrr:
- Cmp = !Negated ? Comparison::LTs : Comparison::GEs;
- break;
- case Hexagon::CMPLTUrr:
- Cmp = !Negated ? Comparison::LTu : Comparison::GEu;
- break;
case Hexagon::CMPGTUri:
case Hexagon::CMPGTUrr:
Cmp = !Negated ? Comparison::GTu : Comparison::LEu;
@@ -701,7 +695,7 @@ CountValue *HexagonHardwareLoops::computeCount(MachineLoop *Loop,
// If the induction variable bump is not a power of 2, quit.
// Othwerise we'd need a general integer division.
- if (!isPowerOf2_64(abs(IVBump)))
+ if (!isPowerOf2_64(abs64(IVBump)))
return 0;
MachineBasicBlock *PH = Loop->getLoopPreheader();
@@ -1125,8 +1119,8 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L) {
// The loop ends with either:
// - a conditional branch followed by an unconditional branch, or
// - a conditional branch to the loop start.
- if (LastI->getOpcode() == Hexagon::JMP_c ||
- LastI->getOpcode() == Hexagon::JMP_cNot) {
+ if (LastI->getOpcode() == Hexagon::JMP_t ||
+ LastI->getOpcode() == Hexagon::JMP_f) {
// Delete one and change/add an uncond. branch to out of the loop.
MachineBasicBlock *BranchTarget = LastI->getOperand(1).getMBB();
LastI = LastMBB->erase(LastI);
@@ -1430,7 +1424,6 @@ MachineBasicBlock *HexagonHardwareLoops::createPreheaderForLoop(
return 0;
typedef MachineBasicBlock::instr_iterator instr_iterator;
- typedef MachineBasicBlock::pred_iterator pred_iterator;
// Verify that all existing predecessors have analyzable branches
// (or no branches at all).
diff --git a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
index 3a1c48b..ba6c100 100644
--- a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
+++ b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
@@ -113,6 +113,46 @@ public:
SDNode *SelectAdd(SDNode *N);
bool isConstExtProfitable(SDNode *N) const;
+// XformMskToBitPosU5Imm - Returns the bit position which
+// the single bit 32 bit mask represents.
+// Used in Clr and Set bit immediate memops.
+SDValue XformMskToBitPosU5Imm(uint32_t Imm) {
+ int32_t bitPos;
+ bitPos = Log2_32(Imm);
+ assert(bitPos >= 0 && bitPos < 32 &&
+ "Constant out of range for 32 BitPos Memops");
+ return CurDAG->getTargetConstant(bitPos, MVT::i32);
+}
+
+// XformMskToBitPosU4Imm - Returns the bit position which the single bit 16 bit
+// mask represents. Used in Clr and Set bit immediate memops.
+SDValue XformMskToBitPosU4Imm(uint16_t Imm) {
+ return XformMskToBitPosU5Imm(Imm);
+}
+
+// XformMskToBitPosU3Imm - Returns the bit position which the single bit 8 bit
+// mask represents. Used in Clr and Set bit immediate memops.
+SDValue XformMskToBitPosU3Imm(uint8_t Imm) {
+ return XformMskToBitPosU5Imm(Imm);
+}
+
+// Return true if there is exactly one bit set in V, i.e., if V is one of the
+// following integers: 2^0, 2^1, ..., 2^31.
+bool ImmIsSingleBit(uint32_t v) const {
+ uint32_t c = CountPopulation_64(v);
+ // Only return true if we counted 1 bit.
+ return c == 1;
+}
+
+// XformM5ToU5Imm - Return a target constant with the specified value, of type
+// i32 where the negative literal is transformed into a positive literal for
+// use in -= memops.
+inline SDValue XformM5ToU5Imm(signed Imm) {
+ assert( (Imm >= -31 && Imm <= -1) && "Constant out of range for Memops");
+ return CurDAG->getTargetConstant( - Imm, MVT::i32);
+}
+
+
// XformU7ToU7M1Imm - Return a target constant decremented by 1, in range
// [1..128], used in cmpb.gtu instructions.
inline SDValue XformU7ToU7M1Imm(signed Imm) {
@@ -120,6 +160,17 @@ inline SDValue XformU7ToU7M1Imm(signed Imm) {
return CurDAG->getTargetConstant(Imm - 1, MVT::i8);
}
+// XformS8ToS8M1Imm - Return a target constant decremented by 1.
+inline SDValue XformSToSM1Imm(signed Imm) {
+ return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
+}
+
+// XformU8ToU8M1Imm - Return a target constant decremented by 1.
+inline SDValue XformUToUM1Imm(unsigned Imm) {
+ assert((Imm >= 1) && "Cannot decrement unsigned int less than 1");
+ return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
+}
+
// Include the pieces autogenerated from the target description.
#include "HexagonGenDAGISel.inc"
};
@@ -657,7 +708,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) {
// Build post increment store.
SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
- MVT::Other, Ops, 4);
+ MVT::Other, Ops);
MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
MemOp[0] = ST->getMemOperand();
cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
@@ -683,8 +734,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) {
// Build regular store.
SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
- SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops,
- 4);
+ SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
// Build splitted incriment instruction.
SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
Base,
@@ -740,7 +790,7 @@ SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
Value, Chain};
// build indexed store
SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
- MVT::Other, Ops, 4);
+ MVT::Other, Ops);
MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
MemOp[0] = ST->getMemOperand();
cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
@@ -1190,8 +1240,7 @@ SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
}
EVT ReturnValueVT = N->getValueType(0);
SDNode *Result = CurDAG->getMachineNode(IntrinsicWithPred, dl,
- ReturnValueVT,
- Ops.data(), Ops.size());
+ ReturnValueVT, Ops);
ReplaceUses(N, Result);
return Result;
}
diff --git a/lib/Target/Hexagon/HexagonISelLowering.cpp b/lib/Target/Hexagon/HexagonISelLowering.cpp
index 0a8b1af..0e5b8dc 100644
--- a/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -1002,14 +1002,6 @@ HexagonTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
return FrameAddr;
}
-
-SDValue HexagonTargetLowering::LowerMEMBARRIER(SDValue Op,
- SelectionDAG& DAG) const {
- DebugLoc dl = Op.getDebugLoc();
- return DAG.getNode(HexagonISD::BARRIER, dl, MVT::Other, Op.getOperand(0));
-}
-
-
SDValue HexagonTargetLowering::LowerATOMIC_FENCE(SDValue Op,
SelectionDAG& DAG) const {
DebugLoc dl = Op.getDebugLoc();
@@ -1361,7 +1353,6 @@ HexagonTargetLowering::HexagonTargetLowering(HexagonTargetMachine
}
- setOperationAction(ISD::BRIND, MVT::Other, Expand);
if (EmitJumpTables) {
setOperationAction(ISD::BR_JT, MVT::Other, Custom);
} else {
@@ -1370,12 +1361,13 @@ HexagonTargetLowering::HexagonTargetLowering(HexagonTargetMachine
// Increase jump tables cutover to 5, was 4.
setMinimumJumpTableEntries(5);
+ setOperationAction(ISD::BR_CC, MVT::Other, Expand);
setOperationAction(ISD::BR_CC, MVT::f32, Expand);
setOperationAction(ISD::BR_CC, MVT::f64, Expand);
setOperationAction(ISD::BR_CC, MVT::i1, Expand);
setOperationAction(ISD::BR_CC, MVT::i32, Expand);
+ setOperationAction(ISD::BR_CC, MVT::i64, Expand);
- setOperationAction(ISD::MEMBARRIER, MVT::Other, Custom);
setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
setOperationAction(ISD::FSIN , MVT::f64, Expand);
@@ -1442,7 +1434,7 @@ HexagonTargetLowering::HexagonTargetLowering(HexagonTargetMachine
setOperationAction(ISD::EXCEPTIONADDR, MVT::i32, Expand);
setOperationAction(ISD::EHSELECTION, MVT::i32, Expand);
- setOperationAction(ISD::EH_RETURN, MVT::Other, Expand);
+ setOperationAction(ISD::EH_RETURN, MVT::Other, Custom);
if (TM.getSubtargetImpl()->isSubtargetV2()) {
setExceptionPointerRegister(Hexagon::R20);
@@ -1497,6 +1489,7 @@ HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const {
case HexagonISD::RET_FLAG: return "HexagonISD::RET_FLAG";
case HexagonISD::BR_JT: return "HexagonISD::BR_JT";
case HexagonISD::TC_RETURN: return "HexagonISD::TC_RETURN";
+ case HexagonISD::EH_RETURN: return "HexagonISD::EH_RETURN";
}
}
@@ -1518,16 +1511,43 @@ bool HexagonTargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
}
SDValue
+HexagonTargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const {
+ SDValue Chain = Op.getOperand(0);
+ SDValue Offset = Op.getOperand(1);
+ SDValue Handler = Op.getOperand(2);
+ DebugLoc dl = Op.getDebugLoc();
+
+ // Mark function as containing a call to EH_RETURN.
+ HexagonMachineFunctionInfo *FuncInfo =
+ DAG.getMachineFunction().getInfo<HexagonMachineFunctionInfo>();
+ FuncInfo->setHasEHReturn();
+
+ unsigned OffsetReg = Hexagon::R28;
+
+ SDValue StoreAddr = DAG.getNode(ISD::ADD, dl, getPointerTy(),
+ DAG.getRegister(Hexagon::R30, getPointerTy()),
+ DAG.getIntPtrConstant(4));
+ Chain = DAG.getStore(Chain, dl, Handler, StoreAddr, MachinePointerInfo(),
+ false, false, 0);
+ Chain = DAG.getCopyToReg(Chain, dl, OffsetReg, Offset);
+
+ // Not needed we already use it as explict input to EH_RETURN.
+ // MF.getRegInfo().addLiveOut(OffsetReg);
+
+ return DAG.getNode(HexagonISD::EH_RETURN, dl, MVT::Other, Chain);
+}
+
+SDValue
HexagonTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
switch (Op.getOpcode()) {
default: llvm_unreachable("Should not custom lower this!");
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
+ case ISD::EH_RETURN: return LowerEH_RETURN(Op, DAG);
// Frame & Return address. Currently unimplemented.
case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
case ISD::GlobalTLSAddress:
llvm_unreachable("TLS not implemented for Hexagon.");
- case ISD::MEMBARRIER: return LowerMEMBARRIER(Op, DAG);
case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG);
case ISD::GlobalAddress: return LowerGLOBALADDRESS(Op, DAG);
case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
diff --git a/lib/Target/Hexagon/HexagonISelLowering.h b/lib/Target/Hexagon/HexagonISelLowering.h
index 3279cc6..bb1acc1 100644
--- a/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/lib/Target/Hexagon/HexagonISelLowering.h
@@ -62,7 +62,8 @@ namespace llvm {
WrapperShuffEH,
WrapperShuffOB,
WrapperShuffOH,
- TC_RETURN
+ TC_RETURN,
+ EH_RETURN
};
}
@@ -101,6 +102,7 @@ namespace llvm {
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerEH_LABEL(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFormalArguments(SDValue Chain,
CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
@@ -122,7 +124,6 @@ namespace llvm {
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerMEMBARRIER(SDValue Op, SelectionDAG& DAG) const;
SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
diff --git a/lib/Target/Hexagon/HexagonInstrInfo.cpp b/lib/Target/Hexagon/HexagonInstrInfo.cpp
index 96a252e..e0beab0 100644
--- a/lib/Target/Hexagon/HexagonInstrInfo.cpp
+++ b/lib/Target/Hexagon/HexagonInstrInfo.cpp
@@ -23,6 +23,7 @@
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#define GET_INSTRINFO_CTOR
#define GET_INSTRMAP_INFO
@@ -118,16 +119,16 @@ HexagonInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
DebugLoc DL) const{
int BOpc = Hexagon::JMP;
- int BccOpc = Hexagon::JMP_c;
+ int BccOpc = Hexagon::JMP_t;
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
int regPos = 0;
// Check if ReverseBranchCondition has asked to reverse this branch
// If we want to reverse the branch an odd number of times, we want
- // JMP_cNot.
+ // JMP_f.
if (!Cond.empty() && Cond[0].isImm() && Cond[0].getImm() == 0) {
- BccOpc = Hexagon::JMP_cNot;
+ BccOpc = Hexagon::JMP_f;
regPos = 1;
}
@@ -174,8 +175,8 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
FBB = NULL;
// If the block has no terminators, it just falls into the block after it.
- MachineBasicBlock::iterator I = MBB.end();
- if (I == MBB.begin())
+ MachineBasicBlock::instr_iterator I = MBB.instr_end();
+ if (I == MBB.instr_begin())
return false;
// A basic block may looks like this:
@@ -194,13 +195,24 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
--I;
if (I->isEHLabel())
return true;
- } while (I != MBB.begin());
+ } while (I != MBB.instr_begin());
- I = MBB.end();
+ I = MBB.instr_end();
--I;
while (I->isDebugValue()) {
- if (I == MBB.begin())
+ if (I == MBB.instr_begin())
+ return false;
+ --I;
+ }
+
+ // Delete the JMP if it's equivalent to a fall-through.
+ if (AllowModify && I->getOpcode() == Hexagon::JMP &&
+ MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
+ DEBUG(dbgs()<< "\nErasing the jump to successor block\n";);
+ I->eraseFromParent();
+ I = MBB.instr_end();
+ if (I == MBB.instr_begin())
return false;
--I;
}
@@ -209,23 +221,42 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
// Get the last instruction in the block.
MachineInstr *LastInst = I;
+ MachineInstr *SecondLastInst = NULL;
+ // Find one more terminator if present.
+ do {
+ if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(I)) {
+ if (!SecondLastInst)
+ SecondLastInst = I;
+ else
+ // This is a third branch.
+ return true;
+ }
+ if (I == MBB.instr_begin())
+ break;
+ --I;
+ } while(I);
+
+ int LastOpcode = LastInst->getOpcode();
+
+ bool LastOpcodeHasJMP_c = PredOpcodeHasJMP_c(LastOpcode);
+ bool LastOpcodeHasNot = PredOpcodeHasNot(LastOpcode);
// If there is only one terminator instruction, process it.
- if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
- if (LastInst->getOpcode() == Hexagon::JMP) {
+ if (LastInst && !SecondLastInst) {
+ if (LastOpcode == Hexagon::JMP) {
TBB = LastInst->getOperand(0).getMBB();
return false;
}
- if (LastInst->getOpcode() == Hexagon::JMP_c) {
- // Block ends with fall-through true condbranch.
- TBB = LastInst->getOperand(1).getMBB();
+ if (LastOpcode == Hexagon::ENDLOOP0) {
+ TBB = LastInst->getOperand(0).getMBB();
Cond.push_back(LastInst->getOperand(0));
return false;
}
- if (LastInst->getOpcode() == Hexagon::JMP_cNot) {
- // Block ends with fall-through false condbranch.
+ if (LastOpcodeHasJMP_c) {
TBB = LastInst->getOperand(1).getMBB();
- Cond.push_back(MachineOperand::CreateImm(0));
+ if (LastOpcodeHasNot) {
+ Cond.push_back(MachineOperand::CreateImm(0));
+ }
Cond.push_back(LastInst->getOperand(0));
return false;
}
@@ -233,29 +264,14 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
return true;
}
- // Get the instruction before it if it's a terminator.
- MachineInstr *SecondLastInst = I;
-
- // If there are three terminators, we don't know what sort of block this is.
- if (SecondLastInst && I != MBB.begin() &&
- isUnpredicatedTerminator(--I))
- return true;
-
- // If the block ends with Hexagon::BRCOND and Hexagon:JMP, handle it.
- if (((SecondLastInst->getOpcode() == Hexagon::BRCOND) ||
- (SecondLastInst->getOpcode() == Hexagon::JMP_c)) &&
- LastInst->getOpcode() == Hexagon::JMP) {
- TBB = SecondLastInst->getOperand(1).getMBB();
- Cond.push_back(SecondLastInst->getOperand(0));
- FBB = LastInst->getOperand(0).getMBB();
- return false;
- }
+ int SecLastOpcode = SecondLastInst->getOpcode();
- // If the block ends with Hexagon::JMP_cNot and Hexagon:JMP, handle it.
- if ((SecondLastInst->getOpcode() == Hexagon::JMP_cNot) &&
- LastInst->getOpcode() == Hexagon::JMP) {
+ bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);
+ bool SecLastOpcodeHasNot = PredOpcodeHasNot(SecLastOpcode);
+ if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::JMP)) {
TBB = SecondLastInst->getOperand(1).getMBB();
- Cond.push_back(MachineOperand::CreateImm(0));
+ if (SecLastOpcodeHasNot)
+ Cond.push_back(MachineOperand::CreateImm(0));
Cond.push_back(SecondLastInst->getOperand(0));
FBB = LastInst->getOperand(0).getMBB();
return false;
@@ -263,8 +279,7 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
// If the block ends with two Hexagon:JMPs, handle it. The second one is not
// executed, so remove it.
- if (SecondLastInst->getOpcode() == Hexagon::JMP &&
- LastInst->getOpcode() == Hexagon::JMP) {
+ if (SecLastOpcode == Hexagon::JMP && LastOpcode == Hexagon::JMP) {
TBB = SecondLastInst->getOperand(0).getMBB();
I = LastInst;
if (AllowModify)
@@ -272,6 +287,15 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
return false;
}
+ // If the block ends with an ENDLOOP, and JMP, handle it.
+ if (SecLastOpcode == Hexagon::ENDLOOP0 &&
+ LastOpcode == Hexagon::JMP) {
+ TBB = SecondLastInst->getOperand(0).getMBB();
+ Cond.push_back(SecondLastInst->getOperand(0));
+ FBB = LastInst->getOperand(0).getMBB();
+ return false;
+ }
+
// Otherwise, can't handle this.
return true;
}
@@ -279,8 +303,8 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
unsigned HexagonInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
int BOpc = Hexagon::JMP;
- int BccOpc = Hexagon::JMP_c;
- int BccOpcNot = Hexagon::JMP_cNot;
+ int BccOpc = Hexagon::JMP_t;
+ int BccOpcNot = Hexagon::JMP_f;
MachineBasicBlock::iterator I = MBB.end();
if (I == MBB.begin()) return 0;
@@ -325,8 +349,6 @@ bool HexagonInstrInfo::analyzeCompare(const MachineInstr *MI,
case Hexagon::CMPGTUrr:
case Hexagon::CMPGTri:
case Hexagon::CMPGTrr:
- case Hexagon::CMPLTUrr:
- case Hexagon::CMPLTrr:
SrcReg = MI->getOperand(1).getReg();
Mask = ~0;
break;
@@ -366,8 +388,6 @@ bool HexagonInstrInfo::analyzeCompare(const MachineInstr *MI,
case Hexagon::CMPhEQrr_xor_V4:
case Hexagon::CMPhGTUrr_V4:
case Hexagon::CMPhGTrr_shl_V4:
- case Hexagon::CMPLTUrr:
- case Hexagon::CMPLTrr:
SrcReg2 = MI->getOperand(2).getReg();
return true;
@@ -537,6 +557,15 @@ MachineInstr *HexagonInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
return(0);
}
+MachineInstr*
+HexagonInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF,
+ int FrameIx, uint64_t Offset,
+ const MDNode *MDPtr,
+ DebugLoc DL) const {
+ MachineInstrBuilder MIB = BuildMI(MF, DL, get(Hexagon::DBG_VALUE))
+ .addImm(0).addImm(Offset).addMetadata(MDPtr);
+ return &*MIB;
+}
unsigned HexagonInstrInfo::createVR(MachineFunction* MF, MVT VT) const {
@@ -737,11 +766,6 @@ bool HexagonInstrInfo::isNewValueStore(const MachineInstr *MI) const {
case Hexagon::STrib_abs_cdnPt_nv_V4:
case Hexagon::STrib_abs_cNotPt_nv_V4:
case Hexagon::STrib_abs_cdnNotPt_nv_V4:
- case Hexagon::STrib_imm_abs_nv_V4:
- case Hexagon::STrib_imm_abs_cPt_nv_V4:
- case Hexagon::STrib_imm_abs_cdnPt_nv_V4:
- case Hexagon::STrib_imm_abs_cNotPt_nv_V4:
- case Hexagon::STrib_imm_abs_cdnNotPt_nv_V4:
// Store Halfword
case Hexagon::STrih_nv_V4:
@@ -775,11 +799,6 @@ bool HexagonInstrInfo::isNewValueStore(const MachineInstr *MI) const {
case Hexagon::STrih_abs_cdnPt_nv_V4:
case Hexagon::STrih_abs_cNotPt_nv_V4:
case Hexagon::STrih_abs_cdnNotPt_nv_V4:
- case Hexagon::STrih_imm_abs_nv_V4:
- case Hexagon::STrih_imm_abs_cPt_nv_V4:
- case Hexagon::STrih_imm_abs_cdnPt_nv_V4:
- case Hexagon::STrih_imm_abs_cNotPt_nv_V4:
- case Hexagon::STrih_imm_abs_cdnNotPt_nv_V4:
// Store Word
case Hexagon::STriw_nv_V4:
@@ -813,11 +832,6 @@ bool HexagonInstrInfo::isNewValueStore(const MachineInstr *MI) const {
case Hexagon::STriw_abs_cdnPt_nv_V4:
case Hexagon::STriw_abs_cNotPt_nv_V4:
case Hexagon::STriw_abs_cdnNotPt_nv_V4:
- case Hexagon::STriw_imm_abs_nv_V4:
- case Hexagon::STriw_imm_abs_cPt_nv_V4:
- case Hexagon::STriw_imm_abs_cdnPt_nv_V4:
- case Hexagon::STriw_imm_abs_cNotPt_nv_V4:
- case Hexagon::STriw_imm_abs_cdnNotPt_nv_V4:
return true;
}
}
@@ -994,9 +1008,6 @@ bool HexagonInstrInfo::isPredicable(MachineInstr *MI) const {
case Hexagon::ZXTB:
case Hexagon::ZXTH:
return Subtarget.hasV4TOps();
-
- case Hexagon::JMPR:
- return false;
}
return true;
@@ -1033,10 +1044,10 @@ unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const {
case Hexagon::TFRI_cNotPt:
return Hexagon::TFRI_cPt;
- case Hexagon::JMP_c:
- return Hexagon::JMP_cNot;
- case Hexagon::JMP_cNot:
- return Hexagon::JMP_c;
+ case Hexagon::JMP_t:
+ return Hexagon::JMP_f;
+ case Hexagon::JMP_f:
+ return Hexagon::JMP_t;
case Hexagon::ADD_ri_cPt:
return Hexagon::ADD_ri_cNotPt;
@@ -1104,10 +1115,10 @@ unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const {
return Hexagon::ZXTH_cPt_V4;
- case Hexagon::JMPR_cPt:
- return Hexagon::JMPR_cNotPt;
- case Hexagon::JMPR_cNotPt:
- return Hexagon::JMPR_cPt;
+ case Hexagon::JMPR_t:
+ return Hexagon::JMPR_f;
+ case Hexagon::JMPR_f:
+ return Hexagon::JMPR_t;
// V4 indexed+scaled load.
case Hexagon::LDrid_indexed_shl_cPt_V4:
@@ -1490,8 +1501,8 @@ getMatchingCondBranchOpcode(int Opc, bool invertPredicate) const {
return !invertPredicate ? Hexagon::TFRI_cPt :
Hexagon::TFRI_cNotPt;
case Hexagon::JMP:
- return !invertPredicate ? Hexagon::JMP_c :
- Hexagon::JMP_cNot;
+ return !invertPredicate ? Hexagon::JMP_t :
+ Hexagon::JMP_f;
case Hexagon::JMP_EQrrPt_nv_V4:
return !invertPredicate ? Hexagon::JMP_EQrrPt_nv_V4 :
Hexagon::JMP_EQrrNotPt_nv_V4;
@@ -1521,8 +1532,8 @@ getMatchingCondBranchOpcode(int Opc, bool invertPredicate) const {
Hexagon::ZXTH_cNotPt_V4;
case Hexagon::JMPR:
- return !invertPredicate ? Hexagon::JMPR_cPt :
- Hexagon::JMPR_cNotPt;
+ return !invertPredicate ? Hexagon::JMPR_t :
+ Hexagon::JMPR_f;
// V4 indexed+scaled load.
case Hexagon::LDrid_indexed_shl_V4:
@@ -1821,11 +1832,15 @@ PredicateInstruction(MachineInstr *MI,
// It is better to have an assert here to check this. But I don't know how
// to write this assert because findFirstPredOperandIdx() would return -1
if (oper < -1) oper = -1;
+
MI->getOperand(oper+1).ChangeToRegister(PredMO.getReg(), PredMO.isDef(),
- PredMO.isImplicit(), PredMO.isKill(),
+ PredMO.isImplicit(), false,
PredMO.isDead(), PredMO.isUndef(),
PredMO.isDebug());
+ MachineRegisterInfo &RegInfo = MI->getParent()->getParent()->getRegInfo();
+ RegInfo.clearKillFlags(PredMO.getReg());
+
if (hasGAOpnd)
{
unsigned int i;
@@ -1881,6 +1896,13 @@ bool HexagonInstrInfo::isPredicated(const MachineInstr *MI) const {
return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask);
}
+bool HexagonInstrInfo::isPredicatedNew(const MachineInstr *MI) const {
+ const uint64_t F = MI->getDesc().TSFlags;
+
+ assert(isPredicated(MI));
+ return ((F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask);
+}
+
bool
HexagonInstrInfo::DefinesPredicate(MachineInstr *MI,
std::vector<MachineOperand> &Pred) const {
@@ -1991,46 +2013,28 @@ isValidOffset(const int Opcode, const int Offset) const {
return (Offset >= Hexagon_ADDI_OFFSET_MIN) &&
(Offset <= Hexagon_ADDI_OFFSET_MAX);
- case Hexagon::MEMw_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMw_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMw_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMw_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMw_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMw_ORr_indexed_MEM_V4 :
- case Hexagon::MEMw_ADDi_MEM_V4 :
- case Hexagon::MEMw_SUBi_MEM_V4 :
- case Hexagon::MEMw_ADDr_MEM_V4 :
- case Hexagon::MEMw_SUBr_MEM_V4 :
- case Hexagon::MEMw_ANDr_MEM_V4 :
- case Hexagon::MEMw_ORr_MEM_V4 :
+ case Hexagon::MemOPw_ADDi_V4 :
+ case Hexagon::MemOPw_SUBi_V4 :
+ case Hexagon::MemOPw_ADDr_V4 :
+ case Hexagon::MemOPw_SUBr_V4 :
+ case Hexagon::MemOPw_ANDr_V4 :
+ case Hexagon::MemOPw_ORr_V4 :
return (0 <= Offset && Offset <= 255);
- case Hexagon::MEMh_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMh_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMh_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMh_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMh_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMh_ORr_indexed_MEM_V4 :
- case Hexagon::MEMh_ADDi_MEM_V4 :
- case Hexagon::MEMh_SUBi_MEM_V4 :
- case Hexagon::MEMh_ADDr_MEM_V4 :
- case Hexagon::MEMh_SUBr_MEM_V4 :
- case Hexagon::MEMh_ANDr_MEM_V4 :
- case Hexagon::MEMh_ORr_MEM_V4 :
+ case Hexagon::MemOPh_ADDi_V4 :
+ case Hexagon::MemOPh_SUBi_V4 :
+ case Hexagon::MemOPh_ADDr_V4 :
+ case Hexagon::MemOPh_SUBr_V4 :
+ case Hexagon::MemOPh_ANDr_V4 :
+ case Hexagon::MemOPh_ORr_V4 :
return (0 <= Offset && Offset <= 127);
- case Hexagon::MEMb_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMb_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMb_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMb_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMb_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMb_ORr_indexed_MEM_V4 :
- case Hexagon::MEMb_ADDi_MEM_V4 :
- case Hexagon::MEMb_SUBi_MEM_V4 :
- case Hexagon::MEMb_ADDr_MEM_V4 :
- case Hexagon::MEMb_SUBr_MEM_V4 :
- case Hexagon::MEMb_ANDr_MEM_V4 :
- case Hexagon::MEMb_ORr_MEM_V4 :
+ case Hexagon::MemOPb_ADDi_V4 :
+ case Hexagon::MemOPb_SUBi_V4 :
+ case Hexagon::MemOPb_ADDr_V4 :
+ case Hexagon::MemOPb_SUBr_V4 :
+ case Hexagon::MemOPb_ANDr_V4 :
+ case Hexagon::MemOPb_ORr_V4 :
return (0 <= Offset && Offset <= 63);
// LDri_pred and STriw_pred are pseudo operations, so it has to take offset of
@@ -2086,44 +2090,33 @@ isMemOp(const MachineInstr *MI) const {
switch (MI->getOpcode())
{
default: return false;
- case Hexagon::MEMw_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMw_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMw_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMw_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMw_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMw_ORr_indexed_MEM_V4 :
- case Hexagon::MEMw_ADDi_MEM_V4 :
- case Hexagon::MEMw_SUBi_MEM_V4 :
- case Hexagon::MEMw_ADDr_MEM_V4 :
- case Hexagon::MEMw_SUBr_MEM_V4 :
- case Hexagon::MEMw_ANDr_MEM_V4 :
- case Hexagon::MEMw_ORr_MEM_V4 :
- case Hexagon::MEMh_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMh_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMh_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMh_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMh_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMh_ORr_indexed_MEM_V4 :
- case Hexagon::MEMh_ADDi_MEM_V4 :
- case Hexagon::MEMh_SUBi_MEM_V4 :
- case Hexagon::MEMh_ADDr_MEM_V4 :
- case Hexagon::MEMh_SUBr_MEM_V4 :
- case Hexagon::MEMh_ANDr_MEM_V4 :
- case Hexagon::MEMh_ORr_MEM_V4 :
- case Hexagon::MEMb_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMb_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMb_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMb_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMb_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMb_ORr_indexed_MEM_V4 :
- case Hexagon::MEMb_ADDi_MEM_V4 :
- case Hexagon::MEMb_SUBi_MEM_V4 :
- case Hexagon::MEMb_ADDr_MEM_V4 :
- case Hexagon::MEMb_SUBr_MEM_V4 :
- case Hexagon::MEMb_ANDr_MEM_V4 :
- case Hexagon::MEMb_ORr_MEM_V4 :
- return true;
+ case Hexagon::MemOPw_ADDi_V4 :
+ case Hexagon::MemOPw_SUBi_V4 :
+ case Hexagon::MemOPw_ADDr_V4 :
+ case Hexagon::MemOPw_SUBr_V4 :
+ case Hexagon::MemOPw_ANDr_V4 :
+ case Hexagon::MemOPw_ORr_V4 :
+ case Hexagon::MemOPh_ADDi_V4 :
+ case Hexagon::MemOPh_SUBi_V4 :
+ case Hexagon::MemOPh_ADDr_V4 :
+ case Hexagon::MemOPh_SUBr_V4 :
+ case Hexagon::MemOPh_ANDr_V4 :
+ case Hexagon::MemOPh_ORr_V4 :
+ case Hexagon::MemOPb_ADDi_V4 :
+ case Hexagon::MemOPb_SUBi_V4 :
+ case Hexagon::MemOPb_ADDr_V4 :
+ case Hexagon::MemOPb_SUBr_V4 :
+ case Hexagon::MemOPb_ANDr_V4 :
+ case Hexagon::MemOPb_ORr_V4 :
+ case Hexagon::MemOPb_SETBITi_V4:
+ case Hexagon::MemOPh_SETBITi_V4:
+ case Hexagon::MemOPw_SETBITi_V4:
+ case Hexagon::MemOPb_CLRBITi_V4:
+ case Hexagon::MemOPh_CLRBITi_V4:
+ case Hexagon::MemOPw_CLRBITi_V4:
+ return true;
}
+ return false;
}
@@ -2142,14 +2135,10 @@ bool HexagonInstrInfo::isNewValueJumpCandidate(const MachineInstr *MI) const {
default: return false;
case Hexagon::CMPEQrr:
case Hexagon::CMPEQri:
- case Hexagon::CMPLTrr:
case Hexagon::CMPGTrr:
case Hexagon::CMPGTri:
- case Hexagon::CMPLTUrr:
case Hexagon::CMPGTUrr:
case Hexagon::CMPGTUri:
- case Hexagon::CMPGEri:
- case Hexagon::CMPGEUri:
return true;
}
}
@@ -2382,6 +2371,13 @@ isConditionalStore (const MachineInstr* MI) const {
}
}
+// Returns true, if any one of the operands is a dot new
+// insn, whether it is predicated dot new or register dot new.
+bool HexagonInstrInfo::isDotNewInst (const MachineInstr* MI) const {
+ return (isNewValueInst(MI) ||
+ (isPredicated(MI) && isPredicatedNew(MI)));
+}
+
unsigned HexagonInstrInfo::getAddrMode(const MachineInstr* MI) const {
const uint64_t F = MI->getDesc().TSFlags;
@@ -2476,6 +2472,34 @@ bool HexagonInstrInfo::isConstExtended(MachineInstr *MI) const {
return (ImmValue < MinValue || ImmValue > MaxValue);
}
+// Returns the opcode to use when converting MI, which is a conditional jump,
+// into a conditional instruction which uses the .new value of the predicate.
+// We also use branch probabilities to add a hint to the jump.
+int
+HexagonInstrInfo::getDotNewPredJumpOp(MachineInstr *MI,
+ const
+ MachineBranchProbabilityInfo *MBPI) const {
+
+ // We assume that block can have at most two successors.
+ bool taken = false;
+ MachineBasicBlock *Src = MI->getParent();
+ MachineOperand *BrTarget = &MI->getOperand(1);
+ MachineBasicBlock *Dst = BrTarget->getMBB();
+
+ const BranchProbability Prediction = MBPI->getEdgeProbability(Src, Dst);
+ if (Prediction >= BranchProbability(1,2))
+ taken = true;
+
+ switch (MI->getOpcode()) {
+ case Hexagon::JMP_t:
+ return taken ? Hexagon::JMP_tnew_t : Hexagon::JMP_tnew_nt;
+ case Hexagon::JMP_f:
+ return taken ? Hexagon::JMP_fnew_t : Hexagon::JMP_fnew_nt;
+
+ default:
+ llvm_unreachable("Unexpected jump instruction.");
+ }
+}
// Returns true if a particular operand is extendable for an instruction.
bool HexagonInstrInfo::isOperandExtended(const MachineInstr *MI,
unsigned short OperandNum) const {
@@ -2580,3 +2604,18 @@ short HexagonInstrInfo::getNonExtOpcode (const MachineInstr *MI) const {
}
return -1;
}
+
+bool HexagonInstrInfo::PredOpcodeHasJMP_c(Opcode_t Opcode) const {
+ return (Opcode == Hexagon::JMP_t) ||
+ (Opcode == Hexagon::JMP_f) ||
+ (Opcode == Hexagon::JMP_tnew_t) ||
+ (Opcode == Hexagon::JMP_fnew_t) ||
+ (Opcode == Hexagon::JMP_tnew_nt) ||
+ (Opcode == Hexagon::JMP_fnew_nt);
+}
+
+bool HexagonInstrInfo::PredOpcodeHasNot(Opcode_t Opcode) const {
+ return (Opcode == Hexagon::JMP_f) ||
+ (Opcode == Hexagon::JMP_fnew_t) ||
+ (Opcode == Hexagon::JMP_fnew_nt);
+}
diff --git a/lib/Target/Hexagon/HexagonInstrInfo.h b/lib/Target/Hexagon/HexagonInstrInfo.h
index d2f059a..e0bec04 100644
--- a/lib/Target/Hexagon/HexagonInstrInfo.h
+++ b/lib/Target/Hexagon/HexagonInstrInfo.h
@@ -16,9 +16,9 @@
#include "HexagonRegisterInfo.h"
#include "MCTargetDesc/HexagonBaseInfo.h"
-#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetInstrInfo.h"
-
+#include "llvm/Target/TargetFrameLowering.h"
+#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
#define GET_INSTRINFO_HEADER
#include "HexagonGenInstrInfo.inc"
@@ -28,6 +28,8 @@ namespace llvm {
class HexagonInstrInfo : public HexagonGenInstrInfo {
const HexagonRegisterInfo RI;
const HexagonSubtarget& Subtarget;
+ typedef unsigned Opcode_t;
+
public:
explicit HexagonInstrInfo(HexagonSubtarget &ST);
@@ -127,6 +129,7 @@ public:
const BranchProbability &Probability) const;
virtual bool isPredicated(const MachineInstr *MI) const;
+ virtual bool isPredicatedNew(const MachineInstr *MI) const;
virtual bool DefinesPredicate(MachineInstr *MI,
std::vector<MachineOperand> &Pred) const;
virtual bool
@@ -140,6 +143,11 @@ public:
isProfitableToDupForIfCvt(MachineBasicBlock &MBB,unsigned NumCycles,
const BranchProbability &Probability) const;
+ virtual MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF,
+ int FrameIx,
+ uint64_t Offset,
+ const MDNode *MDPtr,
+ DebugLoc DL) const;
virtual DFAPacketizer*
CreateTargetScheduleState(const TargetMachine *TM,
const ScheduleDAG *DAG) const;
@@ -170,6 +178,7 @@ public:
bool isConditionalLoad (const MachineInstr* MI) const;
bool isConditionalStore(const MachineInstr* MI) const;
bool isNewValueInst(const MachineInstr* MI) const;
+ bool isDotNewInst(const MachineInstr* MI) const;
bool isDeallocRet(const MachineInstr *MI) const;
unsigned getInvertedPredicatedOpcode(const int Opc) const;
bool isExtendable(const MachineInstr* MI) const;
@@ -182,6 +191,8 @@ public:
void immediateExtend(MachineInstr *MI) const;
bool isConstExtended(MachineInstr *MI) const;
+ int getDotNewPredJumpOp(MachineInstr *MI,
+ const MachineBranchProbabilityInfo *MBPI) const;
unsigned getAddrMode(const MachineInstr* MI) const;
bool isOperandExtended(const MachineInstr *MI,
unsigned short OperandNum) const;
@@ -190,6 +201,9 @@ public:
int getMaxValue(const MachineInstr *MI) const;
bool NonExtEquivalentExists (const MachineInstr *MI) const;
short getNonExtOpcode(const MachineInstr *MI) const;
+ bool PredOpcodeHasJMP_c(Opcode_t Opcode) const;
+ bool PredOpcodeHasNot(Opcode_t Opcode) const;
+
private:
int getMatchingCondBranchOpcode(int Opc, bool sense) const;
diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td
index d7bab20..2a4b17b 100644
--- a/lib/Target/Hexagon/HexagonInstrInfo.td
+++ b/lib/Target/Hexagon/HexagonInstrInfo.td
@@ -14,6 +14,8 @@
include "HexagonInstrFormats.td"
include "HexagonOperands.td"
+//===----------------------------------------------------------------------===//
+
// Multi-class for logical operators.
multiclass ALU32_rr_ri<string OpcStr, SDNode OpNode> {
def rr : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
@@ -34,12 +36,6 @@ multiclass CMP64_rr<string OpcStr, PatFrag OpNode> {
[(set (i1 PredRegs:$dst),
(OpNode (i64 DoubleRegs:$b), (i64 DoubleRegs:$c)))]>;
}
-multiclass CMP32_rr<string OpcStr, PatFrag OpNode> {
- def rr : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
- !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
- [(set (i1 PredRegs:$dst),
- (OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>;
-}
multiclass CMP32_rr_ri_s10<string OpcStr, string CextOp, PatFrag OpNode> {
let CextOpcode = CextOp in {
@@ -75,14 +71,6 @@ multiclass CMP32_rr_ri_u9<string OpcStr, string CextOp, PatFrag OpNode> {
}
}
-multiclass CMP32_ri_u8<string OpcStr, PatFrag OpNode> {
-let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 8 in
- def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, u8Ext:$c),
- !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")),
- [(set (i1 PredRegs:$dst), (OpNode (i32 IntRegs:$b),
- u8ExtPred:$c))]>;
-}
-
multiclass CMP32_ri_s8<string OpcStr, PatFrag OpNode> {
let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8 in
def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s8Ext:$c),
@@ -95,22 +83,30 @@ let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8 in
//===----------------------------------------------------------------------===//
// ALU32/ALU (Instructions with register-register form)
//===----------------------------------------------------------------------===//
-multiclass ALU32_Pbase<string mnemonic, bit isNot,
- bit isPredNew> {
+def SDTHexagonI64I32I32 : SDTypeProfile<1, 2,
+ [SDTCisVT<0, i64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
+
+def HexagonWrapperCombineII :
+ SDNode<"HexagonISD::WrapperCombineII", SDTHexagonI64I32I32>;
+
+def HexagonWrapperCombineRR :
+ SDNode<"HexagonISD::WrapperCombineRR", SDTHexagonI64I32I32>;
- let PNewValue = !if(isPredNew, "new", "") in
- def NAME : ALU32_rr<(outs IntRegs:$dst),
+multiclass ALU32_Pbase<string mnemonic, RegisterClass RC, bit isNot,
+ bit isPredNew> {
+ let isPredicatedNew = isPredNew in
+ def NAME : ALU32_rr<(outs RC:$dst),
(ins PredRegs:$src1, IntRegs:$src2, IntRegs: $src3),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ",
") $dst = ")#mnemonic#"($src2, $src3)",
[]>;
}
-multiclass ALU32_Pred<string mnemonic, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
- defm _c#NAME : ALU32_Pbase<mnemonic, PredNot, 0>;
+multiclass ALU32_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
+ let isPredicatedFalse = PredNot in {
+ defm _c#NAME : ALU32_Pbase<mnemonic, RC, PredNot, 0>;
// Predicate new
- defm _cdn#NAME : ALU32_Pbase<mnemonic, PredNot, 1>;
+ defm _cdn#NAME : ALU32_Pbase<mnemonic, RC, PredNot, 1>;
}
}
@@ -125,8 +121,8 @@ multiclass ALU32_base<string mnemonic, string CextOp, SDNode OpNode> {
(i32 IntRegs:$src2)))]>;
let neverHasSideEffects = 1, isPredicated = 1 in {
- defm Pt : ALU32_Pred<mnemonic, 0>;
- defm NotPt : ALU32_Pred<mnemonic, 1>;
+ defm Pt : ALU32_Pred<mnemonic, IntRegs, 0>;
+ defm NotPt : ALU32_Pred<mnemonic, IntRegs, 1>;
}
}
}
@@ -140,11 +136,42 @@ let isCommutable = 1 in {
defm SUB_rr : ALU32_base<"sub", "SUB", sub>, ImmRegRel, PredNewRel;
+// Combines the two integer registers SRC1 and SRC2 into a double register.
+let isPredicable = 1 in
+class T_Combine : ALU32_rr<(outs DoubleRegs:$dst),
+ (ins IntRegs:$src1, IntRegs:$src2),
+ "$dst = combine($src1, $src2)",
+ [(set (i64 DoubleRegs:$dst),
+ (i64 (HexagonWrapperCombineRR (i32 IntRegs:$src1),
+ (i32 IntRegs:$src2))))]>;
+
+multiclass Combine_base {
+ let BaseOpcode = "combine" in {
+ def NAME : T_Combine;
+ let neverHasSideEffects = 1, isPredicated = 1 in {
+ defm Pt : ALU32_Pred<"combine", DoubleRegs, 0>;
+ defm NotPt : ALU32_Pred<"combine", DoubleRegs, 1>;
+ }
+ }
+}
+
+defm COMBINE_rr : Combine_base, PredNewRel;
+
+// Combines the two immediates SRC1 and SRC2 into a double register.
+class COMBINE_imm<Operand imm1, Operand imm2, PatLeaf pat1, PatLeaf pat2> :
+ ALU32_ii<(outs DoubleRegs:$dst), (ins imm1:$src1, imm2:$src2),
+ "$dst = combine(#$src1, #$src2)",
+ [(set (i64 DoubleRegs:$dst),
+ (i64 (HexagonWrapperCombineII (i32 pat1:$src1), (i32 pat2:$src2))))]>;
+
+let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 8 in
+def COMBINE_Ii : COMBINE_imm<s8Ext, s8Imm, s8ExtPred, s8ImmPred>;
+
//===----------------------------------------------------------------------===//
// ALU32/ALU (ADD with register-immediate form)
//===----------------------------------------------------------------------===//
multiclass ALU32ri_Pbase<string mnemonic, bit isNot, bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : ALU32_ri<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, s8Ext: $src3),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ",
@@ -153,7 +180,7 @@ multiclass ALU32ri_Pbase<string mnemonic, bit isNot, bit isPredNew> {
}
multiclass ALU32ri_Pred<string mnemonic, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ALU32ri_Pbase<mnemonic, PredNot, 0>;
// Predicate new
defm _cdn#NAME : ALU32ri_Pbase<mnemonic, PredNot, 1>;
@@ -189,11 +216,6 @@ def OR_ri : ALU32_ri<(outs IntRegs:$dst),
[(set (i32 IntRegs:$dst), (or (i32 IntRegs:$src1),
s10ExtPred:$src2))]>, ImmRegRel;
-def NOT_rr : ALU32_rr<(outs IntRegs:$dst),
- (ins IntRegs:$src1),
- "$dst = not($src1)",
- [(set (i32 IntRegs:$dst), (not (i32 IntRegs:$src1)))]>;
-
let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 10,
InputType = "imm", CextOpcode = "AND" in
def AND_ri : ALU32_ri<(outs IntRegs:$dst),
@@ -201,10 +223,7 @@ def AND_ri : ALU32_ri<(outs IntRegs:$dst),
"$dst = and($src1, #$src2)",
[(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1),
s10ExtPred:$src2))]>, ImmRegRel;
-// Negate.
-def NEG : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
- "$dst = neg($src1)",
- [(set (i32 IntRegs:$dst), (ineg (i32 IntRegs:$src1)))]>;
+
// Nop.
let neverHasSideEffects = 1 in
def NOP : ALU32_rr<(outs), (ins),
@@ -220,15 +239,21 @@ def SUB_ri : ALU32_ri<(outs IntRegs:$dst),
[(set IntRegs:$dst, (sub s10ExtPred:$src1, IntRegs:$src2))]>,
ImmRegRel;
+// Rd = not(Rs) gets mapped to Rd=sub(#-1, Rs).
+def : Pat<(not (i32 IntRegs:$src1)),
+ (SUB_ri -1, (i32 IntRegs:$src1))>;
+
+// Rd = neg(Rs) gets mapped to Rd=sub(#0, Rs).
+// Pattern definition for 'neg' was not necessary.
multiclass TFR_Pred<bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
def _c#NAME : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
!if(PredNot, "if (!$src1", "if ($src1")#") $dst = $src2",
[]>;
// Predicate new
- let PNewValue = "new" in
+ let isPredicatedNew = 1 in
def _cdn#NAME : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
!if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = $src2",
@@ -274,10 +299,10 @@ class T_TFR64_Pred<bit PredNot, bit isPredNew>
}
multiclass TFR64_Pred<bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
def _c#NAME : T_TFR64_Pred<PredNot, 0>;
- let PNewValue = "new" in
+ let isPredicatedNew = 1 in
def _cdn#NAME : T_TFR64_Pred<PredNot, 1>; // Predicate new
}
}
@@ -309,14 +334,14 @@ multiclass TFR64_base<string BaseName> {
}
multiclass TFRI_Pred<bit PredNot> {
- let isMoveImm = 1, PredSense = !if(PredNot, "false", "true") in {
+ let isMoveImm = 1, isPredicatedFalse = PredNot in {
def _c#NAME : ALU32_ri<(outs IntRegs:$dst),
(ins PredRegs:$src1, s12Ext:$src2),
!if(PredNot, "if (!$src1", "if ($src1")#") $dst = #$src2",
[]>;
// Predicate new
- let PNewValue = "new" in
+ let isPredicatedNew = 1 in
def _cdn#NAME : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, s12Ext:$src2),
!if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = #$src2",
@@ -359,52 +384,6 @@ def TFCR : CRInst<(outs CRRegs:$dst), (ins IntRegs:$src1),
// ALU32/PERM +
//===----------------------------------------------------------------------===//
-// Combine.
-
-def SDTHexagonI64I32I32 : SDTypeProfile<1, 2,
- [SDTCisVT<0, i64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
-
-def HexagonWrapperCombineII :
- SDNode<"HexagonISD::WrapperCombineII", SDTHexagonI64I32I32>;
-def HexagonWrapperCombineRR :
- SDNode<"HexagonISD::WrapperCombineRR", SDTHexagonI64I32I32>;
-
-// Combines the two integer registers SRC1 and SRC2 into a double register.
-let isPredicable = 1 in
-def COMBINE_rr : ALU32_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src1,
- IntRegs:$src2),
- "$dst = combine($src1, $src2)",
- [(set (i64 DoubleRegs:$dst),
- (i64 (HexagonWrapperCombineRR (i32 IntRegs:$src1),
- (i32 IntRegs:$src2))))]>;
-
-// Rd=combine(Rt.[HL], Rs.[HL])
-class COMBINE_halves<string A, string B>: ALU32_rr<(outs IntRegs:$dst),
- (ins IntRegs:$src1,
- IntRegs:$src2),
- "$dst = combine($src1."# A #", $src2."# B #")", []>;
-
-let isPredicable = 1 in {
- def COMBINE_hh : COMBINE_halves<"H", "H">;
- def COMBINE_hl : COMBINE_halves<"H", "L">;
- def COMBINE_lh : COMBINE_halves<"L", "H">;
- def COMBINE_ll : COMBINE_halves<"L", "L">;
-}
-
-def : Pat<(i32 (trunc (i64 (srl (i64 DoubleRegs:$a), (i32 16))))),
- (COMBINE_lh (EXTRACT_SUBREG (i64 DoubleRegs:$a), subreg_hireg),
- (EXTRACT_SUBREG (i64 DoubleRegs:$a), subreg_loreg))>;
-
-// Combines the two immediates SRC1 and SRC2 into a double register.
-class COMBINE_imm<Operand imm1, Operand imm2, PatLeaf pat1, PatLeaf pat2> :
- ALU32_ii<(outs DoubleRegs:$dst), (ins imm1:$src1, imm2:$src2),
- "$dst = combine(#$src1, #$src2)",
- [(set (i64 DoubleRegs:$dst),
- (i64 (HexagonWrapperCombineII (i32 pat1:$src1), (i32 pat2:$src2))))]>;
-
-let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 8 in
-def COMBINE_Ii : COMBINE_imm<s8Ext, s8Imm, s8ExtPred, s8ImmPred>;
-
// Mux.
def VMUX_prr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1,
DoubleRegs:$src2,
@@ -446,38 +425,58 @@ def MUX_ii : ALU32_ii<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Ext:$src2,
s8ExtPred:$src2,
s8ImmPred:$src3)))]>;
-// Shift halfword.
-let isPredicable = 1 in
-def ASLH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
- "$dst = aslh($src1)",
- [(set (i32 IntRegs:$dst), (shl 16, (i32 IntRegs:$src1)))]>;
+// ALU32 - aslh, asrh, sxtb, sxth, zxtb, zxth
+multiclass ALU32_2op_Pbase<string mnemonic, bit isNot, bit isPredNew> {
+ let isPredicatedNew = isPredNew in
+ def NAME : ALU32Inst<(outs IntRegs:$dst),
+ (ins PredRegs:$src1, IntRegs:$src2),
+ !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ",
+ ") $dst = ")#mnemonic#"($src2)">,
+ Requires<[HasV4T]>;
+}
-let isPredicable = 1 in
-def ASRH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
- "$dst = asrh($src1)",
- [(set (i32 IntRegs:$dst), (sra 16, (i32 IntRegs:$src1)))]>;
+multiclass ALU32_2op_Pred<string mnemonic, bit PredNot> {
+ let isPredicatedFalse = PredNot in {
+ defm _c#NAME : ALU32_2op_Pbase<mnemonic, PredNot, 0>;
+ // Predicate new
+ defm _cdn#NAME : ALU32_2op_Pbase<mnemonic, PredNot, 1>;
+ }
+}
-// Sign extend.
-let isPredicable = 1 in
-def SXTB : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
- "$dst = sxtb($src1)",
- [(set (i32 IntRegs:$dst), (sext_inreg (i32 IntRegs:$src1), i8))]>;
+multiclass ALU32_2op_base<string mnemonic> {
+ let BaseOpcode = mnemonic in {
+ let isPredicable = 1, neverHasSideEffects = 1 in
+ def NAME : ALU32Inst<(outs IntRegs:$dst),
+ (ins IntRegs:$src1),
+ "$dst = "#mnemonic#"($src1)">;
-let isPredicable = 1 in
-def SXTH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
- "$dst = sxth($src1)",
- [(set (i32 IntRegs:$dst), (sext_inreg (i32 IntRegs:$src1), i16))]>;
-
-// Zero extend.
-let isPredicable = 1, neverHasSideEffects = 1 in
-def ZXTB : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
- "$dst = zxtb($src1)",
- []>;
+ let Predicates = [HasV4T], validSubTargets = HasV4SubT, isPredicated = 1,
+ neverHasSideEffects = 1 in {
+ defm Pt_V4 : ALU32_2op_Pred<mnemonic, 0>;
+ defm NotPt_V4 : ALU32_2op_Pred<mnemonic, 1>;
+ }
+ }
+}
+
+defm ASLH : ALU32_2op_base<"aslh">, PredNewRel;
+defm ASRH : ALU32_2op_base<"asrh">, PredNewRel;
+defm SXTB : ALU32_2op_base<"sxtb">, PredNewRel;
+defm SXTH : ALU32_2op_base<"sxth">, PredNewRel;
+defm ZXTB : ALU32_2op_base<"zxtb">, PredNewRel;
+defm ZXTH : ALU32_2op_base<"zxth">, PredNewRel;
+
+def : Pat <(shl (i32 IntRegs:$src1), (i32 16)),
+ (ASLH IntRegs:$src1)>;
+
+def : Pat <(sra (i32 IntRegs:$src1), (i32 16)),
+ (ASRH IntRegs:$src1)>;
+
+def : Pat <(sext_inreg (i32 IntRegs:$src1), i8),
+ (SXTB IntRegs:$src1)>;
+
+def : Pat <(sext_inreg (i32 IntRegs:$src1), i16),
+ (SXTH IntRegs:$src1)>;
-let isPredicable = 1, neverHasSideEffects = 1 in
-def ZXTH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
- "$dst = zxth($src1)",
- []>;
//===----------------------------------------------------------------------===//
// ALU32/PERM -
//===----------------------------------------------------------------------===//
@@ -487,39 +486,24 @@ def ZXTH : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
// ALU32/PRED +
//===----------------------------------------------------------------------===//
-// Conditional combine.
-let neverHasSideEffects = 1, isPredicated = 1 in
-def COMBINE_rr_cPt : ALU32_rr<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if ($src1) $dst = combine($src2, $src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def COMBINE_rr_cNotPt : ALU32_rr<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if (!$src1) $dst = combine($src2, $src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def COMBINE_rr_cdnPt : ALU32_rr<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if ($src1.new) $dst = combine($src2, $src3)",
- []>;
-
-let neverHasSideEffects = 1, isPredicated = 1 in
-def COMBINE_rr_cdnNotPt : ALU32_rr<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "if (!$src1.new) $dst = combine($src2, $src3)",
- []>;
-
// Compare.
defm CMPGTU : CMP32_rr_ri_u9<"cmp.gtu", "CMPGTU", setugt>, ImmRegRel;
defm CMPGT : CMP32_rr_ri_s10<"cmp.gt", "CMPGT", setgt>, ImmRegRel;
-defm CMPLT : CMP32_rr<"cmp.lt", setlt>;
-defm CMPLTU : CMP32_rr<"cmp.ltu", setult>;
defm CMPEQ : CMP32_rr_ri_s10<"cmp.eq", "CMPEQ", seteq>, ImmRegRel;
-defm CMPGE : CMP32_ri_s8<"cmp.ge", setge>;
-defm CMPGEU : CMP32_ri_u8<"cmp.geu", setuge>;
+
+// SDNode for converting immediate C to C-1.
+def DEC_CONST_SIGNED : SDNodeXForm<imm, [{
+ // Return the byte immediate const-1 as an SDNode.
+ int32_t imm = N->getSExtValue();
+ return XformSToSM1Imm(imm);
+}]>;
+
+// SDNode for converting immediate C to C-1.
+def DEC_CONST_UNSIGNED : SDNodeXForm<imm, [{
+ // Return the byte immediate const-1 as an SDNode.
+ uint32_t imm = N->getZExtValue();
+ return XformUToUM1Imm(imm);
+}]>;
def CTLZ_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1),
"$dst = cl0($src1)",
@@ -753,112 +737,153 @@ def XOR_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, PredRegs:$src2),
// CR -
//===----------------------------------------------------------------------===//
+def retflag : SDNode<"HexagonISD::RET_FLAG", SDTNone,
+ [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
+def eh_return: SDNode<"HexagonISD::EH_RETURN", SDTNone,
+ [SDNPHasChain]>;
-//===----------------------------------------------------------------------===//
-// J +
-//===----------------------------------------------------------------------===//
-// Jump to address.
-let isBranch = 1, isTerminator=1, isBarrier = 1, isPredicable = 1 in {
- def JMP : JInst< (outs),
- (ins brtarget:$offset),
- "jump $offset",
- [(br bb:$offset)]>;
-}
+def SDHexagonBR_JT: SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
+def HexagonBR_JT: SDNode<"HexagonISD::BR_JT", SDHexagonBR_JT, [SDNPHasChain]>;
-// if (p0) jump
-let isBranch = 1, isTerminator=1, Defs = [PC],
- isPredicated = 1 in {
- def JMP_c : JInst< (outs),
- (ins PredRegs:$src, brtarget:$offset),
- "if ($src) jump $offset",
- [(brcond (i1 PredRegs:$src), bb:$offset)]>;
-}
+let InputType = "imm", isBarrier = 1, isPredicable = 1,
+Defs = [PC], isExtendable = 1, opExtendable = 0, isExtentSigned = 1,
+opExtentBits = 24 in
+class T_JMP <dag InsDag, list<dag> JumpList = []>
+ : JInst<(outs), InsDag,
+ "jump $dst" , JumpList> {
+ bits<24> dst;
+
+ let IClass = 0b0101;
+
+ let Inst{27-25} = 0b100;
+ let Inst{24-16} = dst{23-15};
+ let Inst{13-1} = dst{14-2};
+}
+
+let InputType = "imm", isExtendable = 1, opExtendable = 1, isExtentSigned = 1,
+Defs = [PC], isPredicated = 1, opExtentBits = 17 in
+class T_JMP_c <bit PredNot, bit isPredNew, bit isTaken>:
+ JInst<(outs ), (ins PredRegs:$src, brtarget:$dst),
+ !if(PredNot, "if (!$src", "if ($src")#
+ !if(isPredNew, ".new) ", ") ")#"jump"#
+ !if(isPredNew, !if(isTaken, ":t ", ":nt "), " ")#"$dst"> {
+
+ let isBrTaken = !if(isPredNew, !if(isTaken, "true", "false"), "");
+ let isPredicatedFalse = PredNot;
+ let isPredicatedNew = isPredNew;
+ bits<2> src;
+ bits<17> dst;
+
+ let IClass = 0b0101;
+
+ let Inst{27-24} = 0b1100;
+ let Inst{21} = PredNot;
+ let Inst{12} = !if(isPredNew, isTaken, zero);
+ let Inst{11} = isPredNew;
+ let Inst{9-8} = src;
+ let Inst{23-22} = dst{16-15};
+ let Inst{20-16} = dst{14-10};
+ let Inst{13} = dst{9};
+ let Inst{7-1} = dst{8-2};
+ }
-// if (!p0) jump
-let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC],
- isPredicated = 1 in {
- def JMP_cNot : JInst< (outs),
- (ins PredRegs:$src, brtarget:$offset),
- "if (!$src) jump $offset",
- []>;
+let isBarrier = 1, Defs = [PC], isPredicable = 1, InputType = "reg" in
+class T_JMPr<dag InsDag = (ins IntRegs:$dst)>
+ : JRInst<(outs ), InsDag,
+ "jumpr $dst" ,
+ []> {
+ bits<5> dst;
+
+ let IClass = 0b0101;
+ let Inst{27-21} = 0b0010100;
+ let Inst{20-16} = dst;
}
-let isTerminator = 1, isBranch = 1, neverHasSideEffects = 1, Defs = [PC],
- isPredicated = 1 in {
- def BRCOND : JInst < (outs), (ins PredRegs:$pred, brtarget:$dst),
- "if ($pred) jump $dst",
- []>;
+let Defs = [PC], isPredicated = 1, InputType = "reg" in
+class T_JMPr_c <bit PredNot, bit isPredNew, bit isTaken>:
+ JRInst <(outs ), (ins PredRegs:$src, IntRegs:$dst),
+ !if(PredNot, "if (!$src", "if ($src")#
+ !if(isPredNew, ".new) ", ") ")#"jumpr"#
+ !if(isPredNew, !if(isTaken, ":t ", ":nt "), " ")#"$dst"> {
+
+ let isBrTaken = !if(isPredNew, !if(isTaken, "true", "false"), "");
+ let isPredicatedFalse = PredNot;
+ let isPredicatedNew = isPredNew;
+ bits<2> src;
+ bits<5> dst;
+
+ let IClass = 0b0101;
+
+ let Inst{27-22} = 0b001101;
+ let Inst{21} = PredNot;
+ let Inst{20-16} = dst;
+ let Inst{12} = !if(isPredNew, isTaken, zero);
+ let Inst{11} = isPredNew;
+ let Inst{9-8} = src;
+ let Predicates = !if(isPredNew, [HasV3T], [HasV2T]);
+ let validSubTargets = !if(isPredNew, HasV3SubT, HasV2SubT);
}
-// Jump to address conditioned on new predicate.
-// if (p0) jump:t
-let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC],
- isPredicated = 1 in {
- def JMP_cdnPt : JInst< (outs),
- (ins PredRegs:$src, brtarget:$offset),
- "if ($src.new) jump:t $offset",
- []>;
+multiclass JMP_Pred<bit PredNot> {
+ def _#NAME : T_JMP_c<PredNot, 0, 0>;
+ // Predicate new
+ def _#NAME#new_t : T_JMP_c<PredNot, 1, 1>; // taken
+ def _#NAME#new_nt : T_JMP_c<PredNot, 1, 0>; // not taken
}
-// if (!p0) jump:t
-let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC],
- isPredicated = 1 in {
- def JMP_cdnNotPt : JInst< (outs),
- (ins PredRegs:$src, brtarget:$offset),
- "if (!$src.new) jump:t $offset",
- []>;
+multiclass JMP_base<string BaseOp> {
+ let BaseOpcode = BaseOp in {
+ def NAME : T_JMP<(ins brtarget:$dst), [(br bb:$dst)]>;
+ defm t : JMP_Pred<0>;
+ defm f : JMP_Pred<1>;
+ }
}
-// Not taken.
-let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC],
- isPredicated = 1 in {
- def JMP_cdnPnt : JInst< (outs),
- (ins PredRegs:$src, brtarget:$offset),
- "if ($src.new) jump:nt $offset",
- []>;
+multiclass JMPR_Pred<bit PredNot> {
+ def NAME: T_JMPr_c<PredNot, 0, 0>;
+ // Predicate new
+ def NAME#new_tV3 : T_JMPr_c<PredNot, 1, 1>; // taken
+ def NAME#new_ntV3 : T_JMPr_c<PredNot, 1, 0>; // not taken
}
-// Not taken.
-let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC],
- isPredicated = 1 in {
- def JMP_cdnNotPnt : JInst< (outs),
- (ins PredRegs:$src, brtarget:$offset),
- "if (!$src.new) jump:nt $offset",
- []>;
+multiclass JMPR_base<string BaseOp> {
+ let BaseOpcode = BaseOp in {
+ def NAME : T_JMPr;
+ defm _t : JMPR_Pred<0>;
+ defm _f : JMPR_Pred<1>;
+ }
}
-//===----------------------------------------------------------------------===//
-// J -
-//===----------------------------------------------------------------------===//
-//===----------------------------------------------------------------------===//
-// JR +
-//===----------------------------------------------------------------------===//
-def retflag : SDNode<"HexagonISD::RET_FLAG", SDTNone,
- [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
+let isTerminator = 1, neverHasSideEffects = 1 in {
+let isBranch = 1 in
+defm JMP : JMP_base<"JMP">, PredNewRel;
-// Jump to address from register.
-let isPredicable =1, isReturn = 1, isTerminator = 1, isBarrier = 1,
- Defs = [PC], Uses = [R31] in {
- def JMPR: JRInst<(outs), (ins),
- "jumpr r31",
- [(retflag)]>;
-}
+let isBranch = 1, isIndirectBranch = 1 in
+defm JMPR : JMPR_base<"JMPr">, PredNewRel;
-// Jump to address from register.
-let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicated = 1,
- Defs = [PC], Uses = [R31] in {
- def JMPR_cPt: JRInst<(outs), (ins PredRegs:$src1),
- "if ($src1) jumpr r31",
- []>;
+let isReturn = 1, isCodeGenOnly = 1 in
+defm JMPret : JMPR_base<"JMPret">, PredNewRel;
}
-// Jump to address from register.
-let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicated = 1,
- Defs = [PC], Uses = [R31] in {
- def JMPR_cNotPt: JRInst<(outs), (ins PredRegs:$src1),
- "if (!$src1) jumpr r31",
- []>;
-}
+def : Pat<(retflag),
+ (JMPret (i32 R31))>;
+
+def : Pat <(brcond (i1 PredRegs:$src1), bb:$offset),
+ (JMP_t (i1 PredRegs:$src1), bb:$offset)>;
+
+// A return through builtin_eh_return.
+let isReturn = 1, isTerminator = 1, isBarrier = 1, neverHasSideEffects = 1,
+isCodeGenOnly = 1, Defs = [PC], Uses = [R28], isPredicable = 0 in
+def EH_RETURN_JMPR : T_JMPr;
+
+def : Pat<(eh_return),
+ (EH_RETURN_JMPR (i32 R31))>;
+
+def : Pat<(HexagonBR_JT (i32 IntRegs:$dst)),
+ (JMPR (i32 IntRegs:$dst))>;
+
+def : Pat<(brind (i32 IntRegs:$dst)),
+ (JMPR (i32 IntRegs:$dst))>;
//===----------------------------------------------------------------------===//
// JR -
@@ -871,7 +896,7 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicated = 1,
// Load -- MEMri operand
multiclass LD_MEMri_Pbase<string mnemonic, RegisterClass RC,
bit isNot, bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : LDInst2<(outs RC:$dst),
(ins PredRegs:$src1, MEMri:$addr),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -880,7 +905,7 @@ multiclass LD_MEMri_Pbase<string mnemonic, RegisterClass RC,
}
multiclass LD_MEMri_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : LD_MEMri_Pbase<mnemonic, RC, PredNot, 0>;
// Predicate new
defm _cdn#NAME : LD_MEMri_Pbase<mnemonic, RC, PredNot, 1>;
@@ -937,7 +962,7 @@ def : Pat < (i64 (load ADDRriS11_3:$addr)),
// Load - Base with Immediate offset addressing mode
multiclass LD_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp,
bit isNot, bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : LDInst2<(outs RC:$dst),
(ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -947,7 +972,7 @@ multiclass LD_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp,
multiclass LD_Idxd_Pred<string mnemonic, RegisterClass RC, Operand predImmOp,
bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : LD_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 0>;
// Predicate new
defm _cdn#NAME : LD_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 1>;
@@ -1009,20 +1034,6 @@ def : Pat < (i64 (load (add IntRegs:$src1, s11_3ExtPred:$offset))),
(LDrid_indexed IntRegs:$src1, s11_3ExtPred:$offset) >;
}
-let neverHasSideEffects = 1 in
-def LDrid_GP : LDInst2<(outs DoubleRegs:$dst),
- (ins globaladdress:$global, u16Imm:$offset),
- "$dst = memd(#$global+$offset)",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def LDd_GP : LDInst2<(outs DoubleRegs:$dst),
- (ins globaladdress:$global),
- "$dst = memd(#$global)",
- []>,
- Requires<[NoV4T]>;
-
//===----------------------------------------------------------------------===//
// Post increment load
// Make sure that in post increment load, the first operand is always the post
@@ -1031,7 +1042,7 @@ def LDd_GP : LDInst2<(outs DoubleRegs:$dst),
multiclass LD_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp,
bit isNot, bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : LDInst2PI<(outs RC:$dst, IntRegs:$dst2),
(ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -1042,7 +1053,7 @@ multiclass LD_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp,
multiclass LD_PostInc_Pred<string mnemonic, RegisterClass RC,
Operand ImmOp, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : LD_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>;
// Predicate new
let Predicates = [HasV4T], validSubTargets = HasV4SubT in
@@ -1095,27 +1106,6 @@ let AddedComplexity = 20 in
def : Pat < (i32 (extloadi8 (add IntRegs:$src1, s11_0ImmPred:$offset))),
(i32 (LDrib_indexed IntRegs:$src1, s11_0ImmPred:$offset)) >;
-let neverHasSideEffects = 1 in
-def LDrib_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global, u16Imm:$offset),
- "$dst = memb(#$global+$offset)",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def LDb_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst = memb(#$global)",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def LDub_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst = memub(#$global)",
- []>,
- Requires<[NoV4T]>;
-
def : Pat < (i32 (extloadi16 ADDRriS11_1:$addr)),
(i32 (LDrih ADDRriS11_1:$addr))>;
@@ -1123,27 +1113,6 @@ let AddedComplexity = 20 in
def : Pat < (i32 (extloadi16 (add IntRegs:$src1, s11_1ImmPred:$offset))),
(i32 (LDrih_indexed IntRegs:$src1, s11_1ImmPred:$offset)) >;
-let neverHasSideEffects = 1 in
-def LDrih_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global, u16Imm:$offset),
- "$dst = memh(#$global+$offset)",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def LDh_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst = memh(#$global)",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def LDuh_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst = memuh(#$global)",
- []>,
- Requires<[NoV4T]>;
-
let AddedComplexity = 10 in
def : Pat < (i32 (zextloadi1 ADDRriS11_0:$addr)),
(i32 (LDriub ADDRriS11_0:$addr))>;
@@ -1152,21 +1121,6 @@ let AddedComplexity = 20 in
def : Pat < (i32 (zextloadi1 (add IntRegs:$src1, s11_0ImmPred:$offset))),
(i32 (LDriub_indexed IntRegs:$src1, s11_0ImmPred:$offset))>;
-let neverHasSideEffects = 1 in
-def LDriub_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global, u16Imm:$offset),
- "$dst = memub(#$global+$offset)",
- []>,
- Requires<[NoV4T]>;
-
-// Load unsigned halfword.
-let neverHasSideEffects = 1 in
-def LDriuh_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global, u16Imm:$offset),
- "$dst = memuh(#$global+$offset)",
- []>,
- Requires<[NoV4T]>;
-
// Load predicate.
let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13,
isPseudo = 1, Defs = [R10,R11,D5], neverHasSideEffects = 1 in
@@ -1175,21 +1129,6 @@ def LDriw_pred : LDInst2<(outs PredRegs:$dst),
"Error; should not emit",
[]>;
-// Indexed load.
-let neverHasSideEffects = 1 in
-def LDriw_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global, u16Imm:$offset),
- "$dst = memw(#$global+$offset)",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def LDw_GP : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst = memw(#$global)",
- []>,
- Requires<[NoV4T]>;
-
// Deallocate stack frame.
let Defs = [R29, R30, R31], Uses = [R29], neverHasSideEffects = 1 in {
def DEALLOCFRAME : LDInst2<(outs), (ins),
@@ -1423,35 +1362,15 @@ def SUBri_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1,
// ST +
//===----------------------------------------------------------------------===//
///
-/// Assumptions::: ****** DO NOT IGNORE ********
-/// 1. Make sure that in post increment store, the zero'th operand is always the
-/// post increment operand.
-/// 2. Make sure that the store value operand(Rt/Rtt) in a store is always the
-/// last operand.
-///
// Store doubleword.
-let neverHasSideEffects = 1 in
-def STrid_GP : STInst2<(outs),
- (ins globaladdress:$global, u16Imm:$offset, DoubleRegs:$src),
- "memd(#$global+$offset) = $src",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def STd_GP : STInst2<(outs),
- (ins globaladdress:$global, DoubleRegs:$src),
- "memd(#$global) = $src",
- []>,
- Requires<[NoV4T]>;
-
//===----------------------------------------------------------------------===//
// Post increment store
//===----------------------------------------------------------------------===//
multiclass ST_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp,
bit isNot, bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : STInst2PI<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset, RC:$src3),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -1462,7 +1381,7 @@ multiclass ST_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp,
multiclass ST_PostInc_Pred<string mnemonic, RegisterClass RC,
Operand ImmOp, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME# : ST_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>;
// Predicate new
let Predicates = [HasV4T], validSubTargets = HasV4SubT in
@@ -1516,7 +1435,7 @@ def : Pat<(post_store (i64 DoubleRegs:$src1), IntRegs:$src2,
//===----------------------------------------------------------------------===//
multiclass ST_MEMri_Pbase<string mnemonic, RegisterClass RC, bit isNot,
bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : STInst2<(outs),
(ins PredRegs:$src1, MEMri:$addr, RC: $src2),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -1525,7 +1444,7 @@ multiclass ST_MEMri_Pbase<string mnemonic, RegisterClass RC, bit isNot,
}
multiclass ST_MEMri_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ST_MEMri_Pbase<mnemonic, RC, PredNot, 0>;
// Predicate new
@@ -1582,7 +1501,7 @@ def : Pat<(store (i64 DoubleRegs:$src1), ADDRriS11_3:$addr),
//===----------------------------------------------------------------------===//
multiclass ST_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp,
bit isNot, bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : STInst2<(outs),
(ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -1592,7 +1511,7 @@ multiclass ST_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp,
multiclass ST_Idxd_Pred<string mnemonic, RegisterClass RC, Operand predImmOp,
bit PredNot> {
- let PredSense = !if(PredNot, "false", "true"), isPredicated = 1 in {
+ let isPredicatedFalse = PredNot, isPredicated = 1 in {
defm _c#NAME : ST_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 0>;
// Predicate new
@@ -1655,36 +1574,6 @@ def : Pat<(store (i64 DoubleRegs:$src1), (add IntRegs:$src2,
(i64 DoubleRegs:$src1))>;
}
-// memb(gp+#u16:0)=Rt
-let neverHasSideEffects = 1 in
-def STrib_GP : STInst2<(outs),
- (ins globaladdress:$global, u16Imm:$offset, IntRegs:$src),
- "memb(#$global+$offset) = $src",
- []>,
- Requires<[NoV4T]>;
-
-// memb(#global)=Rt
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def STb_GP : STInst2<(outs),
- (ins globaladdress:$global, IntRegs:$src),
- "memb(#$global) = $src",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1 in
-def STrih_GP : STInst2<(outs),
- (ins globaladdress:$global, u16Imm:$offset, IntRegs:$src),
- "memh(#$global+$offset) = $src",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def STh_GP : STInst2<(outs),
- (ins globaladdress:$global, IntRegs:$src),
- "memh(#$global) = $src",
- []>,
- Requires<[NoV4T]>;
-
// memh(Rx++#s4:1)=Rt.H
// Store word.
@@ -1695,20 +1584,6 @@ def STriw_pred : STInst2<(outs),
"Error; should not emit",
[]>;
-let neverHasSideEffects = 1 in
-def STriw_GP : STInst2<(outs),
- (ins globaladdress:$global, u16Imm:$offset, IntRegs:$src),
- "memw(#$global+$offset) = $src",
- []>,
- Requires<[NoV4T]>;
-
-let neverHasSideEffects = 1, validSubTargets = NoV4SubT in
-def STw_GP : STInst2<(outs),
- (ins globaladdress:$global, IntRegs:$src),
- "memw(#$global) = $src",
- []>,
- Requires<[NoV4T]>;
-
// Allocate stack frame.
let Defs = [R29, R30], Uses = [R31, R30], neverHasSideEffects = 1 in {
def ALLOCFRAME : STInst2<(outs),
@@ -2152,20 +2027,18 @@ let isCall = 1, neverHasSideEffects = 1,
[]>;
}
-// Tail Calls.
-let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1 in {
- def TCRETURNtg : JInst<(outs), (ins calltarget:$dst),
- "jump $dst // TAILCALL", []>;
-}
-let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1 in {
- def TCRETURNtext : JInst<(outs), (ins calltarget:$dst),
- "jump $dst // TAILCALL", []>;
-}
-let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1 in {
- def TCRETURNR : JInst<(outs), (ins IntRegs:$dst),
- "jumpr $dst // TAILCALL", []>;
+// Indirect tail-call.
+let isCodeGenOnly = 1, isCall = 1, isReturn = 1 in
+def TCRETURNR : T_JMPr;
+
+// Direct tail-calls.
+let isCall = 1, isReturn = 1, isBarrier = 1, isPredicable = 0,
+isTerminator = 1, isCodeGenOnly = 1 in {
+ def TCRETURNtg : T_JMP<(ins calltarget:$dst)>;
+ def TCRETURNtext : T_JMP<(ins calltarget:$dst)>;
}
+
// Map call instruction.
def : Pat<(call (i32 IntRegs:$dst)),
(CALLR (i32 IntRegs:$dst))>, Requires<[HasV2TOnly]>;
@@ -2183,68 +2056,26 @@ def : Pat<(HexagonTCRet (i32 IntRegs:$dst)),
// Atomic load and store support
// 8 bit atomic load
-def : Pat<(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)),
- (i32 (LDub_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-def : Pat<(atomic_load_8 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset)),
- (i32 (LDriub_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
def : Pat<(atomic_load_8 ADDRriS11_0:$src1),
(i32 (LDriub ADDRriS11_0:$src1))>;
def : Pat<(atomic_load_8 (add (i32 IntRegs:$src1), s11_0ImmPred:$offset)),
(i32 (LDriub_indexed (i32 IntRegs:$src1), s11_0ImmPred:$offset))>;
-
-
// 16 bit atomic load
-def : Pat<(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)),
- (i32 (LDuh_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-def : Pat<(atomic_load_16 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset)),
- (i32 (LDriuh_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
def : Pat<(atomic_load_16 ADDRriS11_1:$src1),
(i32 (LDriuh ADDRriS11_1:$src1))>;
def : Pat<(atomic_load_16 (add (i32 IntRegs:$src1), s11_1ImmPred:$offset)),
(i32 (LDriuh_indexed (i32 IntRegs:$src1), s11_1ImmPred:$offset))>;
-
-
-// 32 bit atomic load
-def : Pat<(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)),
- (i32 (LDw_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-def : Pat<(atomic_load_32 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset)),
- (i32 (LDriw_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
def : Pat<(atomic_load_32 ADDRriS11_2:$src1),
(i32 (LDriw ADDRriS11_2:$src1))>;
def : Pat<(atomic_load_32 (add (i32 IntRegs:$src1), s11_2ImmPred:$offset)),
(i32 (LDriw_indexed (i32 IntRegs:$src1), s11_2ImmPred:$offset))>;
-
// 64 bit atomic load
-def : Pat<(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)),
- (i64 (LDd_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-def : Pat<(atomic_load_64 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset)),
- (i64 (LDrid_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
def : Pat<(atomic_load_64 ADDRriS11_3:$src1),
(i64 (LDrid ADDRriS11_3:$src1))>;
@@ -2252,30 +2083,6 @@ def : Pat<(atomic_load_64 (add (i32 IntRegs:$src1), s11_3ImmPred:$offset)),
(i64 (LDrid_indexed (i32 IntRegs:$src1), s11_3ImmPred:$offset))>;
-// 64 bit atomic store
-def : Pat<(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global),
- (i64 DoubleRegs:$src1)),
- (STd_GP tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
- Requires<[NoV4T]>;
-
-def : Pat<(atomic_store_64 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset),
- (i64 DoubleRegs:$src1)),
- (STrid_GP tglobaladdr:$global, u16ImmPred:$offset,
- (i64 DoubleRegs:$src1))>, Requires<[NoV4T]>;
-
-// 8 bit atomic store
-def : Pat<(atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global),
- (i32 IntRegs:$src1)),
- (STb_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
-def : Pat<(atomic_store_8 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset),
- (i32 IntRegs:$src1)),
- (STrib_GP tglobaladdr:$global, u16ImmPred:$offset,
- (i32 IntRegs:$src1))>, Requires<[NoV4T]>;
-
def : Pat<(atomic_store_8 ADDRriS11_0:$src2, (i32 IntRegs:$src1)),
(STrib ADDRriS11_0:$src2, (i32 IntRegs:$src1))>;
@@ -2285,18 +2092,6 @@ def : Pat<(atomic_store_8 (add (i32 IntRegs:$src2), s11_0ImmPred:$offset),
(i32 IntRegs:$src1))>;
-// 16 bit atomic store
-def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
- (i32 IntRegs:$src1)),
- (STh_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
-def : Pat<(atomic_store_16 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset),
- (i32 IntRegs:$src1)),
- (STrih_GP tglobaladdr:$global, u16ImmPred:$offset,
- (i32 IntRegs:$src1))>, Requires<[NoV4T]>;
-
def : Pat<(atomic_store_16 ADDRriS11_1:$src2, (i32 IntRegs:$src1)),
(STrih ADDRriS11_1:$src2, (i32 IntRegs:$src1))>;
@@ -2305,20 +2100,6 @@ def : Pat<(atomic_store_16 (i32 IntRegs:$src1),
(STrih_indexed (i32 IntRegs:$src2), s11_1ImmPred:$offset,
(i32 IntRegs:$src1))>;
-
-// 32 bit atomic store
-def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global),
- (i32 IntRegs:$src1)),
- (STw_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
-def : Pat<(atomic_store_32 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset),
- (i32 IntRegs:$src1)),
- (STriw_GP tglobaladdr:$global, u16ImmPred:$offset,
- (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
def : Pat<(atomic_store_32 ADDRriS11_2:$src2, (i32 IntRegs:$src1)),
(STriw ADDRriS11_2:$src2, (i32 IntRegs:$src1))>;
@@ -2354,10 +2135,11 @@ def : Pat <(add (i1 PredRegs:$src1), -1),
// Map from p0 = setlt(r0, r1) r2 = mux(p0, r3, r4) =>
// p0 = cmp.lt(r0, r1), r0 = mux(p0, r2, r1).
+// cmp.lt(r0, r1) -> cmp.gt(r1, r0)
def : Pat <(select (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
(i32 IntRegs:$src3),
(i32 IntRegs:$src4)),
- (i32 (TFR_condset_rr (CMPLTrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
+ (i32 (TFR_condset_rr (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)),
(i32 IntRegs:$src4), (i32 IntRegs:$src3)))>,
Requires<[HasV2TOnly]>;
@@ -2375,210 +2157,27 @@ def : Pat <(select (not (i1 PredRegs:$src1)), s12ImmPred:$src2,
// Map from p0 = pnot(p0); r0 = mux(p0, r1, #i)
// => r0 = TFR_condset_ir(p0, #i, r1)
-def : Pat <(select (not PredRegs:$src1), IntRegs:$src2, s12ImmPred:$src3),
+def : Pat <(select (not (i1 PredRegs:$src1)), IntRegs:$src2, s12ImmPred:$src3),
(i32 (TFR_condset_ir (i1 PredRegs:$src1), s12ImmPred:$src3,
(i32 IntRegs:$src2)))>;
// Map from p0 = pnot(p0); if (p0) jump => if (!p0) jump.
-def : Pat <(brcond (not PredRegs:$src1), bb:$offset),
- (JMP_cNot (i1 PredRegs:$src1), bb:$offset)>;
+def : Pat <(brcond (not (i1 PredRegs:$src1)), bb:$offset),
+ (JMP_f (i1 PredRegs:$src1), bb:$offset)>;
// Map from p2 = pnot(p2); p1 = and(p0, p2) => p1 = and(p0, !p2).
-def : Pat <(and PredRegs:$src1, (not PredRegs:$src2)),
+def : Pat <(and (i1 PredRegs:$src1), (not (i1 PredRegs:$src2))),
(i1 (AND_pnotp (i1 PredRegs:$src1), (i1 PredRegs:$src2)))>;
-// Map from store(globaladdress + x) -> memd(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(store (i64 DoubleRegs:$src1),
- (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset)),
- (STrid_GP tglobaladdr:$global, u16ImmPred:$offset,
- (i64 DoubleRegs:$src1))>, Requires<[NoV4T]>;
-
-// Map from store(globaladdress) -> memd(#foo).
-let AddedComplexity = 100 in
-def : Pat <(store (i64 DoubleRegs:$src1),
- (HexagonCONST32_GP tglobaladdr:$global)),
- (STd_GP tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
- Requires<[NoV4T]>;
-
-// Map from store(globaladdress + x) -> memw(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(store (i32 IntRegs:$src1),
- (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset)),
- (STriw_GP tglobaladdr:$global, u16ImmPred:$offset, (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
-// Map from store(globaladdress) -> memw(#foo + 0).
-let AddedComplexity = 100 in
-def : Pat <(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
- (STriw_GP tglobaladdr:$global, 0, (i32 IntRegs:$src1))>;
-
-// Map from store(globaladdress) -> memw(#foo).
-let AddedComplexity = 100 in
-def : Pat <(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
- (STriw_GP tglobaladdr:$global, 0, (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
-// Map from store(globaladdress + x) -> memh(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(truncstorei16 (i32 IntRegs:$src1),
- (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset)),
- (STrih_GP tglobaladdr:$global, u16ImmPred:$offset, (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
-// Map from store(globaladdress) -> memh(#foo).
-let AddedComplexity = 100 in
-def : Pat <(truncstorei16 (i32 IntRegs:$src1),
- (HexagonCONST32_GP tglobaladdr:$global)),
- (STh_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
-// Map from store(globaladdress + x) -> memb(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(truncstorei8 (i32 IntRegs:$src1),
- (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset)),
- (STrib_GP tglobaladdr:$global, u16ImmPred:$offset, (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
-// Map from store(globaladdress) -> memb(#foo).
-let AddedComplexity = 100 in
-def : Pat <(truncstorei8 (i32 IntRegs:$src1),
- (HexagonCONST32_GP tglobaladdr:$global)),
- (STb_GP tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress + x) -> memw(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(i32 (load (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset))),
- (i32 (LDriw_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress) -> memw(#foo).
-let AddedComplexity = 100 in
-def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDw_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress + x) -> memd(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(i64 (load (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset))),
- (i64 (LDrid_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress) -> memw(#foo + 0).
-let AddedComplexity = 100 in
-def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))),
- (i64 (LDd_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-// Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd.
-let AddedComplexity = 100 in
-def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))),
- (i1 (TFR_PdRs (i32 (LDb_GP tglobaladdr:$global))))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress + x) -> memh(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(i32 (extloadi16 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset))),
- (i32 (LDrih_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress + x) -> memh(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDrih_GP tglobaladdr:$global, 0))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress + x) -> memuh(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(i32 (zextloadi16 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset))),
- (i32 (LDriuh_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress) -> memuh(#foo).
-let AddedComplexity = 100 in
-def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDriuh_GP tglobaladdr:$global, 0))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress) -> memh(#foo).
-let AddedComplexity = 100 in
-def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDh_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress) -> memuh(#foo).
-let AddedComplexity = 100 in
-def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDuh_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress + x) -> memb(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(i32 (extloadi8 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset))),
- (i32 (LDrib_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress + x) -> memb(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(i32 (sextloadi8 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset))),
- (i32 (LDrib_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress + x) -> memub(#foo + x).
-let AddedComplexity = 100 in
-def : Pat <(i32 (zextloadi8 (add (HexagonCONST32_GP tglobaladdr:$global),
- u16ImmPred:$offset))),
- (i32 (LDriub_GP tglobaladdr:$global, u16ImmPred:$offset))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress) -> memb(#foo).
-let AddedComplexity = 100 in
-def : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-// Map from load(globaladdress) -> memb(#foo).
-let AddedComplexity = 100 in
-def : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-// Map from load(globaladdress) -> memub(#foo).
let AddedComplexity = 100 in
-def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDub_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-// When the Interprocedural Global Variable optimizer realizes that a
-// certain global variable takes only two constant values, it shrinks the
-// global to a boolean. Catch those loads here in the following 3 patterns.
-let AddedComplexity = 100 in
-def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-let AddedComplexity = 100 in
-def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP tglobaladdr:$global))>,
- Requires<[NoV4T]>;
-
-let AddedComplexity = 100 in
-def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDub_GP tglobaladdr:$global))>,
+def : Pat <(i64 (zextloadi1 (HexagonCONST32 tglobaladdr:$global))),
+ (i64 (COMBINE_rr (TFRI 0),
+ (LDriub_indexed (CONST32_set tglobaladdr:$global), 0)))>,
Requires<[NoV4T]>;
// Map from i1 loads to 32 bits. This assumes that the i1* is byte aligned.
+let AddedComplexity = 10 in
def : Pat <(i32 (zextloadi1 ADDRriS11_0:$addr)),
(i32 (AND_rr (i32 (LDrib ADDRriS11_0:$addr)), (TFRI 0x1)))>;
@@ -2597,43 +2196,46 @@ def : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i8)),
subreg_loreg))))))>;
// We want to prevent emitting pnot's as much as possible.
-// Map brcond with an unsupported setcc to a JMP_cNot.
+// Map brcond with an unsupported setcc to a JMP_f.
def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
bb:$offset),
- (JMP_cNot (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
+ (JMP_f (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
bb:$offset)>;
def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), s10ImmPred:$src2)),
bb:$offset),
- (JMP_cNot (CMPEQri (i32 IntRegs:$src1), s10ImmPred:$src2), bb:$offset)>;
+ (JMP_f (CMPEQri (i32 IntRegs:$src1), s10ImmPred:$src2), bb:$offset)>;
def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 -1))), bb:$offset),
- (JMP_cNot (i1 PredRegs:$src1), bb:$offset)>;
+ (JMP_f (i1 PredRegs:$src1), bb:$offset)>;
def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 0))), bb:$offset),
- (JMP_c (i1 PredRegs:$src1), bb:$offset)>;
+ (JMP_t (i1 PredRegs:$src1), bb:$offset)>;
+// cmp.lt(Rs, Imm) -> !cmp.ge(Rs, Imm) -> !cmp.gt(Rs, Imm-1)
def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), s8ImmPred:$src2)),
bb:$offset),
- (JMP_cNot (CMPGEri (i32 IntRegs:$src1), s8ImmPred:$src2), bb:$offset)>;
+ (JMP_f (CMPGTri (i32 IntRegs:$src1),
+ (DEC_CONST_SIGNED s8ImmPred:$src2)), bb:$offset)>;
+// cmp.lt(r0, r1) -> cmp.gt(r1, r0)
def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
bb:$offset),
- (JMP_c (CMPLTrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)), bb:$offset)>;
+ (JMP_t (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)), bb:$offset)>;
def : Pat <(brcond (i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
bb:$offset),
- (JMP_cNot (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)),
+ (JMP_f (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)),
bb:$offset)>;
def : Pat <(brcond (i1 (setule (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
bb:$offset),
- (JMP_cNot (CMPGTUrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
+ (JMP_f (CMPGTUrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
bb:$offset)>;
def : Pat <(brcond (i1 (setule (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
bb:$offset),
- (JMP_cNot (CMPGTU64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
+ (JMP_f (CMPGTU64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
bb:$offset)>;
// Map from a 64-bit select to an emulated 64-bit mux.
@@ -2694,12 +2296,6 @@ def : Pat<(truncstorei32 (i64 DoubleRegs:$src), ADDRriS11_0:$addr),
def : Pat<(store (i1 -1), ADDRriS11_2:$addr),
(STrib ADDRriS11_2:$addr, (TFRI 1))>;
-let AddedComplexity = 100 in
-// Map from i1 = constant<-1>; memw(CONST32(#foo)) = i1 -> r0 = 1;
-// memw(#foo) = r0
-def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
- (STb_GP tglobaladdr:$global, (TFRI 1))>,
- Requires<[NoV4T]>;
// Map from i1 = constant<-1>; store i1 -> r0 = 1; store r0.
def : Pat<(store (i1 -1), ADDRriS11_2:$addr),
@@ -2717,8 +2313,8 @@ def : Pat<(i64 (anyext (i32 IntRegs:$src1))),
// Map cmple -> cmpgt.
// rs <= rt -> !(rs > rt).
-def : Pat<(i1 (setle (i32 IntRegs:$src1), s10ImmPred:$src2)),
- (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), s10ImmPred:$src2)))>;
+def : Pat<(i1 (setle (i32 IntRegs:$src1), s10ExtPred:$src2)),
+ (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), s10ExtPred:$src2)))>;
// rs <= rt -> !(rs > rt).
def : Pat<(i1 (setle (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
@@ -2731,8 +2327,8 @@ def : Pat<(i1 (setle (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
// Map cmpne -> cmpeq.
// Hexagon_TODO: We should improve on this.
// rs != rt -> !(rs == rt).
-def : Pat <(i1 (setne (i32 IntRegs:$src1), s10ImmPred:$src2)),
- (i1 (NOT_p(i1 (CMPEQri (i32 IntRegs:$src1), s10ImmPred:$src2))))>;
+def : Pat <(i1 (setne (i32 IntRegs:$src1), s10ExtPred:$src2)),
+ (i1 (NOT_p(i1 (CMPEQri (i32 IntRegs:$src1), s10ExtPred:$src2))))>;
// Map cmpne(Rs) -> !cmpeqe(Rs).
// rs != rt -> !(rs == rt).
@@ -2754,8 +2350,9 @@ def : Pat <(i1 (setne (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
def : Pat <(i1 (setge (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
(i1 (NOT_p (i1 (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))))>;
-def : Pat <(i1 (setge (i32 IntRegs:$src1), s8ImmPred:$src2)),
- (i1 (CMPGEri (i32 IntRegs:$src1), s8ImmPred:$src2))>;
+// cmpge(Rs, Imm) -> cmpgt(Rs, Imm-1)
+def : Pat <(i1 (setge (i32 IntRegs:$src1), s8ExtPred:$src2)),
+ (i1 (CMPGTri (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2)))>;
// Map cmpge(Rss, Rtt) -> !cmpgt(Rtt, Rss).
// rss >= rtt -> !(rtt > rss).
@@ -2764,9 +2361,10 @@ def : Pat <(i1 (setge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
(i64 DoubleRegs:$src1)))))>;
// Map cmplt(Rs, Imm) -> !cmpge(Rs, Imm).
+// !cmpge(Rs, Imm) -> !cmpgt(Rs, Imm-1).
// rs < rt -> !(rs >= rt).
-def : Pat <(i1 (setlt (i32 IntRegs:$src1), s8ImmPred:$src2)),
- (i1 (NOT_p (CMPGEri (i32 IntRegs:$src1), s8ImmPred:$src2)))>;
+def : Pat <(i1 (setlt (i32 IntRegs:$src1), s8ExtPred:$src2)),
+ (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2))))>;
// Map cmplt(Rs, Rt) -> cmpgt(Rt, Rs).
// rs < rt -> rt > rs.
@@ -2790,13 +2388,17 @@ def : Pat <(i1 (setult (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
def : Pat <(i1 (setult (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
(i1 (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)))>;
-// Generate cmpgeu(Rs, #u8)
-def : Pat <(i1 (setuge (i32 IntRegs:$src1), u8ImmPred:$src2)),
- (i1 (CMPGEUri (i32 IntRegs:$src1), u8ImmPred:$src2))>;
+// Generate cmpgeu(Rs, #0) -> cmpeq(Rs, Rs)
+def : Pat <(i1 (setuge (i32 IntRegs:$src1), 0)),
+ (i1 (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src1)))>;
+
+// Generate cmpgeu(Rs, #u8) -> cmpgtu(Rs, #u8 -1)
+def : Pat <(i1 (setuge (i32 IntRegs:$src1), u8ExtPred:$src2)),
+ (i1 (CMPGTUri (i32 IntRegs:$src1), (DEC_CONST_UNSIGNED u8ExtPred:$src2)))>;
// Generate cmpgtu(Rs, #u9)
-def : Pat <(i1 (setugt (i32 IntRegs:$src1), u9ImmPred:$src2)),
- (i1 (CMPGTUri (i32 IntRegs:$src1), u9ImmPred:$src2))>;
+def : Pat <(i1 (setugt (i32 IntRegs:$src1), u9ExtPred:$src2)),
+ (i1 (CMPGTUri (i32 IntRegs:$src1), u9ExtPred:$src2))>;
// Map from Rs >= Rt -> !(Rt > Rs).
// rs >= rt -> !(rt > rs).
@@ -2808,7 +2410,7 @@ def : Pat <(i1 (setuge (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
def : Pat <(i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
(i1 (NOT_p (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1))))>;
-// Map from cmpleu(Rs, Rs) -> !cmpgtu(Rs, Rs).
+// Map from cmpleu(Rs, Rt) -> !cmpgtu(Rs, Rt).
// Map from (Rs <= Rt) -> !(Rs > Rt).
def : Pat <(i1 (setule (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
(i1 (NOT_p (CMPGTUrr (i32 IntRegs:$src1), (i32 IntRegs:$src2))))>;
@@ -2904,6 +2506,13 @@ def: Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)),
(i64 (COMBINE_rr (TFRI 0), (LDriw ADDRriS11_2:$src1)))>,
Requires<[NoV4T]>;
+let AddedComplexity = 100 in
+def: Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
+ (i64 (COMBINE_rr (TFRI 0), (LDriw_indexed IntRegs:$src1,
+ s11_2ExtPred:$offset)))>,
+ Requires<[NoV4T]>;
+
+let AddedComplexity = 10 in
def: Pat <(i32 (zextloadi1 ADDRriS11_0:$src1)),
(i32 (LDriw ADDRriS11_0:$src1))>;
@@ -2920,6 +2529,48 @@ def : Pat <(i64 (anyext (i1 PredRegs:$src1))),
(i64 (SXTW (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))))>;
+let AddedComplexity = 100 in
+def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
+ (i32 32))),
+ (i64 (zextloadi32 (i32 (add IntRegs:$src2,
+ s11_2ExtPred:$offset2)))))),
+ (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
+ (LDriw_indexed IntRegs:$src2,
+ s11_2ExtPred:$offset2)))>;
+
+def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
+ (i32 32))),
+ (i64 (zextloadi32 ADDRriS11_2:$srcLow)))),
+ (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
+ (LDriw ADDRriS11_2:$srcLow)))>;
+
+def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
+ (i32 32))),
+ (i64 (zext (i32 IntRegs:$srcLow))))),
+ (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
+ IntRegs:$srcLow))>;
+
+let AddedComplexity = 100 in
+def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
+ (i32 32))),
+ (i64 (zextloadi32 (i32 (add IntRegs:$src2,
+ s11_2ExtPred:$offset2)))))),
+ (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
+ (LDriw_indexed IntRegs:$src2,
+ s11_2ExtPred:$offset2)))>;
+
+def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
+ (i32 32))),
+ (i64 (zextloadi32 ADDRriS11_2:$srcLow)))),
+ (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
+ (LDriw ADDRriS11_2:$srcLow)))>;
+
+def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
+ (i32 32))),
+ (i64 (zext (i32 IntRegs:$srcLow))))),
+ (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
+ IntRegs:$srcLow))>;
+
// Any extended 64-bit load.
// anyext i32 -> i64
def: Pat <(i64 (extloadi32 ADDRriS11_2:$src1)),
@@ -3054,19 +2705,6 @@ let AddedComplexity = 100 in
def : Pat<(i32 (sext_inreg (Hexagon_ARGEXTEND (i32 IntRegs:$src1)), i16)),
(COPY (i32 IntRegs:$src1))>;
-def SDHexagonBR_JT: SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
-def HexagonBR_JT: SDNode<"HexagonISD::BR_JT", SDHexagonBR_JT, [SDNPHasChain]>;
-
-let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in
-def BR_JT : JRInst<(outs), (ins IntRegs:$src),
- "jumpr $src",
- [(HexagonBR_JT (i32 IntRegs:$src))]>;
-
-let isBranch=1, isIndirectBranch=1, isTerminator=1 in
-def BRIND : JRInst<(outs), (ins IntRegs:$src),
- "jumpr $src",
- [(brind (i32 IntRegs:$src))]>;
-
def HexagonWrapperJT: SDNode<"HexagonISD::WrapperJT", SDTIntUnaryOp>;
def : Pat<(HexagonWrapperJT tjumptable:$dst),
diff --git a/lib/Target/Hexagon/HexagonInstrInfoV3.td b/lib/Target/Hexagon/HexagonInstrInfoV3.td
index 157ab3d..7e75554 100644
--- a/lib/Target/Hexagon/HexagonInstrInfoV3.td
+++ b/lib/Target/Hexagon/HexagonInstrInfoV3.td
@@ -11,6 +11,11 @@
//
//===----------------------------------------------------------------------===//
+def callv3 : SDNode<"HexagonISD::CALLv3", SDT_SPCall,
+ [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;
+
+def callv3nr : SDNode<"HexagonISD::CALLv3nr", SDT_SPCall,
+ [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;
//===----------------------------------------------------------------------===//
// J +
@@ -40,41 +45,6 @@ let isCall = 1, neverHasSideEffects = 1,
[]>, Requires<[HasV3TOnly]>;
}
-
-// Jump to address from register
-// if(p?.new) jumpr:t r?
-let isReturn = 1, isTerminator = 1, isBarrier = 1,
- Defs = [PC], Uses = [R31] in {
- def JMPR_cdnPt_V3: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1.new) jumpr:t $src2",
- []>, Requires<[HasV3T]>;
-}
-
-// if (!p?.new) jumpr:t r?
-let isReturn = 1, isTerminator = 1, isBarrier = 1,
- Defs = [PC], Uses = [R31] in {
- def JMPR_cdnNotPt_V3: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1.new) jumpr:t $src2",
- []>, Requires<[HasV3T]>;
-}
-
-// Not taken.
-// if(p?.new) jumpr:nt r?
-let isReturn = 1, isTerminator = 1, isBarrier = 1,
- Defs = [PC], Uses = [R31] in {
- def JMPR_cdnPnt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1.new) jumpr:nt $src2",
- []>, Requires<[HasV3T]>;
-}
-
-// if (!p?.new) jumpr:nt r?
-let isReturn = 1, isTerminator = 1, isBarrier = 1,
- Defs = [PC], Uses = [R31] in {
- def JMPR_cdnNotPnt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1.new) jumpr:nt $src2",
- []>, Requires<[HasV3T]>;
-}
-
//===----------------------------------------------------------------------===//
// JR -
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/Hexagon/HexagonInstrInfoV4.td b/lib/Target/Hexagon/HexagonInstrInfoV4.td
index 1d0643d..744efe8 100644
--- a/lib/Target/Hexagon/HexagonInstrInfoV4.td
+++ b/lib/Target/Hexagon/HexagonInstrInfoV4.td
@@ -95,164 +95,6 @@ def NumUsesBelowThresCONST32 : PatFrag<(ops node:$addr),
//===----------------------------------------------------------------------===//
// ALU32 +
//===----------------------------------------------------------------------===//
-
-// Shift halfword.
-
-let isPredicated = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in {
-def ASLH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1) $dst = aslh($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ASLH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1) $dst = aslh($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ASLH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1.new) $dst = aslh($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ASLH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1.new) $dst = aslh($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ASRH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1) $dst = asrh($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ASRH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1) $dst = asrh($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ASRH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1.new) $dst = asrh($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ASRH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1.new) $dst = asrh($src2)",
- []>,
- Requires<[HasV4T]>;
-}
-
-// Sign extend.
-
-let isPredicated = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in {
-def SXTB_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1) $dst = sxtb($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def SXTB_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1) $dst = sxtb($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def SXTB_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1.new) $dst = sxtb($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def SXTB_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1.new) $dst = sxtb($src2)",
- []>,
- Requires<[HasV4T]>;
-
-
-def SXTH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1) $dst = sxth($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def SXTH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1) $dst = sxth($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def SXTH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1.new) $dst = sxth($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def SXTH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1.new) $dst = sxth($src2)",
- []>,
- Requires<[HasV4T]>;
-}
-
-// Zero exten.
-
-let neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in {
-def ZXTB_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1) $dst = zxtb($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ZXTB_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1) $dst = zxtb($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ZXTB_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1.new) $dst = zxtb($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ZXTB_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1.new) $dst = zxtb($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ZXTH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1) $dst = zxth($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ZXTH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1) $dst = zxth($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ZXTH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if ($src1.new) $dst = zxth($src2)",
- []>,
- Requires<[HasV4T]>;
-
-def ZXTH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- "if (!$src1.new) $dst = zxth($src2)",
- []>,
- Requires<[HasV4T]>;
-}
-
// Generate frame index addresses.
let neverHasSideEffects = 1, isReMaterializable = 1,
isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in
@@ -367,105 +209,31 @@ def COMBINE_iI_V4 : ALU32_ii<(outs DoubleRegs:$dst),
//===----------------------------------------------------------------------===//
// LD +
//===----------------------------------------------------------------------===//
-//
-// These absolute set addressing mode instructions accept immediate as
-// an operand. We have duplicated these patterns to take global address.
-
+//===----------------------------------------------------------------------===//
+// Template class for load instructions with Absolute set addressing mode.
+//===----------------------------------------------------------------------===//
let isExtended = 1, opExtendable = 2, neverHasSideEffects = 1,
-validSubTargets = HasV4SubT in {
-def LDrid_abs_setimm_V4 : LDInst2<(outs DoubleRegs:$dst1, IntRegs:$dst2),
- (ins u0AlwaysExt:$addr),
- "$dst1 = memd($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-
-// Rd=memb(Re=#U6)
-def LDrib_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins u0AlwaysExt:$addr),
- "$dst1 = memb($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-
-// Rd=memh(Re=#U6)
-def LDrih_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins u0AlwaysExt:$addr),
- "$dst1 = memh($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-
-// Rd=memub(Re=#U6)
-def LDriub_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins u0AlwaysExt:$addr),
- "$dst1 = memub($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-
-// Rd=memuh(Re=#U6)
-def LDriuh_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
+validSubTargets = HasV4SubT in
+class T_LD_abs_set<string mnemonic, RegisterClass RC>:
+ LDInst2<(outs RC:$dst1, IntRegs:$dst2),
(ins u0AlwaysExt:$addr),
- "$dst1 = memuh($dst2=##$addr)",
+ "$dst1 = "#mnemonic#"($dst2=##$addr)",
[]>,
Requires<[HasV4T]>;
-// Rd=memw(Re=#U6)
-def LDriw_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins u0AlwaysExt:$addr),
- "$dst1 = memw($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-}
+def LDrid_abs_set_V4 : T_LD_abs_set <"memd", DoubleRegs>;
+def LDrib_abs_set_V4 : T_LD_abs_set <"memb", IntRegs>;
+def LDriub_abs_set_V4 : T_LD_abs_set <"memub", IntRegs>;
+def LDrih_abs_set_V4 : T_LD_abs_set <"memh", IntRegs>;
+def LDriw_abs_set_V4 : T_LD_abs_set <"memw", IntRegs>;
+def LDriuh_abs_set_V4 : T_LD_abs_set <"memuh", IntRegs>;
-// Following patterns are defined for absolute set addressing mode
-// instruction which take global address as operand.
-let isExtended = 1, opExtendable = 2, neverHasSideEffects = 1,
-validSubTargets = HasV4SubT in {
-def LDrid_abs_set_V4 : LDInst2<(outs DoubleRegs:$dst1, IntRegs:$dst2),
- (ins globaladdressExt:$addr),
- "$dst1 = memd($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-
-// Rd=memb(Re=#U6)
-def LDrib_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins globaladdressExt:$addr),
- "$dst1 = memb($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-
-// Rd=memh(Re=#U6)
-def LDrih_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins globaladdressExt:$addr),
- "$dst1 = memh($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-
-// Rd=memub(Re=#U6)
-def LDriub_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins globaladdressExt:$addr),
- "$dst1 = memub($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-
-// Rd=memuh(Re=#U6)
-def LDriuh_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins globaladdressExt:$addr),
- "$dst1 = memuh($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-
-// Rd=memw(Re=#U6)
-def LDriw_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
- (ins globaladdressExt:$addr),
- "$dst1 = memw($dst2=##$addr)",
- []>,
- Requires<[HasV4T]>;
-}
// multiclass for load instructions with base + register offset
// addressing mode
multiclass ld_idxd_shl_pbase<string mnemonic, RegisterClass RC, bit isNot,
bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : LDInst2<(outs RC:$dst),
(ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -474,7 +242,7 @@ multiclass ld_idxd_shl_pbase<string mnemonic, RegisterClass RC, bit isNot,
}
multiclass ld_idxd_shl_pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ld_idxd_shl_pbase<mnemonic, RC, PredNot, 0>;
// Predicate new
defm _cdn#NAME : ld_idxd_shl_pbase<mnemonic, RC, PredNot, 1>;
@@ -596,329 +364,6 @@ def : Pat <(i32 (load (add IntRegs:$src1, IntRegs:$src2))),
Requires<[HasV4T]>;
}
-let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
-def LDd_GP_V4 : LDInst2<(outs DoubleRegs:$dst),
- (ins globaladdress:$global),
- "$dst=memd(#$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rtt=memd(##global)
-let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
-validSubTargets = HasV4SubT in {
-def LDd_GP_cPt_V4 : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1) $dst=memd(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-
-// if (!Pv) Rtt=memd(##global)
-def LDd_GP_cNotPt_V4 : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1) $dst=memd(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rtt=memd(##global)
-def LDd_GP_cdnPt_V4 : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1.new) $dst=memd(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-
-// if (!Pv) Rtt=memd(##global)
-def LDd_GP_cdnNotPt_V4 : LDInst2<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1.new) $dst=memd(##$global)",
- []>,
- Requires<[HasV4T]>;
-}
-
-let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
-def LDb_GP_V4 : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst=memb(#$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memb(##global)
-let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
-validSubTargets = HasV4SubT in {
-def LDb_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1) $dst=memb(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) Rt=memb(##global)
-def LDb_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1) $dst=memb(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memb(##global)
-def LDb_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1.new) $dst=memb(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) Rt=memb(##global)
-def LDb_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1.new) $dst=memb(##$global)",
- []>,
- Requires<[HasV4T]>;
-}
-
-let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
-def LDub_GP_V4 : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst=memub(#$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memub(##global)
-let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
-validSubTargets = HasV4SubT in {
-def LDub_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1) $dst=memub(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-
-// if (!Pv) Rt=memub(##global)
-def LDub_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1) $dst=memub(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memub(##global)
-def LDub_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1.new) $dst=memub(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-
-// if (!Pv) Rt=memub(##global)
-def LDub_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1.new) $dst=memub(##$global)",
- []>,
- Requires<[HasV4T]>;
-}
-
-let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
-def LDh_GP_V4 : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst=memh(#$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memh(##global)
-let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
-validSubTargets = HasV4SubT in {
-def LDh_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1) $dst=memh(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) Rt=memh(##global)
-def LDh_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1) $dst=memh(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memh(##global)
-def LDh_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1.new) $dst=memh(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) Rt=memh(##global)
-def LDh_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1.new) $dst=memh(##$global)",
- []>,
- Requires<[HasV4T]>;
-}
-
-let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
-def LDuh_GP_V4 : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst=memuh(#$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memuh(##global)
-let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
-validSubTargets = HasV4SubT in {
-def LDuh_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1) $dst=memuh(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) Rt=memuh(##global)
-def LDuh_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1) $dst=memuh(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memuh(##global)
-def LDuh_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1.new) $dst=memuh(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) Rt=memuh(##global)
-def LDuh_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1.new) $dst=memuh(##$global)",
- []>,
- Requires<[HasV4T]>;
-}
-
-let isPredicable = 1, neverHasSideEffects = 1, validSubTargets = HasV4SubT in
-def LDw_GP_V4 : LDInst2<(outs IntRegs:$dst),
- (ins globaladdress:$global),
- "$dst=memw(#$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memw(##global)
-let neverHasSideEffects = 1, isPredicated = 1, isExtended = 1, opExtendable = 2,
-validSubTargets = HasV4SubT in {
-def LDw_GP_cPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1) $dst=memw(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-
-// if (!Pv) Rt=memw(##global)
-def LDw_GP_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1) $dst=memw(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) Rt=memw(##global)
-def LDw_GP_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if ($src1.new) $dst=memw(##$global)",
- []>,
- Requires<[HasV4T]>;
-
-
-// if (!Pv) Rt=memw(##global)
-def LDw_GP_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, globaladdress:$global),
- "if (!$src1.new) $dst=memw(##$global)",
- []>,
- Requires<[HasV4T]>;
-}
-
-
-def : Pat <(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)),
- (i64 (LDd_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-def : Pat <(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)),
- (i32 (LDw_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-def : Pat <(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)),
- (i32 (LDuh_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-def : Pat <(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)),
- (i32 (LDub_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-// Map from load(globaladdress) -> memw(#foo + 0)
-let AddedComplexity = 100 in
-def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))),
- (i64 (LDd_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-// Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd
-let AddedComplexity = 100 in
-def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))),
- (i1 (TFR_PdRs (i32 (LDb_GP_V4 tglobaladdr:$global))))>,
- Requires<[HasV4T]>;
-
-// When the Interprocedural Global Variable optimizer realizes that a certain
-// global variable takes only two constant values, it shrinks the global to
-// a boolean. Catch those loads here in the following 3 patterns.
-let AddedComplexity = 100 in
-def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-let AddedComplexity = 100 in
-def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-// Map from load(globaladdress) -> memb(#foo)
-let AddedComplexity = 100 in
-def : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-// Map from load(globaladdress) -> memb(#foo)
-let AddedComplexity = 100 in
-def : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-let AddedComplexity = 100 in
-def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDub_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-// Map from load(globaladdress) -> memub(#foo)
-let AddedComplexity = 100 in
-def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDub_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-// Map from load(globaladdress) -> memh(#foo)
-let AddedComplexity = 100 in
-def : Pat <(i32 (extloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDh_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-// Map from load(globaladdress) -> memh(#foo)
-let AddedComplexity = 100 in
-def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDh_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-// Map from load(globaladdress) -> memuh(#foo)
-let AddedComplexity = 100 in
-def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDuh_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
-// Map from load(globaladdress) -> memw(#foo)
-let AddedComplexity = 100 in
-def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDw_GP_V4 tglobaladdr:$global))>,
- Requires<[HasV4T]>;
-
// zext i1->i64
def : Pat <(i64 (zext (i1 PredRegs:$src1))),
(i64 (COMBINE_Ir_V4 0, (MUX_ii (i1 PredRegs:$src1), 1, 0)))>,
@@ -1008,78 +453,29 @@ def: Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
// ST +
//===----------------------------------------------------------------------===//
///
-/// Assumptions::: ****** DO NOT IGNORE ********
-/// 1. Make sure that in post increment store, the zero'th operand is always the
-/// post increment operand.
-/// 2. Make sure that the store value operand(Rt/Rtt) in a store is always the
-/// last operand.
-///
-
-// memd(Re=#U)=Rtt
-let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in {
-def STrid_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
- (ins DoubleRegs:$src1, u0AlwaysExt:$src2),
- "memd($dst1=##$src2) = $src1",
- []>,
- Requires<[HasV4T]>;
-
-// memb(Re=#U)=Rs
-def STrib_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
- (ins IntRegs:$src1, u0AlwaysExt:$src2),
- "memb($dst1=##$src2) = $src1",
- []>,
- Requires<[HasV4T]>;
-
-// memh(Re=#U)=Rs
-def STrih_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
- (ins IntRegs:$src1, u0AlwaysExt:$src2),
- "memh($dst1=##$src2) = $src1",
- []>,
- Requires<[HasV4T]>;
-
-// memw(Re=#U)=Rs
-def STriw_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
- (ins IntRegs:$src1, u0AlwaysExt:$src2),
- "memw($dst1=##$src2) = $src1",
- []>,
- Requires<[HasV4T]>;
-}
-
-// memd(Re=#U)=Rtt
-let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in {
-def STrid_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
- (ins DoubleRegs:$src1, globaladdressExt:$src2),
- "memd($dst1=##$src2) = $src1",
- []>,
- Requires<[HasV4T]>;
-
-// memb(Re=#U)=Rs
-def STrib_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
- (ins IntRegs:$src1, globaladdressExt:$src2),
- "memb($dst1=##$src2) = $src1",
- []>,
- Requires<[HasV4T]>;
-
-// memh(Re=#U)=Rs
-def STrih_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
- (ins IntRegs:$src1, globaladdressExt:$src2),
- "memh($dst1=##$src2) = $src1",
+//===----------------------------------------------------------------------===//
+// Template class for store instructions with Absolute set addressing mode.
+//===----------------------------------------------------------------------===//
+let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in
+class T_ST_abs_set<string mnemonic, RegisterClass RC>:
+ STInst2<(outs IntRegs:$dst1),
+ (ins RC:$src1, u0AlwaysExt:$src2),
+ mnemonic#"($dst1=##$src2) = $src1",
[]>,
Requires<[HasV4T]>;
-// memw(Re=#U)=Rs
-def STriw_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
- (ins IntRegs:$src1, globaladdressExt:$src2),
- "memw($dst1=##$src2) = $src1",
- []>,
- Requires<[HasV4T]>;
-}
+def STrid_abs_set_V4 : T_ST_abs_set <"memd", DoubleRegs>;
+def STrib_abs_set_V4 : T_ST_abs_set <"memb", IntRegs>;
+def STrih_abs_set_V4 : T_ST_abs_set <"memh", IntRegs>;
+def STriw_abs_set_V4 : T_ST_abs_set <"memw", IntRegs>;
+//===----------------------------------------------------------------------===//
// multiclass for store instructions with base + register offset addressing
// mode
+//===----------------------------------------------------------------------===//
multiclass ST_Idxd_shl_Pbase<string mnemonic, RegisterClass RC, bit isNot,
bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : STInst2<(outs),
(ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
RC:$src5),
@@ -1090,7 +486,7 @@ multiclass ST_Idxd_shl_Pbase<string mnemonic, RegisterClass RC, bit isNot,
}
multiclass ST_Idxd_shl_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 0>;
// Predicate new
defm _cdn#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 1>;
@@ -1118,7 +514,7 @@ multiclass ST_Idxd_shl<string mnemonic, string CextOp, RegisterClass RC> {
// addressing mode.
multiclass ST_Idxd_shl_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME#_nv_V4 : NVInst_V4<(outs),
(ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
RC:$src5),
@@ -1129,7 +525,7 @@ multiclass ST_Idxd_shl_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
}
multiclass ST_Idxd_shl_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 0>;
// Predicate new
defm _cdn#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 1>;
@@ -1192,17 +588,59 @@ def : Pat<(store (i64 DoubleRegs:$src4),
u2ImmPred:$src3, DoubleRegs:$src4)>;
}
-// memd(Ru<<#u2+#U6)=Rtt
-let isExtended = 1, opExtendable = 2, AddedComplexity = 10,
-validSubTargets = HasV4SubT in
-def STrid_shl_V4 : STInst<(outs),
- (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, DoubleRegs:$src4),
- "memd($src1<<#$src2+#$src3) = $src4",
- [(store (i64 DoubleRegs:$src4),
+let isExtended = 1, opExtendable = 2 in
+class T_ST_LongOff <string mnemonic, PatFrag stOp, RegisterClass RC, ValueType VT> :
+ STInst<(outs),
+ (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, RC:$src4),
+ mnemonic#"($src1<<#$src2+##$src3) = $src4",
+ [(stOp (VT RC:$src4),
(add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
u0AlwaysExtPred:$src3))]>,
Requires<[HasV4T]>;
+let isExtended = 1, opExtendable = 2, mayStore = 1, isNVStore = 1 in
+class T_ST_LongOff_nv <string mnemonic> :
+ NVInst_V4<(outs),
+ (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
+ mnemonic#"($src1<<#$src2+##$src3) = $src4.new",
+ []>,
+ Requires<[HasV4T]>;
+
+multiclass ST_LongOff <string mnemonic, string BaseOp, PatFrag stOp> {
+ let BaseOpcode = BaseOp#"_shl" in {
+ let isNVStorable = 1 in
+ def NAME#_V4 : T_ST_LongOff<mnemonic, stOp, IntRegs, i32>;
+
+ def NAME#_nv_V4 : T_ST_LongOff_nv<mnemonic>;
+ }
+}
+
+let AddedComplexity = 10, validSubTargets = HasV4SubT in {
+ def STrid_shl_V4 : T_ST_LongOff<"memd", store, DoubleRegs, i64>;
+ defm STrib_shl : ST_LongOff <"memb", "STrib", truncstorei8>, NewValueRel;
+ defm STrih_shl : ST_LongOff <"memh", "Strih", truncstorei16>, NewValueRel;
+ defm STriw_shl : ST_LongOff <"memw", "STriw", store>, NewValueRel;
+}
+
+let AddedComplexity = 40 in
+multiclass T_ST_LOff_Pats <InstHexagon I, RegisterClass RC, ValueType VT,
+ PatFrag stOp> {
+ def : Pat<(stOp (VT RC:$src4),
+ (add (shl IntRegs:$src1, u2ImmPred:$src2),
+ (NumUsesBelowThresCONST32 tglobaladdr:$src3))),
+ (I IntRegs:$src1, u2ImmPred:$src2, tglobaladdr:$src3, RC:$src4)>;
+
+ def : Pat<(stOp (VT RC:$src4),
+ (add IntRegs:$src1,
+ (NumUsesBelowThresCONST32 tglobaladdr:$src3))),
+ (I IntRegs:$src1, 0, tglobaladdr:$src3, RC:$src4)>;
+}
+
+defm : T_ST_LOff_Pats<STrid_shl_V4, DoubleRegs, i64, store>;
+defm : T_ST_LOff_Pats<STriw_shl_V4, IntRegs, i32, store>;
+defm : T_ST_LOff_Pats<STrib_shl_V4, IntRegs, i32, truncstorei8>;
+defm : T_ST_LOff_Pats<STrih_shl_V4, IntRegs, i32, truncstorei16>;
+
// memd(Rx++#s4:3)=Rtt
// memd(Rx++#s4:3:circ(Mu))=Rtt
// memd(Rx++I:circ(Mu))=Rtt
@@ -1222,7 +660,7 @@ def STrid_shl_V4 : STInst<(outs),
//===----------------------------------------------------------------------===//
multiclass ST_Imm_Pbase<string mnemonic, Operand OffsetOp, bit isNot,
bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : STInst2<(outs),
(ins PredRegs:$src1, IntRegs:$src2, OffsetOp:$src3, s6Ext:$src4),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -1232,7 +670,7 @@ multiclass ST_Imm_Pbase<string mnemonic, Operand OffsetOp, bit isNot,
}
multiclass ST_Imm_Pred<string mnemonic, Operand OffsetOp, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 0>;
// Predicate new
defm _cdn#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 1>;
@@ -1280,17 +718,6 @@ def : Pat <(truncstorei8 s8ExtPred:$src2, (i32 IntRegs:$src1)),
(STrib_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
Requires<[HasV4T]>;
-// memb(Ru<<#u2+#U6)=Rt
-let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
-validSubTargets = HasV4SubT in
-def STrib_shl_V4 : STInst<(outs),
- (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
- "memb($src1<<#$src2+#$src3) = $src4",
- [(truncstorei8 (i32 IntRegs:$src4),
- (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
- u0AlwaysExtPred:$src3))]>,
- Requires<[HasV4T]>;
-
// memb(Rx++#s4:0:circ(Mu))=Rt
// memb(Rx++I:circ(Mu))=Rt
// memb(Rx++Mu)=Rt
@@ -1311,17 +738,6 @@ def : Pat <(truncstorei16 s8ExtPred:$src2, (i32 IntRegs:$src1)),
// TODO: needs to be implemented.
// memh(Ru<<#u2+#U6)=Rt.H
-// memh(Ru<<#u2+#U6)=Rt
-let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
-validSubTargets = HasV4SubT in
-def STrih_shl_V4 : STInst<(outs),
- (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
- "memh($src1<<#$src2+#$src3) = $src4",
- [(truncstorei16 (i32 IntRegs:$src4),
- (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
- u0AlwaysExtPred:$src3))]>,
- Requires<[HasV4T]>;
-
// memh(Rx++#s4:1:circ(Mu))=Rt.H
// memh(Rx++#s4:1:circ(Mu))=Rt
// memh(Rx++I:circ(Mu))=Rt.H
@@ -1358,241 +774,11 @@ def : Pat <(store s8ExtPred:$src2, (i32 IntRegs:$src1)),
(STriw_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
Requires<[HasV4T]>;
-// memw(Ru<<#u2+#U6)=Rt
-let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
-validSubTargets = HasV4SubT in
-def STriw_shl_V4 : STInst<(outs),
- (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
- "memw($src1<<#$src2+#$src3) = $src4",
- [(store (i32 IntRegs:$src4),
- (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
- u0AlwaysExtPred:$src3))]>,
- Requires<[HasV4T]>;
-
// memw(Rx++#s4:2)=Rt
// memw(Rx++#s4:2:circ(Mu))=Rt
// memw(Rx++I:circ(Mu))=Rt
// memw(Rx++Mu)=Rt
// memw(Rx++Mu:brev)=Rt
-// memw(gp+#u16:2)=Rt
-
-
-// memd(#global)=Rtt
-let isPredicable = 1, mayStore = 1, neverHasSideEffects = 1,
-validSubTargets = HasV4SubT in
-def STd_GP_V4 : STInst2<(outs),
- (ins globaladdress:$global, DoubleRegs:$src),
- "memd(#$global) = $src",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memd(##global) = Rtt
-let mayStore = 1, neverHasSideEffects = 1, isPredicated = 1,
-isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
-def STd_GP_cPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
- "if ($src1) memd(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memd(##global) = Rtt
-def STd_GP_cNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
- "if (!$src1) memd(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memd(##global) = Rtt
-def STd_GP_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
- "if ($src1.new) memd(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memd(##global) = Rtt
-def STd_GP_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, DoubleRegs:$src2),
- "if (!$src1.new) memd(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-}
-
-// memb(#global)=Rt
-let isPredicable = 1, neverHasSideEffects = 1, isNVStorable = 1,
-validSubTargets = HasV4SubT in
-def STb_GP_V4 : STInst2<(outs),
- (ins globaladdress:$global, IntRegs:$src),
- "memb(#$global) = $src",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memb(##global) = Rt
-let neverHasSideEffects = 1, isPredicated = 1, isNVStorable = 1,
-isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
-def STb_GP_cPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1) memb(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memb(##global) = Rt
-def STb_GP_cNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1) memb(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memb(##global) = Rt
-def STb_GP_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1.new) memb(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memb(##global) = Rt
-def STb_GP_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1.new) memb(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-}
-
-// memh(#global)=Rt
-let isPredicable = 1, neverHasSideEffects = 1, isNVStorable = 1,
-validSubTargets = HasV4SubT in
-def STh_GP_V4 : STInst2<(outs),
- (ins globaladdress:$global, IntRegs:$src),
- "memh(#$global) = $src",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memh(##global) = Rt
-let neverHasSideEffects = 1, isPredicated = 1, isNVStorable = 1,
-isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
-def STh_GP_cPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1) memh(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memh(##global) = Rt
-def STh_GP_cNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1) memh(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memh(##global) = Rt
-def STh_GP_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1.new) memh(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memh(##global) = Rt
-def STh_GP_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1.new) memh(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-}
-
-// memw(#global)=Rt
-let isPredicable = 1, neverHasSideEffects = 1, isNVStorable = 1,
-validSubTargets = HasV4SubT in
-def STw_GP_V4 : STInst2<(outs),
- (ins globaladdress:$global, IntRegs:$src),
- "memw(#$global) = $src",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memw(##global) = Rt
-let neverHasSideEffects = 1, isPredicated = 1, isNVStorable = 1,
-isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
-def STw_GP_cPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1) memw(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memw(##global) = Rt
-def STw_GP_cNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1) memw(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memw(##global) = Rt
-def STw_GP_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1.new) memw(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memw(##global) = Rt
-def STw_GP_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1.new) memw(##$global) = $src2",
- []>,
- Requires<[HasV4T]>;
-}
-
-// 64 bit atomic store
-def : Pat <(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global),
- (i64 DoubleRegs:$src1)),
- (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
- Requires<[HasV4T]>;
-
-// Map from store(globaladdress) -> memd(#foo)
-let AddedComplexity = 100 in
-def : Pat <(store (i64 DoubleRegs:$src1),
- (HexagonCONST32_GP tglobaladdr:$global)),
- (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
- Requires<[HasV4T]>;
-
-// 8 bit atomic store
-def : Pat < (atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global),
- (i32 IntRegs:$src1)),
- (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[HasV4T]>;
-
-// Map from store(globaladdress) -> memb(#foo)
-let AddedComplexity = 100 in
-def : Pat<(truncstorei8 (i32 IntRegs:$src1),
- (HexagonCONST32_GP tglobaladdr:$global)),
- (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[HasV4T]>;
-
-// Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1"
-// to "r0 = 1; memw(#foo) = r0"
-let AddedComplexity = 100 in
-def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
- (STb_GP_V4 tglobaladdr:$global, (TFRI 1))>,
- Requires<[HasV4T]>;
-
-def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
- (i32 IntRegs:$src1)),
- (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[HasV4T]>;
-
-// Map from store(globaladdress) -> memh(#foo)
-let AddedComplexity = 100 in
-def : Pat<(truncstorei16 (i32 IntRegs:$src1),
- (HexagonCONST32_GP tglobaladdr:$global)),
- (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[HasV4T]>;
-
-// 32 bit atomic store
-def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global),
- (i32 IntRegs:$src1)),
- (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[HasV4T]>;
-
-// Map from store(globaladdress) -> memw(#foo)
-let AddedComplexity = 100 in
-def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
- (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>,
- Requires<[HasV4T]>;
//===----------------------------------------------------------------------===
// ST -
@@ -1607,7 +793,7 @@ def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
//
multiclass ST_Idxd_Pbase_nv<string mnemonic, RegisterClass RC,
Operand predImmOp, bit isNot, bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME#_nv_V4 : NVInst_V4<(outs),
(ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -1618,7 +804,7 @@ multiclass ST_Idxd_Pbase_nv<string mnemonic, RegisterClass RC,
multiclass ST_Idxd_Pred_nv<string mnemonic, RegisterClass RC, Operand predImmOp,
bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 0>;
// Predicate new
defm _cdn#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 1>;
@@ -1660,7 +846,7 @@ let addrMode = BaseImmOffset, validSubTargets = HasV4SubT in {
// and MEMri operand.
multiclass ST_MEMri_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME#_nv_V4 : NVInst_V4<(outs),
(ins PredRegs:$src1, MEMri:$addr, RC: $src2),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -1670,7 +856,7 @@ multiclass ST_MEMri_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
}
multiclass ST_MEMri_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 0>;
// Predicate new
@@ -1706,15 +892,6 @@ mayStore = 1 in {
defm STriw: ST_MEMri_nv<"memw", "STriw", IntRegs, 13, 8>, AddrModeRel;
}
-// memb(Ru<<#u2+#U6)=Nt.new
-let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
-isNVStore = 1, validSubTargets = HasV4SubT in
-def STrib_shl_nv_V4 : NVInst_V4<(outs),
- (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
- "memb($src1<<#$src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
//===----------------------------------------------------------------------===//
// Post increment store
// mem[bhwd](Rx++#s4:[0123])=Nt.new
@@ -1722,7 +899,7 @@ def STrib_shl_nv_V4 : NVInst_V4<(outs),
multiclass ST_PostInc_Pbase_nv<string mnemonic, RegisterClass RC, Operand ImmOp,
bit isNot, bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset, RC:$src3),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
@@ -1734,7 +911,7 @@ multiclass ST_PostInc_Pbase_nv<string mnemonic, RegisterClass RC, Operand ImmOp,
multiclass ST_PostInc_Pred_nv<string mnemonic, RegisterClass RC,
Operand ImmOp, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 0>;
// Predicate new
let Predicates = [HasV4T], validSubTargets = HasV4SubT in
@@ -1772,146 +949,15 @@ defm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel;
// memb(Rx++I:circ(Mu))=Nt.new
// memb(Rx++Mu)=Nt.new
// memb(Rx++Mu:brev)=Nt.new
-
-// memb(#global)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1 in
-def STb_GP_nv_V4 : NVInst_V4<(outs),
- (ins globaladdress:$global, IntRegs:$src),
- "memb(#$global) = $src.new",
- []>,
- Requires<[HasV4T]>;
-
-// memh(Ru<<#u2+#U6)=Nt.new
-let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
-isNVStore = 1, validSubTargets = HasV4SubT in
-def STrih_shl_nv_V4 : NVInst_V4<(outs),
- (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
- "memh($src1<<#$src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
// memh(Rx++#s4:1:circ(Mu))=Nt.new
// memh(Rx++I:circ(Mu))=Nt.new
// memh(Rx++Mu)=Nt.new
// memh(Rx++Mu:brev)=Nt.new
-// memh(#global)=Nt.new
-let mayStore = 1, neverHasSideEffects = 1 in
-def STh_GP_nv_V4 : NVInst_V4<(outs),
- (ins globaladdress:$global, IntRegs:$src),
- "memh(#$global) = $src.new",
- []>,
- Requires<[HasV4T]>;
-
-// memw(Ru<<#u2+#U6)=Nt.new
-let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
-isNVStore = 1, validSubTargets = HasV4SubT in
-def STriw_shl_nv_V4 : NVInst_V4<(outs),
- (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
- "memw($src1<<#$src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-
// memw(Rx++#s4:2:circ(Mu))=Nt.new
// memw(Rx++I:circ(Mu))=Nt.new
// memw(Rx++Mu)=Nt.new
// memw(Rx++Mu:brev)=Nt.new
-// memw(gp+#u16:2)=Nt.new
-
-let mayStore = 1, neverHasSideEffects = 1, isNVStore = 1,
-validSubTargets = HasV4SubT in
-def STw_GP_nv_V4 : NVInst_V4<(outs),
- (ins globaladdress:$global, IntRegs:$src),
- "memw(#$global) = $src.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memb(##global) = Rt
-let mayStore = 1, neverHasSideEffects = 1, isNVStore = 1,
-isExtended = 1, opExtendable = 1, validSubTargets = HasV4SubT in {
-def STb_GP_cPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1) memb(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memb(##global) = Rt
-def STb_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1) memb(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memb(##global) = Rt
-def STb_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1.new) memb(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memb(##global) = Rt
-def STb_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1.new) memb(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memh(##global) = Rt
-def STh_GP_cPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1) memh(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memh(##global) = Rt
-def STh_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1) memh(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memh(##global) = Rt
-def STh_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1.new) memh(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memh(##global) = Rt
-def STh_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1.new) memh(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memw(##global) = Rt
-def STw_GP_cPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1) memw(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memw(##global) = Rt
-def STw_GP_cNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1) memw(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (Pv) memw(##global) = Rt
-def STw_GP_cdnPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if ($src1.new) memw(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-
-// if (!Pv) memw(##global) = Rt
-def STw_GP_cdnNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdress:$global, IntRegs:$src2),
- "if (!$src1.new) memw(##$global) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-}
//===----------------------------------------------------------------------===//
// NV/ST -
@@ -2658,414 +1704,367 @@ def LSRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
// MEMOP: Word, Half, Byte
//===----------------------------------------------------------------------===//
+def MEMOPIMM : SDNodeXForm<imm, [{
+ // Call the transformation function XformM5ToU5Imm to get the negative
+ // immediate's positive counterpart.
+ int32_t imm = N->getSExtValue();
+ return XformM5ToU5Imm(imm);
+}]>;
+
+def MEMOPIMM_HALF : SDNodeXForm<imm, [{
+ // -1 .. -31 represented as 65535..65515
+ // assigning to a short restores our desired signed value.
+ // Call the transformation function XformM5ToU5Imm to get the negative
+ // immediate's positive counterpart.
+ int16_t imm = N->getSExtValue();
+ return XformM5ToU5Imm(imm);
+}]>;
+
+def MEMOPIMM_BYTE : SDNodeXForm<imm, [{
+ // -1 .. -31 represented as 255..235
+ // assigning to a char restores our desired signed value.
+ // Call the transformation function XformM5ToU5Imm to get the negative
+ // immediate's positive counterpart.
+ int8_t imm = N->getSExtValue();
+ return XformM5ToU5Imm(imm);
+}]>;
+
+def SETMEMIMM : SDNodeXForm<imm, [{
+ // Return the bit position we will set [0-31].
+ // As an SDNode.
+ int32_t imm = N->getSExtValue();
+ return XformMskToBitPosU5Imm(imm);
+}]>;
+
+def CLRMEMIMM : SDNodeXForm<imm, [{
+ // Return the bit position we will clear [0-31].
+ // As an SDNode.
+ // we bit negate the value first
+ int32_t imm = ~(N->getSExtValue());
+ return XformMskToBitPosU5Imm(imm);
+}]>;
+
+def SETMEMIMM_SHORT : SDNodeXForm<imm, [{
+ // Return the bit position we will set [0-15].
+ // As an SDNode.
+ int16_t imm = N->getSExtValue();
+ return XformMskToBitPosU4Imm(imm);
+}]>;
+
+def CLRMEMIMM_SHORT : SDNodeXForm<imm, [{
+ // Return the bit position we will clear [0-15].
+ // As an SDNode.
+ // we bit negate the value first
+ int16_t imm = ~(N->getSExtValue());
+ return XformMskToBitPosU4Imm(imm);
+}]>;
+
+def SETMEMIMM_BYTE : SDNodeXForm<imm, [{
+ // Return the bit position we will set [0-7].
+ // As an SDNode.
+ int8_t imm = N->getSExtValue();
+ return XformMskToBitPosU3Imm(imm);
+}]>;
+
+def CLRMEMIMM_BYTE : SDNodeXForm<imm, [{
+ // Return the bit position we will clear [0-7].
+ // As an SDNode.
+ // we bit negate the value first
+ int8_t imm = ~(N->getSExtValue());
+ return XformMskToBitPosU3Imm(imm);
+}]>;
+
//===----------------------------------------------------------------------===//
-// MEMOP: Word
-//
-// Implemented:
-// MEMw_ADDi_indexed_V4 : memw(Rs+#u6:2)+=#U5
-// MEMw_SUBi_indexed_V4 : memw(Rs+#u6:2)-=#U5
-// MEMw_ADDr_indexed_V4 : memw(Rs+#u6:2)+=Rt
-// MEMw_SUBr_indexed_V4 : memw(Rs+#u6:2)-=Rt
-// MEMw_CLRr_indexed_V4 : memw(Rs+#u6:2)&=Rt
-// MEMw_SETr_indexed_V4 : memw(Rs+#u6:2)|=Rt
-// MEMw_ADDi_V4 : memw(Rs+#u6:2)+=#U5
-// MEMw_SUBi_V4 : memw(Rs+#u6:2)-=#U5
-// MEMw_ADDr_V4 : memw(Rs+#u6:2)+=Rt
-// MEMw_SUBr_V4 : memw(Rs+#u6:2)-=Rt
-// MEMw_CLRr_V4 : memw(Rs+#u6:2)&=Rt
-// MEMw_SETr_V4 : memw(Rs+#u6:2)|=Rt
-//
-// Not implemented:
-// MEMw_CLRi_indexed_V4 : memw(Rs+#u6:2)=clrbit(#U5)
-// MEMw_SETi_indexed_V4 : memw(Rs+#u6:2)=setbit(#U5)
-// MEMw_CLRi_V4 : memw(Rs+#u6:2)=clrbit(#U5)
-// MEMw_SETi_V4 : memw(Rs+#u6:2)=setbit(#U5)
+// Template class for MemOp instructions with the register value.
//===----------------------------------------------------------------------===//
+class MemOp_rr_base <string opc, bits<2> opcBits, Operand ImmOp,
+ string memOp, bits<2> memOpBits> :
+ MEMInst_V4<(outs),
+ (ins IntRegs:$base, ImmOp:$offset, IntRegs:$delta),
+ opc#"($base+#$offset)"#memOp#"$delta",
+ []>,
+ Requires<[HasV4T, UseMEMOP]> {
+
+ bits<5> base;
+ bits<5> delta;
+ bits<32> offset;
+ bits<6> offsetBits; // memb - u6:0 , memh - u6:1, memw - u6:2
+
+ let offsetBits = !if (!eq(opcBits, 0b00), offset{5-0},
+ !if (!eq(opcBits, 0b01), offset{6-1},
+ !if (!eq(opcBits, 0b10), offset{7-2},0)));
+
+ let IClass = 0b0011;
+ let Inst{27-24} = 0b1110;
+ let Inst{22-21} = opcBits;
+ let Inst{20-16} = base;
+ let Inst{13} = 0b0;
+ let Inst{12-7} = offsetBits;
+ let Inst{6-5} = memOpBits;
+ let Inst{4-0} = delta;
+}
+//===----------------------------------------------------------------------===//
+// Template class for MemOp instructions with the immediate value.
+//===----------------------------------------------------------------------===//
+class MemOp_ri_base <string opc, bits<2> opcBits, Operand ImmOp,
+ string memOp, bits<2> memOpBits> :
+ MEMInst_V4 <(outs),
+ (ins IntRegs:$base, ImmOp:$offset, u5Imm:$delta),
+ opc#"($base+#$offset)"#memOp#"#$delta"
+ #!if(memOpBits{1},")", ""), // clrbit, setbit - include ')'
+ []>,
+ Requires<[HasV4T, UseMEMOP]> {
+ bits<5> base;
+ bits<5> delta;
+ bits<32> offset;
+ bits<6> offsetBits; // memb - u6:0 , memh - u6:1, memw - u6:2
-// memw(Rs+#u6:2) += #U5
-let AddedComplexity = 30 in
-def MEMw_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_2Imm:$offset, u5Imm:$addend),
- "memw($base+#$offset) += #$addend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
+ let offsetBits = !if (!eq(opcBits, 0b00), offset{5-0},
+ !if (!eq(opcBits, 0b01), offset{6-1},
+ !if (!eq(opcBits, 0b10), offset{7-2},0)));
-// memw(Rs+#u6:2) -= #U5
-let AddedComplexity = 30 in
-def MEMw_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_2Imm:$offset, u5Imm:$subend),
- "memw($base+#$offset) -= #$subend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memw(Rs+#u6:2) += Rt
-let AddedComplexity = 30 in
-def MEMw_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$addend),
- "memw($base+#$offset) += $addend",
- [(store (add (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
- (i32 IntRegs:$addend)),
- (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memw(Rs+#u6:2) -= Rt
-let AddedComplexity = 30 in
-def MEMw_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$subend),
- "memw($base+#$offset) -= $subend",
- [(store (sub (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
- (i32 IntRegs:$subend)),
- (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memw(Rs+#u6:2) &= Rt
-let AddedComplexity = 30 in
-def MEMw_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$andend),
- "memw($base+#$offset) &= $andend",
- [(store (and (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
- (i32 IntRegs:$andend)),
- (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memw(Rs+#u6:2) |= Rt
-let AddedComplexity = 30 in
-def MEMw_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_2Imm:$offset, IntRegs:$orend),
- "memw($base+#$offset) |= $orend",
- [(store (or (load (add (i32 IntRegs:$base), u6_2ImmPred:$offset)),
- (i32 IntRegs:$orend)),
- (add (i32 IntRegs:$base), u6_2ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memw(Rs+#u6:2) += #U5
-let AddedComplexity = 30 in
-def MEMw_ADDi_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, u5Imm:$addend),
- "memw($addr) += $addend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
+ let IClass = 0b0011;
+ let Inst{27-24} = 0b1111;
+ let Inst{22-21} = opcBits;
+ let Inst{20-16} = base;
+ let Inst{13} = 0b0;
+ let Inst{12-7} = offsetBits;
+ let Inst{6-5} = memOpBits;
+ let Inst{4-0} = delta;
+}
-// memw(Rs+#u6:2) -= #U5
-let AddedComplexity = 30 in
-def MEMw_SUBi_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, u5Imm:$subend),
- "memw($addr) -= $subend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memw(Rs+#u6:2) += Rt
-let AddedComplexity = 30 in
-def MEMw_ADDr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$addend),
- "memw($addr) += $addend",
- [(store (add (load ADDRriU6_2:$addr), (i32 IntRegs:$addend)),
- ADDRriU6_2:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memw(Rs+#u6:2) -= Rt
-let AddedComplexity = 30 in
-def MEMw_SUBr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$subend),
- "memw($addr) -= $subend",
- [(store (sub (load ADDRriU6_2:$addr), (i32 IntRegs:$subend)),
- ADDRriU6_2:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memw(Rs+#u6:2) &= Rt
-let AddedComplexity = 30 in
-def MEMw_ANDr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$andend),
- "memw($addr) &= $andend",
- [(store (and (load ADDRriU6_2:$addr), (i32 IntRegs:$andend)),
- ADDRriU6_2:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memw(Rs+#u6:2) |= Rt
-let AddedComplexity = 30 in
-def MEMw_ORr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$orend),
- "memw($addr) |= $orend",
- [(store (or (load ADDRriU6_2:$addr), (i32 IntRegs:$orend)),
- ADDRriU6_2:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
+// multiclass to define MemOp instructions with register operand.
+multiclass MemOp_rr<string opc, bits<2> opcBits, Operand ImmOp> {
+ def _ADD#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " += ", 0b00>; // add
+ def _SUB#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " -= ", 0b01>; // sub
+ def _AND#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " &= ", 0b10>; // and
+ def _OR#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " |= ", 0b11>; // or
+}
+
+// multiclass to define MemOp instructions with immediate Operand.
+multiclass MemOp_ri<string opc, bits<2> opcBits, Operand ImmOp> {
+ def _ADD#NAME#_V4 : MemOp_ri_base <opc, opcBits, ImmOp, " += ", 0b00 >;
+ def _SUB#NAME#_V4 : MemOp_ri_base <opc, opcBits, ImmOp, " -= ", 0b01 >;
+ def _CLRBIT#NAME#_V4 : MemOp_ri_base<opc, opcBits, ImmOp, " =clrbit(", 0b10>;
+ def _SETBIT#NAME#_V4 : MemOp_ri_base<opc, opcBits, ImmOp, " =setbit(", 0b11>;
+}
+
+multiclass MemOp_base <string opc, bits<2> opcBits, Operand ImmOp> {
+ defm r : MemOp_rr <opc, opcBits, ImmOp>;
+ defm i : MemOp_ri <opc, opcBits, ImmOp>;
+}
+
+// Define MemOp instructions.
+let isExtendable = 1, opExtendable = 1, isExtentSigned = 0,
+validSubTargets =HasV4SubT in {
+ let opExtentBits = 6, accessSize = ByteAccess in
+ defm MemOPb : MemOp_base <"memb", 0b00, u6_0Ext>;
+
+ let opExtentBits = 7, accessSize = HalfWordAccess in
+ defm MemOPh : MemOp_base <"memh", 0b01, u6_1Ext>;
+
+ let opExtentBits = 8, accessSize = WordAccess in
+ defm MemOPw : MemOp_base <"memw", 0b10, u6_2Ext>;
+}
//===----------------------------------------------------------------------===//
-// MEMOP: Halfword
-//
-// Implemented:
-// MEMh_ADDi_indexed_V4 : memw(Rs+#u6:2)+=#U5
-// MEMh_SUBi_indexed_V4 : memw(Rs+#u6:2)-=#U5
-// MEMh_ADDr_indexed_V4 : memw(Rs+#u6:2)+=Rt
-// MEMh_SUBr_indexed_V4 : memw(Rs+#u6:2)-=Rt
-// MEMh_CLRr_indexed_V4 : memw(Rs+#u6:2)&=Rt
-// MEMh_SETr_indexed_V4 : memw(Rs+#u6:2)|=Rt
-// MEMh_ADDi_V4 : memw(Rs+#u6:2)+=#U5
-// MEMh_SUBi_V4 : memw(Rs+#u6:2)-=#U5
-// MEMh_ADDr_V4 : memw(Rs+#u6:2)+=Rt
-// MEMh_SUBr_V4 : memw(Rs+#u6:2)-=Rt
-// MEMh_CLRr_V4 : memw(Rs+#u6:2)&=Rt
-// MEMh_SETr_V4 : memw(Rs+#u6:2)|=Rt
-//
-// Not implemented:
-// MEMh_CLRi_indexed_V4 : memw(Rs+#u6:2)=clrbit(#U5)
-// MEMh_SETi_indexed_V4 : memw(Rs+#u6:2)=setbit(#U5)
-// MEMh_CLRi_V4 : memw(Rs+#u6:2)=clrbit(#U5)
-// MEMh_SETi_V4 : memw(Rs+#u6:2)=setbit(#U5)
+// Multiclass to define 'Def Pats' for ALU operations on the memory
+// Here value used for the ALU operation is an immediate value.
+// mem[bh](Rs+#0) += #U5
+// mem[bh](Rs+#u6) += #U5
//===----------------------------------------------------------------------===//
+multiclass MemOpi_u5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf ExtPred,
+ InstHexagon MI, SDNode OpNode> {
+ let AddedComplexity = 180 in
+ def : Pat < (stOp (OpNode (ldOp IntRegs:$addr), u5ImmPred:$addend),
+ IntRegs:$addr),
+ (MI IntRegs:$addr, #0, u5ImmPred:$addend )>;
-// memh(Rs+#u6:1) += #U5
-let AddedComplexity = 30 in
-def MEMh_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_1Imm:$offset, u5Imm:$addend),
- "memh($base+#$offset) += $addend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
+ let AddedComplexity = 190 in
+ def : Pat <(stOp (OpNode (ldOp (add IntRegs:$base, ExtPred:$offset)),
+ u5ImmPred:$addend),
+ (add IntRegs:$base, ExtPred:$offset)),
+ (MI IntRegs:$base, ExtPred:$offset, u5ImmPred:$addend)>;
+}
-// memh(Rs+#u6:1) -= #U5
-let AddedComplexity = 30 in
-def MEMh_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_1Imm:$offset, u5Imm:$subend),
- "memh($base+#$offset) -= $subend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memh(Rs+#u6:1) += Rt
-let AddedComplexity = 30 in
-def MEMh_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$addend),
- "memh($base+#$offset) += $addend",
- [(truncstorei16 (add (sextloadi16 (add (i32 IntRegs:$base),
- u6_1ImmPred:$offset)),
- (i32 IntRegs:$addend)),
- (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memh(Rs+#u6:1) -= Rt
-let AddedComplexity = 30 in
-def MEMh_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$subend),
- "memh($base+#$offset) -= $subend",
- [(truncstorei16 (sub (sextloadi16 (add (i32 IntRegs:$base),
- u6_1ImmPred:$offset)),
- (i32 IntRegs:$subend)),
- (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memh(Rs+#u6:1) &= Rt
-let AddedComplexity = 30 in
-def MEMh_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$andend),
- "memh($base+#$offset) += $andend",
- [(truncstorei16 (and (sextloadi16 (add (i32 IntRegs:$base),
- u6_1ImmPred:$offset)),
- (i32 IntRegs:$andend)),
- (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memh(Rs+#u6:1) |= Rt
-let AddedComplexity = 30 in
-def MEMh_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_1Imm:$offset, IntRegs:$orend),
- "memh($base+#$offset) |= $orend",
- [(truncstorei16 (or (sextloadi16 (add (i32 IntRegs:$base),
- u6_1ImmPred:$offset)),
- (i32 IntRegs:$orend)),
- (add (i32 IntRegs:$base), u6_1ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memh(Rs+#u6:1) += #U5
-let AddedComplexity = 30 in
-def MEMh_ADDi_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, u5Imm:$addend),
- "memh($addr) += $addend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
+multiclass MemOpi_u5ALUOp<PatFrag ldOp, PatFrag stOp, PatLeaf ExtPred,
+ InstHexagon addMI, InstHexagon subMI> {
+ defm : MemOpi_u5Pats<ldOp, stOp, ExtPred, addMI, add>;
+ defm : MemOpi_u5Pats<ldOp, stOp, ExtPred, subMI, sub>;
+}
-// memh(Rs+#u6:1) -= #U5
-let AddedComplexity = 30 in
-def MEMh_SUBi_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, u5Imm:$subend),
- "memh($addr) -= $subend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memh(Rs+#u6:1) += Rt
-let AddedComplexity = 30 in
-def MEMh_ADDr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$addend),
- "memh($addr) += $addend",
- [(truncstorei16 (add (sextloadi16 ADDRriU6_1:$addr),
- (i32 IntRegs:$addend)), ADDRriU6_1:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memh(Rs+#u6:1) -= Rt
-let AddedComplexity = 30 in
-def MEMh_SUBr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$subend),
- "memh($addr) -= $subend",
- [(truncstorei16 (sub (sextloadi16 ADDRriU6_1:$addr),
- (i32 IntRegs:$subend)), ADDRriU6_1:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memh(Rs+#u6:1) &= Rt
-let AddedComplexity = 30 in
-def MEMh_ANDr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$andend),
- "memh($addr) &= $andend",
- [(truncstorei16 (and (sextloadi16 ADDRriU6_1:$addr),
- (i32 IntRegs:$andend)), ADDRriU6_1:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memh(Rs+#u6:1) |= Rt
-let AddedComplexity = 30 in
-def MEMh_ORr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$orend),
- "memh($addr) |= $orend",
- [(truncstorei16 (or (sextloadi16 ADDRriU6_1:$addr),
- (i32 IntRegs:$orend)), ADDRriU6_1:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
+multiclass MemOpi_u5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
+ // Half Word
+ defm : MemOpi_u5ALUOp <ldOpHalf, truncstorei16, u6_1ExtPred,
+ MemOPh_ADDi_V4, MemOPh_SUBi_V4>;
+ // Byte
+ defm : MemOpi_u5ALUOp <ldOpByte, truncstorei8, u6ExtPred,
+ MemOPb_ADDi_V4, MemOPb_SUBi_V4>;
+}
+
+let Predicates = [HasV4T, UseMEMOP] in {
+ defm : MemOpi_u5ExtType<zextloadi8, zextloadi16>; // zero extend
+ defm : MemOpi_u5ExtType<sextloadi8, sextloadi16>; // sign extend
+ defm : MemOpi_u5ExtType<extloadi8, extloadi16>; // any extend
+ // Word
+ defm : MemOpi_u5ALUOp <load, store, u6_2ExtPred, MemOPw_ADDi_V4,
+ MemOPw_SUBi_V4>;
+}
//===----------------------------------------------------------------------===//
-// MEMOP: Byte
-//
-// Implemented:
-// MEMb_ADDi_indexed_V4 : memb(Rs+#u6:0)+=#U5
-// MEMb_SUBi_indexed_V4 : memb(Rs+#u6:0)-=#U5
-// MEMb_ADDr_indexed_V4 : memb(Rs+#u6:0)+=Rt
-// MEMb_SUBr_indexed_V4 : memb(Rs+#u6:0)-=Rt
-// MEMb_CLRr_indexed_V4 : memb(Rs+#u6:0)&=Rt
-// MEMb_SETr_indexed_V4 : memb(Rs+#u6:0)|=Rt
-// MEMb_ADDi_V4 : memb(Rs+#u6:0)+=#U5
-// MEMb_SUBi_V4 : memb(Rs+#u6:0)-=#U5
-// MEMb_ADDr_V4 : memb(Rs+#u6:0)+=Rt
-// MEMb_SUBr_V4 : memb(Rs+#u6:0)-=Rt
-// MEMb_CLRr_V4 : memb(Rs+#u6:0)&=Rt
-// MEMb_SETr_V4 : memb(Rs+#u6:0)|=Rt
-//
-// Not implemented:
-// MEMb_CLRi_indexed_V4 : memb(Rs+#u6:0)=clrbit(#U5)
-// MEMb_SETi_indexed_V4 : memb(Rs+#u6:0)=setbit(#U5)
-// MEMb_CLRi_V4 : memb(Rs+#u6:0)=clrbit(#U5)
-// MEMb_SETi_V4 : memb(Rs+#u6:0)=setbit(#U5)
+// multiclass to define 'Def Pats' for ALU operations on the memory.
+// Here value used for the ALU operation is a negative value.
+// mem[bh](Rs+#0) += #m5
+// mem[bh](Rs+#u6) += #m5
//===----------------------------------------------------------------------===//
-// memb(Rs+#u6:0) += #U5
-let AddedComplexity = 30 in
-def MEMb_ADDi_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_0Imm:$offset, u5Imm:$addend),
- "memb($base+#$offset) += $addend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
+multiclass MemOpi_m5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf extPred,
+ PatLeaf immPred, ComplexPattern addrPred,
+ SDNodeXForm xformFunc, InstHexagon MI> {
+ let AddedComplexity = 190 in
+ def : Pat <(stOp (add (ldOp IntRegs:$addr), immPred:$subend),
+ IntRegs:$addr),
+ (MI IntRegs:$addr, #0, (xformFunc immPred:$subend) )>;
-// memb(Rs+#u6:0) -= #U5
-let AddedComplexity = 30 in
-def MEMb_SUBi_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_0Imm:$offset, u5Imm:$subend),
- "memb($base+#$offset) -= $subend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memb(Rs+#u6:0) += Rt
-let AddedComplexity = 30 in
-def MEMb_ADDr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$addend),
- "memb($base+#$offset) += $addend",
- [(truncstorei8 (add (sextloadi8 (add (i32 IntRegs:$base),
- u6_0ImmPred:$offset)),
- (i32 IntRegs:$addend)),
- (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memb(Rs+#u6:0) -= Rt
-let AddedComplexity = 30 in
-def MEMb_SUBr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$subend),
- "memb($base+#$offset) -= $subend",
- [(truncstorei8 (sub (sextloadi8 (add (i32 IntRegs:$base),
- u6_0ImmPred:$offset)),
- (i32 IntRegs:$subend)),
- (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memb(Rs+#u6:0) &= Rt
-let AddedComplexity = 30 in
-def MEMb_ANDr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$andend),
- "memb($base+#$offset) += $andend",
- [(truncstorei8 (and (sextloadi8 (add (i32 IntRegs:$base),
- u6_0ImmPred:$offset)),
- (i32 IntRegs:$andend)),
- (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memb(Rs+#u6:0) |= Rt
-let AddedComplexity = 30 in
-def MEMb_ORr_indexed_MEM_V4 : MEMInst_V4<(outs),
- (ins IntRegs:$base, u6_0Imm:$offset, IntRegs:$orend),
- "memb($base+#$offset) |= $orend",
- [(truncstorei8 (or (sextloadi8 (add (i32 IntRegs:$base),
- u6_0ImmPred:$offset)),
- (i32 IntRegs:$orend)),
- (add (i32 IntRegs:$base), u6_0ImmPred:$offset))]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memb(Rs+#u6:0) += #U5
-let AddedComplexity = 30 in
-def MEMb_ADDi_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, u5Imm:$addend),
- "memb($addr) += $addend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
+ let AddedComplexity = 195 in
+ def : Pat<(stOp (add (ldOp (add IntRegs:$base, extPred:$offset)),
+ immPred:$subend),
+ (add IntRegs:$base, extPred:$offset)),
+ (MI IntRegs:$base, extPred:$offset, (xformFunc immPred:$subend))>;
+}
-// memb(Rs+#u6:0) -= #U5
-let AddedComplexity = 30 in
-def MEMb_SUBi_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, u5Imm:$subend),
- "memb($addr) -= $subend",
- []>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memb(Rs+#u6:0) += Rt
-let AddedComplexity = 30 in
-def MEMb_ADDr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$addend),
- "memb($addr) += $addend",
- [(truncstorei8 (add (sextloadi8 ADDRriU6_0:$addr),
- (i32 IntRegs:$addend)), ADDRriU6_0:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memb(Rs+#u6:0) -= Rt
-let AddedComplexity = 30 in
-def MEMb_SUBr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$subend),
- "memb($addr) -= $subend",
- [(truncstorei8 (sub (sextloadi8 ADDRriU6_0:$addr),
- (i32 IntRegs:$subend)), ADDRriU6_0:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memb(Rs+#u6:0) &= Rt
-let AddedComplexity = 30 in
-def MEMb_ANDr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$andend),
- "memb($addr) &= $andend",
- [(truncstorei8 (and (sextloadi8 ADDRriU6_0:$addr),
- (i32 IntRegs:$andend)), ADDRriU6_0:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
-
-// memb(Rs+#u6:0) |= Rt
-let AddedComplexity = 30 in
-def MEMb_ORr_MEM_V4 : MEMInst_V4<(outs),
- (ins MEMri:$addr, IntRegs:$orend),
- "memb($addr) |= $orend",
- [(truncstorei8 (or (sextloadi8 ADDRriU6_0:$addr),
- (i32 IntRegs:$orend)), ADDRriU6_0:$addr)]>,
- Requires<[HasV4T, UseMEMOP]>;
+multiclass MemOpi_m5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
+ // Half Word
+ defm : MemOpi_m5Pats <ldOpHalf, truncstorei16, u6_1ExtPred, m5HImmPred,
+ ADDRriU6_1, MEMOPIMM_HALF, MemOPh_SUBi_V4>;
+ // Byte
+ defm : MemOpi_m5Pats <ldOpByte, truncstorei8, u6ExtPred, m5BImmPred,
+ ADDRriU6_0, MEMOPIMM_BYTE, MemOPb_SUBi_V4>;
+}
+let Predicates = [HasV4T, UseMEMOP] in {
+ defm : MemOpi_m5ExtType<zextloadi8, zextloadi16>; // zero extend
+ defm : MemOpi_m5ExtType<sextloadi8, sextloadi16>; // sign extend
+ defm : MemOpi_m5ExtType<extloadi8, extloadi16>; // any extend
+
+ // Word
+ defm : MemOpi_m5Pats <load, store, u6_2ExtPred, m5ImmPred,
+ ADDRriU6_2, MEMOPIMM, MemOPw_SUBi_V4>;
+}
+
+//===----------------------------------------------------------------------===//
+// Multiclass to define 'def Pats' for bit operations on the memory.
+// mem[bhw](Rs+#0) = [clrbit|setbit](#U5)
+// mem[bhw](Rs+#u6) = [clrbit|setbit](#U5)
+//===----------------------------------------------------------------------===//
+
+multiclass MemOpi_bitPats <PatFrag ldOp, PatFrag stOp, PatLeaf immPred,
+ PatLeaf extPred, ComplexPattern addrPred,
+ SDNodeXForm xformFunc, InstHexagon MI, SDNode OpNode> {
+
+ // mem[bhw](Rs+#u6:[012]) = [clrbit|setbit](#U5)
+ let AddedComplexity = 250 in
+ def : Pat<(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)),
+ immPred:$bitend),
+ (add IntRegs:$base, extPred:$offset)),
+ (MI IntRegs:$base, extPred:$offset, (xformFunc immPred:$bitend))>;
+
+ // mem[bhw](Rs+#0) = [clrbit|setbit](#U5)
+ let AddedComplexity = 225 in
+ def : Pat <(stOp (OpNode (ldOp addrPred:$addr), immPred:$bitend),
+ addrPred:$addr),
+ (MI IntRegs:$addr, #0, (xformFunc immPred:$bitend))>;
+}
+
+multiclass MemOpi_bitExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
+ // Byte - clrbit
+ defm : MemOpi_bitPats<ldOpByte, truncstorei8, Clr3ImmPred, u6ExtPred,
+ ADDRriU6_0, CLRMEMIMM_BYTE, MemOPb_CLRBITi_V4, and>;
+ // Byte - setbit
+ defm : MemOpi_bitPats<ldOpByte, truncstorei8, Set3ImmPred, u6ExtPred,
+ ADDRriU6_0, SETMEMIMM_BYTE, MemOPb_SETBITi_V4, or>;
+ // Half Word - clrbit
+ defm : MemOpi_bitPats<ldOpHalf, truncstorei16, Clr4ImmPred, u6_1ExtPred,
+ ADDRriU6_1, CLRMEMIMM_SHORT, MemOPh_CLRBITi_V4, and>;
+ // Half Word - setbit
+ defm : MemOpi_bitPats<ldOpHalf, truncstorei16, Set4ImmPred, u6_1ExtPred,
+ ADDRriU6_1, SETMEMIMM_SHORT, MemOPh_SETBITi_V4, or>;
+}
+
+let Predicates = [HasV4T, UseMEMOP] in {
+ // mem[bh](Rs+#0) = [clrbit|setbit](#U5)
+ // mem[bh](Rs+#u6:[01]) = [clrbit|setbit](#U5)
+ defm : MemOpi_bitExtType<zextloadi8, zextloadi16>; // zero extend
+ defm : MemOpi_bitExtType<sextloadi8, sextloadi16>; // sign extend
+ defm : MemOpi_bitExtType<extloadi8, extloadi16>; // any extend
+
+ // memw(Rs+#0) = [clrbit|setbit](#U5)
+ // memw(Rs+#u6:2) = [clrbit|setbit](#U5)
+ defm : MemOpi_bitPats<load, store, Clr5ImmPred, u6_2ExtPred, ADDRriU6_2,
+ CLRMEMIMM, MemOPw_CLRBITi_V4, and>;
+ defm : MemOpi_bitPats<load, store, Set5ImmPred, u6_2ExtPred, ADDRriU6_2,
+ SETMEMIMM, MemOPw_SETBITi_V4, or>;
+}
+
+//===----------------------------------------------------------------------===//
+// Multiclass to define 'def Pats' for ALU operations on the memory
+// where addend is a register.
+// mem[bhw](Rs+#0) [+-&|]= Rt
+// mem[bhw](Rs+#U6:[012]) [+-&|]= Rt
+//===----------------------------------------------------------------------===//
+
+multiclass MemOpr_Pats <PatFrag ldOp, PatFrag stOp, ComplexPattern addrPred,
+ PatLeaf extPred, InstHexagon MI, SDNode OpNode> {
+ let AddedComplexity = 141 in
+ // mem[bhw](Rs+#0) [+-&|]= Rt
+ def : Pat <(stOp (OpNode (ldOp addrPred:$addr), (i32 IntRegs:$addend)),
+ addrPred:$addr),
+ (MI IntRegs:$addr, #0, (i32 IntRegs:$addend) )>;
+
+ // mem[bhw](Rs+#U6:[012]) [+-&|]= Rt
+ let AddedComplexity = 150 in
+ def : Pat <(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)),
+ (i32 IntRegs:$orend)),
+ (add IntRegs:$base, extPred:$offset)),
+ (MI IntRegs:$base, extPred:$offset, (i32 IntRegs:$orend) )>;
+}
+
+multiclass MemOPr_ALUOp<PatFrag ldOp, PatFrag stOp,
+ ComplexPattern addrPred, PatLeaf extPred,
+ InstHexagon addMI, InstHexagon subMI,
+ InstHexagon andMI, InstHexagon orMI > {
+
+ defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, addMI, add>;
+ defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, subMI, sub>;
+ defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, andMI, and>;
+ defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, orMI, or>;
+}
+
+multiclass MemOPr_ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
+ // Half Word
+ defm : MemOPr_ALUOp <ldOpHalf, truncstorei16, ADDRriU6_1, u6_1ExtPred,
+ MemOPh_ADDr_V4, MemOPh_SUBr_V4,
+ MemOPh_ANDr_V4, MemOPh_ORr_V4>;
+ // Byte
+ defm : MemOPr_ALUOp <ldOpByte, truncstorei8, ADDRriU6_0, u6ExtPred,
+ MemOPb_ADDr_V4, MemOPb_SUBr_V4,
+ MemOPb_ANDr_V4, MemOPb_ORr_V4>;
+}
+
+// Define 'def Pats' for MemOps with register addend.
+let Predicates = [HasV4T, UseMEMOP] in {
+ // Byte, Half Word
+ defm : MemOPr_ExtType<zextloadi8, zextloadi16>; // zero extend
+ defm : MemOPr_ExtType<sextloadi8, sextloadi16>; // sign extend
+ defm : MemOPr_ExtType<extloadi8, extloadi16>; // any extend
+ // Word
+ defm : MemOPr_ALUOp <load, store, ADDRriU6_2, u6_2ExtPred, MemOPw_ADDr_V4,
+ MemOPw_SUBr_V4, MemOPw_ANDr_V4, MemOPw_ORr_V4 >;
+}
//===----------------------------------------------------------------------===//
// XTYPE/PRED +
@@ -3146,7 +2145,7 @@ def CMPbEQri_V4 : MInst<(outs PredRegs:$dst),
def : Pat <(brcond (i1 (setne (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2)),
bb:$offset),
- (JMP_cNot (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2),
+ (JMP_f (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2),
bb:$offset)>,
Requires<[HasV4T]>;
@@ -3629,9 +2628,9 @@ let isReturn = 1, isTerminator = 1,
multiclass ST_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME#_V4 : STInst2<(outs),
- (ins PredRegs:$src1, globaladdressExt:$absaddr, RC: $src2),
+ (ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
") ")#mnemonic#"(##$absaddr) = $src2",
[]>,
@@ -3639,7 +2638,7 @@ multiclass ST_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
}
multiclass ST_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 0>;
// Predicate new
defm _cdn#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 1>;
@@ -3651,7 +2650,7 @@ multiclass ST_Abs<string mnemonic, string CextOp, RegisterClass RC> {
let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
let opExtendable = 0, isPredicable = 1 in
def NAME#_V4 : STInst2<(outs),
- (ins globaladdressExt:$absaddr, RC:$src),
+ (ins u0AlwaysExt:$absaddr, RC:$src),
mnemonic#"(##$absaddr) = $src",
[]>,
Requires<[HasV4T]>;
@@ -3665,9 +2664,9 @@ multiclass ST_Abs<string mnemonic, string CextOp, RegisterClass RC> {
multiclass ST_Abs_Predbase_nv<string mnemonic, RegisterClass RC, bit isNot,
bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME#_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, globaladdressExt:$absaddr, RC: $src2),
+ (ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
") ")#mnemonic#"(##$absaddr) = $src2.new",
[]>,
@@ -3675,7 +2674,7 @@ multiclass ST_Abs_Predbase_nv<string mnemonic, RegisterClass RC, bit isNot,
}
multiclass ST_Abs_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 0>;
// Predicate new
defm _cdn#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 1>;
@@ -3687,7 +2686,7 @@ multiclass ST_Abs_nv<string mnemonic, string CextOp, RegisterClass RC> {
let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
let opExtendable = 0, isPredicable = 1 in
def NAME#_nv_V4 : NVInst_V4<(outs),
- (ins globaladdressExt:$absaddr, RC:$src),
+ (ins u0AlwaysExt:$absaddr, RC:$src),
mnemonic#"(##$absaddr) = $src.new",
[]>,
Requires<[HasV4T]>;
@@ -3700,16 +2699,19 @@ multiclass ST_Abs_nv<string mnemonic, string CextOp, RegisterClass RC> {
}
let addrMode = Absolute in {
+ let accessSize = ByteAccess in
defm STrib_abs : ST_Abs<"memb", "STrib", IntRegs>,
ST_Abs_nv<"memb", "STrib", IntRegs>, AddrModeRel;
+ let accessSize = HalfWordAccess in
defm STrih_abs : ST_Abs<"memh", "STrih", IntRegs>,
ST_Abs_nv<"memh", "STrih", IntRegs>, AddrModeRel;
+ let accessSize = WordAccess in
defm STriw_abs : ST_Abs<"memw", "STriw", IntRegs>,
ST_Abs_nv<"memw", "STriw", IntRegs>, AddrModeRel;
- let isNVStorable = 0 in
+ let accessSize = DoubleWordAccess, isNVStorable = 0 in
defm STrid_abs : ST_Abs<"memd", "STrid", DoubleRegs>, AddrModeRel;
}
@@ -3730,11 +2732,115 @@ def : Pat<(store (i64 DoubleRegs:$src1),
(STrid_abs_V4 tglobaladdr: $absaddr, DoubleRegs: $src1)>;
}
+//===----------------------------------------------------------------------===//
+// multiclass for store instructions with GP-relative addressing mode.
+// mem[bhwd](#global)=Rt
+// if ([!]Pv[.new]) mem[bhwd](##global) = Rt
+//===----------------------------------------------------------------------===//
+let mayStore = 1, isNVStorable = 1 in
+multiclass ST_GP<string mnemonic, string BaseOp, RegisterClass RC> {
+ let BaseOpcode = BaseOp, isPredicable = 1 in
+ def NAME#_V4 : STInst2<(outs),
+ (ins globaladdress:$global, RC:$src),
+ mnemonic#"(#$global) = $src",
+ []>;
+
+ // When GP-relative instructions are predicated, their addressing mode is
+ // changed to absolute and they are always constant extended.
+ let BaseOpcode = BaseOp, isExtended = 1, opExtendable = 1,
+ isPredicated = 1 in {
+ defm Pt : ST_Abs_Pred <mnemonic, RC, 0>;
+ defm NotPt : ST_Abs_Pred <mnemonic, RC, 1>;
+ }
+}
+
+let mayStore = 1, isNVStore = 1 in
+multiclass ST_GP_nv<string mnemonic, string BaseOp, RegisterClass RC> {
+ let BaseOpcode = BaseOp, isPredicable = 1 in
+ def NAME#_nv_V4 : NVInst_V4<(outs),
+ (ins u0AlwaysExt:$global, RC:$src),
+ mnemonic#"(#$global) = $src.new",
+ []>,
+ Requires<[HasV4T]>;
+
+ // When GP-relative instructions are predicated, their addressing mode is
+ // changed to absolute and they are always constant extended.
+ let BaseOpcode = BaseOp, isExtended = 1, opExtendable = 1,
+ isPredicated = 1 in {
+ defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>;
+ defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>;
+ }
+}
+
+let validSubTargets = HasV4SubT, neverHasSideEffects = 1 in {
+ let isNVStorable = 0 in
+ defm STd_GP : ST_GP <"memd", "STd_GP", DoubleRegs>, PredNewRel;
+
+ defm STb_GP : ST_GP<"memb", "STb_GP", IntRegs>,
+ ST_GP_nv<"memb", "STb_GP", IntRegs>, NewValueRel;
+ defm STh_GP : ST_GP<"memh", "STh_GP", IntRegs>,
+ ST_GP_nv<"memh", "STh_GP", IntRegs>, NewValueRel;
+ defm STw_GP : ST_GP<"memw", "STw_GP", IntRegs>,
+ ST_GP_nv<"memw", "STw_GP", IntRegs>, NewValueRel;
+}
+
+// 64 bit atomic store
+def : Pat <(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global),
+ (i64 DoubleRegs:$src1)),
+ (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
+ Requires<[HasV4T]>;
+
+// Map from store(globaladdress) -> memd(#foo)
+let AddedComplexity = 100 in
+def : Pat <(store (i64 DoubleRegs:$src1),
+ (HexagonCONST32_GP tglobaladdr:$global)),
+ (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>;
+
+// 8 bit atomic store
+def : Pat < (atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global),
+ (i32 IntRegs:$src1)),
+ (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
+
+// Map from store(globaladdress) -> memb(#foo)
+let AddedComplexity = 100 in
+def : Pat<(truncstorei8 (i32 IntRegs:$src1),
+ (HexagonCONST32_GP tglobaladdr:$global)),
+ (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
+
+// Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1"
+// to "r0 = 1; memw(#foo) = r0"
+let AddedComplexity = 100 in
+def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
+ (STb_GP_V4 tglobaladdr:$global, (TFRI 1))>;
+
+def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
+ (i32 IntRegs:$src1)),
+ (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
+
+// Map from store(globaladdress) -> memh(#foo)
+let AddedComplexity = 100 in
+def : Pat<(truncstorei16 (i32 IntRegs:$src1),
+ (HexagonCONST32_GP tglobaladdr:$global)),
+ (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
+
+// 32 bit atomic store
+def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global),
+ (i32 IntRegs:$src1)),
+ (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
+
+// Map from store(globaladdress) -> memw(#foo)
+let AddedComplexity = 100 in
+def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
+ (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
+
+//===----------------------------------------------------------------------===//
+// Multiclass for the load instructions with absolute addressing mode.
+//===----------------------------------------------------------------------===//
multiclass LD_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
bit isPredNew> {
- let PNewValue = !if(isPredNew, "new", "") in
+ let isPredicatedNew = isPredNew in
def NAME : LDInst2<(outs RC:$dst),
- (ins PredRegs:$src1, globaladdressExt:$absaddr),
+ (ins PredRegs:$src1, u0AlwaysExt:$absaddr),
!if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
") ")#"$dst = "#mnemonic#"(##$absaddr)",
[]>,
@@ -3742,7 +2848,7 @@ multiclass LD_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
}
multiclass LD_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let PredSense = !if(PredNot, "false", "true") in {
+ let isPredicatedFalse = PredNot in {
defm _c#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 0>;
// Predicate new
defm _cdn#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 1>;
@@ -3754,7 +2860,7 @@ multiclass LD_Abs<string mnemonic, string CextOp, RegisterClass RC> {
let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
let opExtendable = 1, isPredicable = 1 in
def NAME#_V4 : LDInst2<(outs RC:$dst),
- (ins globaladdressExt:$absaddr),
+ (ins u0AlwaysExt:$absaddr),
"$dst = "#mnemonic#"(##$absaddr)",
[]>,
Requires<[HasV4T]>;
@@ -3767,33 +2873,138 @@ multiclass LD_Abs<string mnemonic, string CextOp, RegisterClass RC> {
}
let addrMode = Absolute in {
+ let accessSize = ByteAccess in {
defm LDrib_abs : LD_Abs<"memb", "LDrib", IntRegs>, AddrModeRel;
defm LDriub_abs : LD_Abs<"memub", "LDriub", IntRegs>, AddrModeRel;
+ }
+ let accessSize = HalfWordAccess in {
defm LDrih_abs : LD_Abs<"memh", "LDrih", IntRegs>, AddrModeRel;
defm LDriuh_abs : LD_Abs<"memuh", "LDriuh", IntRegs>, AddrModeRel;
+ }
+ let accessSize = WordAccess in
defm LDriw_abs : LD_Abs<"memw", "LDriw", IntRegs>, AddrModeRel;
+
+ let accessSize = DoubleWordAccess in
defm LDrid_abs : LD_Abs<"memd", "LDrid", DoubleRegs>, AddrModeRel;
}
-let Predicates = [HasV4T], AddedComplexity = 30 in
+let Predicates = [HasV4T], AddedComplexity = 30 in {
def : Pat<(i32 (load (HexagonCONST32 tglobaladdr:$absaddr))),
(LDriw_abs_V4 tglobaladdr: $absaddr)>;
-let Predicates = [HasV4T], AddedComplexity=30 in
def : Pat<(i32 (sextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
(LDrib_abs_V4 tglobaladdr:$absaddr)>;
-let Predicates = [HasV4T], AddedComplexity=30 in
def : Pat<(i32 (zextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
(LDriub_abs_V4 tglobaladdr:$absaddr)>;
-let Predicates = [HasV4T], AddedComplexity=30 in
def : Pat<(i32 (sextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
(LDrih_abs_V4 tglobaladdr:$absaddr)>;
-let Predicates = [HasV4T], AddedComplexity=30 in
def : Pat<(i32 (zextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
(LDriuh_abs_V4 tglobaladdr:$absaddr)>;
+}
+
+//===----------------------------------------------------------------------===//
+// multiclass for load instructions with GP-relative addressing mode.
+// Rx=mem[bhwd](##global)
+// if ([!]Pv[.new]) Rx=mem[bhwd](##global)
+//===----------------------------------------------------------------------===//
+let neverHasSideEffects = 1, validSubTargets = HasV4SubT in
+multiclass LD_GP<string mnemonic, string BaseOp, RegisterClass RC> {
+ let BaseOpcode = BaseOp in {
+ let isPredicable = 1 in
+ def NAME#_V4 : LDInst2<(outs RC:$dst),
+ (ins globaladdress:$global),
+ "$dst = "#mnemonic#"(#$global)",
+ []>;
+
+ let isExtended = 1, opExtendable = 2, isPredicated = 1 in {
+ defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>;
+ defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>;
+ }
+ }
+}
+
+defm LDd_GP : LD_GP<"memd", "LDd_GP", DoubleRegs>, PredNewRel;
+defm LDb_GP : LD_GP<"memb", "LDb_GP", IntRegs>, PredNewRel;
+defm LDub_GP : LD_GP<"memub", "LDub_GP", IntRegs>, PredNewRel;
+defm LDh_GP : LD_GP<"memh", "LDh_GP", IntRegs>, PredNewRel;
+defm LDuh_GP : LD_GP<"memuh", "LDuh_GP", IntRegs>, PredNewRel;
+defm LDw_GP : LD_GP<"memw", "LDw_GP", IntRegs>, PredNewRel;
+
+def : Pat <(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)),
+ (i64 (LDd_GP_V4 tglobaladdr:$global))>;
+
+def : Pat <(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)),
+ (i32 (LDw_GP_V4 tglobaladdr:$global))>;
+
+def : Pat <(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)),
+ (i32 (LDuh_GP_V4 tglobaladdr:$global))>;
+
+def : Pat <(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)),
+ (i32 (LDub_GP_V4 tglobaladdr:$global))>;
+
+// Map from load(globaladdress) -> memw(#foo + 0)
+let AddedComplexity = 100 in
+def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))),
+ (i64 (LDd_GP_V4 tglobaladdr:$global))>;
+
+// Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd
+let AddedComplexity = 100 in
+def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))),
+ (i1 (TFR_PdRs (i32 (LDb_GP_V4 tglobaladdr:$global))))>;
+
+// When the Interprocedural Global Variable optimizer realizes that a certain
+// global variable takes only two constant values, it shrinks the global to
+// a boolean. Catch those loads here in the following 3 patterns.
+let AddedComplexity = 100 in
+def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDb_GP_V4 tglobaladdr:$global))>;
+
+let AddedComplexity = 100 in
+def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDb_GP_V4 tglobaladdr:$global))>;
+
+// Map from load(globaladdress) -> memb(#foo)
+let AddedComplexity = 100 in
+def : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDb_GP_V4 tglobaladdr:$global))>;
+
+// Map from load(globaladdress) -> memb(#foo)
+let AddedComplexity = 100 in
+def : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDb_GP_V4 tglobaladdr:$global))>;
+
+let AddedComplexity = 100 in
+def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDub_GP_V4 tglobaladdr:$global))>;
+
+// Map from load(globaladdress) -> memub(#foo)
+let AddedComplexity = 100 in
+def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDub_GP_V4 tglobaladdr:$global))>;
+
+// Map from load(globaladdress) -> memh(#foo)
+let AddedComplexity = 100 in
+def : Pat <(i32 (extloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDh_GP_V4 tglobaladdr:$global))>;
+
+// Map from load(globaladdress) -> memh(#foo)
+let AddedComplexity = 100 in
+def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDh_GP_V4 tglobaladdr:$global))>;
+
+// Map from load(globaladdress) -> memuh(#foo)
+let AddedComplexity = 100 in
+def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDuh_GP_V4 tglobaladdr:$global))>;
+
+// Map from load(globaladdress) -> memw(#foo)
+let AddedComplexity = 100 in
+def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))),
+ (i32 (LDw_GP_V4 tglobaladdr:$global))>;
+
// Transfer global address into a register
let AddedComplexity=50, isMoveImm = 1, isReMaterializable = 1 in
@@ -3842,19 +3053,21 @@ def : Pat<(HexagonCONST32_GP tglobaladdr:$src1),
// Load - Indirect with long offset: These instructions take global address
// as an operand
-let AddedComplexity = 10 in
+let isExtended = 1, opExtendable = 3, AddedComplexity = 40,
+validSubTargets = HasV4SubT in
def LDrid_ind_lo_V4 : LDInst<(outs DoubleRegs:$dst),
- (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$offset),
+ (ins IntRegs:$src1, u2Imm:$src2, globaladdressExt:$offset),
"$dst=memd($src1<<#$src2+##$offset)",
[(set (i64 DoubleRegs:$dst),
(load (add (shl IntRegs:$src1, u2ImmPred:$src2),
(HexagonCONST32 tglobaladdr:$offset))))]>,
Requires<[HasV4T]>;
-let AddedComplexity = 10 in
+let AddedComplexity = 40 in
multiclass LD_indirect_lo<string OpcStr, PatFrag OpNode> {
+let isExtended = 1, opExtendable = 3, validSubTargets = HasV4SubT in
def _lo_V4 : LDInst<(outs IntRegs:$dst),
- (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$offset),
+ (ins IntRegs:$src1, u2Imm:$src2, globaladdressExt:$offset),
!strconcat("$dst = ",
!strconcat(OpcStr, "($src1<<#$src2+##$offset)")),
[(set IntRegs:$dst,
@@ -3865,202 +3078,53 @@ multiclass LD_indirect_lo<string OpcStr, PatFrag OpNode> {
defm LDrib_ind : LD_indirect_lo<"memb", sextloadi8>;
defm LDriub_ind : LD_indirect_lo<"memub", zextloadi8>;
+defm LDriub_ind_anyext : LD_indirect_lo<"memub", extloadi8>;
defm LDrih_ind : LD_indirect_lo<"memh", sextloadi16>;
defm LDriuh_ind : LD_indirect_lo<"memuh", zextloadi16>;
+defm LDriuh_ind_anyext : LD_indirect_lo<"memuh", extloadi16>;
defm LDriw_ind : LD_indirect_lo<"memw", load>;
-// Store - Indirect with long offset: These instructions take global address
-// as an operand
-let AddedComplexity = 10 in
-def STrid_ind_lo_V4 : STInst<(outs),
- (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$src3,
- DoubleRegs:$src4),
- "memd($src1<<#$src2+#$src3) = $src4",
- [(store (i64 DoubleRegs:$src4),
- (add (shl IntRegs:$src1, u2ImmPred:$src2),
- (HexagonCONST32 tglobaladdr:$src3)))]>,
- Requires<[HasV4T]>;
-
-let AddedComplexity = 10 in
-multiclass ST_indirect_lo<string OpcStr, PatFrag OpNode> {
- def _lo_V4 : STInst<(outs),
- (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$src3,
- IntRegs:$src4),
- !strconcat(OpcStr, "($src1<<#$src2+##$src3) = $src4"),
- [(OpNode (i32 IntRegs:$src4),
- (add (shl IntRegs:$src1, u2ImmPred:$src2),
- (HexagonCONST32 tglobaladdr:$src3)))]>,
- Requires<[HasV4T]>;
-}
-
-defm STrib_ind : ST_indirect_lo<"memb", truncstorei8>;
-defm STrih_ind : ST_indirect_lo<"memh", truncstorei16>;
-defm STriw_ind : ST_indirect_lo<"memw", store>;
-
-// Store - absolute addressing mode: These instruction take constant
-// value as the extended operand.
-multiclass ST_absimm<string OpcStr> {
-let isExtended = 1, opExtendable = 0, isPredicable = 1,
-validSubTargets = HasV4SubT in
- def _abs_V4 : STInst2<(outs),
- (ins u0AlwaysExt:$src1, IntRegs:$src2),
- !strconcat(OpcStr, "(##$src1) = $src2"),
- []>,
- Requires<[HasV4T]>;
-
-let isExtended = 1, opExtendable = 1, isPredicated = 1,
-validSubTargets = HasV4SubT in {
- def _abs_cPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
- !strconcat("if ($src1)", !strconcat(OpcStr, "(##$src2) = $src3")),
- []>,
- Requires<[HasV4T]>;
-
- def _abs_cNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
- !strconcat("if (!$src1)", !strconcat(OpcStr, "(##$src2) = $src3")),
- []>,
- Requires<[HasV4T]>;
-
- def _abs_cdnPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
- !strconcat("if ($src1.new)",
- !strconcat(OpcStr, "(##$src2) = $src3")),
- []>,
- Requires<[HasV4T]>;
-
- def _abs_cdnNotPt_V4 : STInst2<(outs),
- (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
- !strconcat("if (!$src1.new)",
- !strconcat(OpcStr, "(##$src2) = $src3")),
- []>,
- Requires<[HasV4T]>;
-}
-
-let isExtended = 1, opExtendable = 0, mayStore = 1, isNVStore = 1,
-validSubTargets = HasV4SubT in
- def _abs_nv_V4 : NVInst_V4<(outs),
- (ins u0AlwaysExt:$src1, IntRegs:$src2),
- !strconcat(OpcStr, "(##$src1) = $src2.new"),
- []>,
- Requires<[HasV4T]>;
-
-let isExtended = 1, opExtendable = 1, mayStore = 1, isPredicated = 1,
-isNVStore = 1, validSubTargets = HasV4SubT in {
- def _abs_cPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
- !strconcat("if ($src1)",
- !strconcat(OpcStr, "(##$src2) = $src3.new")),
- []>,
- Requires<[HasV4T]>;
-
- def _abs_cNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
- !strconcat("if (!$src1)",
- !strconcat(OpcStr, "(##$src2) = $src3.new")),
- []>,
- Requires<[HasV4T]>;
-
- def _abs_cdnPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
- !strconcat("if ($src1.new)",
- !strconcat(OpcStr, "(##$src2) = $src3.new")),
- []>,
- Requires<[HasV4T]>;
-
- def _abs_cdnNotPt_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
- !strconcat("if (!$src1.new)",
- !strconcat(OpcStr, "(##$src2) = $src3.new")),
- []>,
- Requires<[HasV4T]>;
-}
-}
+let AddedComplexity = 40 in
+def : Pat <(i32 (sextloadi8 (add IntRegs:$src1,
+ (NumUsesBelowThresCONST32 tglobaladdr:$offset)))),
+ (i32 (LDrib_ind_lo_V4 IntRegs:$src1, 0, tglobaladdr:$offset))>,
+ Requires<[HasV4T]>;
-defm STrib_imm : ST_absimm<"memb">;
-defm STrih_imm : ST_absimm<"memh">;
-defm STriw_imm : ST_absimm<"memw">;
+let AddedComplexity = 40 in
+def : Pat <(i32 (zextloadi8 (add IntRegs:$src1,
+ (NumUsesBelowThresCONST32 tglobaladdr:$offset)))),
+ (i32 (LDriub_ind_lo_V4 IntRegs:$src1, 0, tglobaladdr:$offset))>,
+ Requires<[HasV4T]>;
let Predicates = [HasV4T], AddedComplexity = 30 in {
def : Pat<(truncstorei8 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
- (STrib_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
+ (STrib_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
def : Pat<(truncstorei16 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
- (STrih_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
+ (STrih_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
def : Pat<(store (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
- (STriw_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
-}
-
-// Load - absolute addressing mode: These instruction take constant
-// value as the extended operand
-
-multiclass LD_absimm<string OpcStr> {
-let isExtended = 1, opExtendable = 1, isPredicable = 1,
-validSubTargets = HasV4SubT in
- def _abs_V4 : LDInst2<(outs IntRegs:$dst),
- (ins u0AlwaysExt:$src),
- !strconcat("$dst = ",
- !strconcat(OpcStr, "(##$src)")),
- []>,
- Requires<[HasV4T]>;
-
-let isExtended = 1, opExtendable = 2, isPredicated = 1,
-validSubTargets = HasV4SubT in {
- def _abs_cPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, u0AlwaysExt:$src2),
- !strconcat("if ($src1) $dst = ",
- !strconcat(OpcStr, "(##$src2)")),
- []>,
- Requires<[HasV4T]>;
-
- def _abs_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, u0AlwaysExt:$src2),
- !strconcat("if (!$src1) $dst = ",
- !strconcat(OpcStr, "(##$src2)")),
- []>,
- Requires<[HasV4T]>;
-
- def _abs_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, u0AlwaysExt:$src2),
- !strconcat("if ($src1.new) $dst = ",
- !strconcat(OpcStr, "(##$src2)")),
- []>,
- Requires<[HasV4T]>;
-
- def _abs_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
- (ins PredRegs:$src1, u0AlwaysExt:$src2),
- !strconcat("if (!$src1.new) $dst = ",
- !strconcat(OpcStr, "(##$src2)")),
- []>,
- Requires<[HasV4T]>;
+ (STriw_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
}
-}
-
-defm LDrib_imm : LD_absimm<"memb">;
-defm LDriub_imm : LD_absimm<"memub">;
-defm LDrih_imm : LD_absimm<"memh">;
-defm LDriuh_imm : LD_absimm<"memuh">;
-defm LDriw_imm : LD_absimm<"memw">;
let Predicates = [HasV4T], AddedComplexity = 30 in {
def : Pat<(i32 (load u0AlwaysExtPred:$src)),
- (LDriw_imm_abs_V4 u0AlwaysExtPred:$src)>;
+ (LDriw_abs_V4 u0AlwaysExtPred:$src)>;
def : Pat<(i32 (sextloadi8 u0AlwaysExtPred:$src)),
- (LDrib_imm_abs_V4 u0AlwaysExtPred:$src)>;
+ (LDrib_abs_V4 u0AlwaysExtPred:$src)>;
def : Pat<(i32 (zextloadi8 u0AlwaysExtPred:$src)),
- (LDriub_imm_abs_V4 u0AlwaysExtPred:$src)>;
+ (LDriub_abs_V4 u0AlwaysExtPred:$src)>;
def : Pat<(i32 (sextloadi16 u0AlwaysExtPred:$src)),
- (LDrih_imm_abs_V4 u0AlwaysExtPred:$src)>;
+ (LDrih_abs_V4 u0AlwaysExtPred:$src)>;
def : Pat<(i32 (zextloadi16 u0AlwaysExtPred:$src)),
- (LDriuh_imm_abs_V4 u0AlwaysExtPred:$src)>;
+ (LDriuh_abs_V4 u0AlwaysExtPred:$src)>;
}
-// Indexed store double word - global address.
+// Indexed store word - global address.
// memw(Rs+#u6:2)=#S8
let AddedComplexity = 10 in
def STriw_offset_ext_V4 : STInst<(outs),
diff --git a/lib/Target/Hexagon/HexagonMCInst.h b/lib/Target/Hexagon/HexagonMCInst.h
deleted file mode 100644
index e16636e..0000000
--- a/lib/Target/Hexagon/HexagonMCInst.h
+++ /dev/null
@@ -1,41 +0,0 @@
-//===- HexagonMCInst.h - Hexagon sub-class of MCInst ----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class extends MCInst to allow some VLIW annotation.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef HEXAGONMCINST_H
-#define HEXAGONMCINST_H
-
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/MC/MCInst.h"
-
-namespace llvm {
- class HexagonMCInst: public MCInst {
- // Packet start and end markers
- unsigned startPacket: 1, endPacket: 1;
- const MachineInstr *MachineI;
- public:
- explicit HexagonMCInst(): MCInst(),
- startPacket(0), endPacket(0) {}
-
- const MachineInstr* getMI() const { return MachineI; }
-
- void setMI(const MachineInstr *MI) { MachineI = MI; }
-
- bool isStartPacket() const { return (startPacket); }
- bool isEndPacket() const { return (endPacket); }
-
- void setStartPacket(bool yes) { startPacket = yes; }
- void setEndPacket(bool yes) { endPacket = yes; }
- };
-}
-
-#endif
diff --git a/lib/Target/Hexagon/HexagonMachineFunctionInfo.h b/lib/Target/Hexagon/HexagonMachineFunctionInfo.h
index 0318c51..bd7b26a 100644
--- a/lib/Target/Hexagon/HexagonMachineFunctionInfo.h
+++ b/lib/Target/Hexagon/HexagonMachineFunctionInfo.h
@@ -29,15 +29,18 @@ class HexagonMachineFunctionInfo : public MachineFunctionInfo {
std::vector<MachineInstr*> AllocaAdjustInsts;
int VarArgsFrameIndex;
bool HasClobberLR;
+ bool HasEHReturn;
std::map<const MachineInstr*, unsigned> PacketInfo;
public:
- HexagonMachineFunctionInfo() : SRetReturnReg(0), HasClobberLR(0) {}
+ HexagonMachineFunctionInfo() : SRetReturnReg(0), HasClobberLR(0),
+ HasEHReturn(false) {}
HexagonMachineFunctionInfo(MachineFunction &MF) : SRetReturnReg(0),
- HasClobberLR(0) {}
+ HasClobberLR(0),
+ HasEHReturn(false) {}
unsigned getSRetReturnReg() const { return SRetReturnReg; }
void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
@@ -69,6 +72,8 @@ public:
void setHasClobberLR(bool v) { HasClobberLR = v; }
bool hasClobberLR() const { return HasClobberLR; }
+ bool hasEHReturn() const { return HasEHReturn; };
+ void setHasEHReturn(bool H = true) { HasEHReturn = H; };
};
} // End llvm namespace
diff --git a/lib/Target/Hexagon/HexagonNewValueJump.cpp b/lib/Target/Hexagon/HexagonNewValueJump.cpp
index cd3d289..72af876 100644
--- a/lib/Target/Hexagon/HexagonNewValueJump.cpp
+++ b/lib/Target/Hexagon/HexagonNewValueJump.cpp
@@ -68,6 +68,7 @@ namespace {
HexagonNewValueJump() : MachineFunctionPass(ID) { }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<MachineBranchProbabilityInfo>();
MachineFunctionPass::getAnalysisUsage(AU);
}
@@ -78,6 +79,8 @@ namespace {
virtual bool runOnMachineFunction(MachineFunction &Fn);
private:
+ /// \brief A handle to the branch probability pass.
+ const MachineBranchProbabilityInfo *MBPI;
};
@@ -208,19 +211,15 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII,
// range specified by the arch.
if (!secondReg) {
int64_t v = MI->getOperand(2).getImm();
- if (MI->getOpcode() == Hexagon::CMPGEri ||
- (MI->getOpcode() == Hexagon::CMPGEUri && v > 0))
- --v;
if (!(isUInt<5>(v) ||
((MI->getOpcode() == Hexagon::CMPEQri ||
- MI->getOpcode() == Hexagon::CMPGTri ||
- MI->getOpcode() == Hexagon::CMPGEri) &&
+ MI->getOpcode() == Hexagon::CMPGTri) &&
(v == -1))))
return false;
}
- unsigned cmpReg1, cmpOp2 = 0; // cmpOp2 assignment silences compiler warning.
+ unsigned cmpReg1, cmpOp2;
cmpReg1 = MI->getOperand(1).getReg();
if (secondReg) {
@@ -271,58 +270,58 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII,
// Given a compare operator, return a matching New Value Jump
// compare operator. Make sure that MI here is included in
// HexagonInstrInfo.cpp::isNewValueJumpCandidate
-static unsigned getNewValueJumpOpcode(const MachineInstr *MI, int reg,
- bool secondRegNewified) {
+static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg,
+ bool secondRegNewified,
+ MachineBasicBlock *jmpTarget,
+ const MachineBranchProbabilityInfo
+ *MBPI) {
+ bool taken = false;
+ MachineBasicBlock *Src = MI->getParent();
+ const BranchProbability Prediction =
+ MBPI->getEdgeProbability(Src, jmpTarget);
+
+ if (Prediction >= BranchProbability(1,2))
+ taken = true;
+
switch (MI->getOpcode()) {
case Hexagon::CMPEQrr:
- return Hexagon::JMP_EQrrPt_nv_V4;
+ return taken ? Hexagon::JMP_EQrrPt_nv_V4 : Hexagon::JMP_EQrrPnt_nv_V4;
case Hexagon::CMPEQri: {
if (reg >= 0)
- return Hexagon::JMP_EQriPt_nv_V4;
+ return taken ? Hexagon::JMP_EQriPt_nv_V4 : Hexagon::JMP_EQriPnt_nv_V4;
else
- return Hexagon::JMP_EQriPtneg_nv_V4;
+ return taken ? Hexagon::JMP_EQriPtneg_nv_V4
+ : Hexagon::JMP_EQriPntneg_nv_V4;
}
- case Hexagon::CMPLTrr:
case Hexagon::CMPGTrr: {
if (secondRegNewified)
- return Hexagon::JMP_GTrrdnPt_nv_V4;
+ return taken ? Hexagon::JMP_GTrrdnPt_nv_V4
+ : Hexagon::JMP_GTrrdnPnt_nv_V4;
else
- return Hexagon::JMP_GTrrPt_nv_V4;
- }
-
- case Hexagon::CMPGEri: {
- if (reg >= 1)
- return Hexagon::JMP_GTriPt_nv_V4;
- else
- return Hexagon::JMP_GTriPtneg_nv_V4;
+ return taken ? Hexagon::JMP_GTrrPt_nv_V4
+ : Hexagon::JMP_GTrrPnt_nv_V4;
}
case Hexagon::CMPGTri: {
if (reg >= 0)
- return Hexagon::JMP_GTriPt_nv_V4;
+ return taken ? Hexagon::JMP_GTriPt_nv_V4 : Hexagon::JMP_GTriPnt_nv_V4;
else
- return Hexagon::JMP_GTriPtneg_nv_V4;
+ return taken ? Hexagon::JMP_GTriPtneg_nv_V4
+ : Hexagon::JMP_GTriPntneg_nv_V4;
}
- case Hexagon::CMPLTUrr:
case Hexagon::CMPGTUrr: {
if (secondRegNewified)
- return Hexagon::JMP_GTUrrdnPt_nv_V4;
+ return taken ? Hexagon::JMP_GTUrrdnPt_nv_V4
+ : Hexagon::JMP_GTUrrdnPnt_nv_V4;
else
- return Hexagon::JMP_GTUrrPt_nv_V4;
+ return taken ? Hexagon::JMP_GTUrrPt_nv_V4 : Hexagon::JMP_GTUrrPnt_nv_V4;
}
case Hexagon::CMPGTUri:
- return Hexagon::JMP_GTUriPt_nv_V4;
-
- case Hexagon::CMPGEUri: {
- if (reg == 0)
- return Hexagon::JMP_EQrrPt_nv_V4;
- else
- return Hexagon::JMP_GTUriPt_nv_V4;
- }
+ return taken ? Hexagon::JMP_GTUriPt_nv_V4 : Hexagon::JMP_GTUriPnt_nv_V4;
default:
llvm_unreachable("Could not find matching New Value Jump instruction.");
@@ -346,6 +345,7 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
QII = static_cast<const HexagonInstrInfo *>(MF.getTarget().getInstrInfo());
QRI =
static_cast<const HexagonRegisterInfo *>(MF.getTarget().getRegisterInfo());
+ MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
if (!QRI->Subtarget.hasV4TOps() ||
DisableNewValueJumps) {
@@ -393,12 +393,12 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
DEBUG(dbgs() << "Instr: "; MI->dump(); dbgs() << "\n");
if (!foundJump &&
- (MI->getOpcode() == Hexagon::JMP_c ||
- MI->getOpcode() == Hexagon::JMP_cNot ||
- MI->getOpcode() == Hexagon::JMP_cdnPt ||
- MI->getOpcode() == Hexagon::JMP_cdnPnt ||
- MI->getOpcode() == Hexagon::JMP_cdnNotPt ||
- MI->getOpcode() == Hexagon::JMP_cdnNotPnt)) {
+ (MI->getOpcode() == Hexagon::JMP_t ||
+ MI->getOpcode() == Hexagon::JMP_f ||
+ MI->getOpcode() == Hexagon::JMP_tnew_t ||
+ MI->getOpcode() == Hexagon::JMP_tnew_nt ||
+ MI->getOpcode() == Hexagon::JMP_fnew_t ||
+ MI->getOpcode() == Hexagon::JMP_fnew_nt)) {
// This is where you would insert your compare and
// instr that feeds compare
jmpPos = MII;
@@ -434,9 +434,9 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
jmpTarget = MI->getOperand(1).getMBB();
foundJump = true;
- if (MI->getOpcode() == Hexagon::JMP_cNot ||
- MI->getOpcode() == Hexagon::JMP_cdnNotPt ||
- MI->getOpcode() == Hexagon::JMP_cdnNotPnt) {
+ if (MI->getOpcode() == Hexagon::JMP_f ||
+ MI->getOpcode() == Hexagon::JMP_fnew_t ||
+ MI->getOpcode() == Hexagon::JMP_fnew_nt) {
invertPredicate = true;
}
continue;
@@ -525,10 +525,8 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
if (isSecondOpReg) {
// In case of CMPLT, or CMPLTU, or EQ with the second register
// to newify, swap the operands.
- if (cmpInstr->getOpcode() == Hexagon::CMPLTrr ||
- cmpInstr->getOpcode() == Hexagon::CMPLTUrr ||
- (cmpInstr->getOpcode() == Hexagon::CMPEQrr &&
- feederReg == (unsigned) cmpOp2)) {
+ if (cmpInstr->getOpcode() == Hexagon::CMPEQrr &&
+ feederReg == (unsigned) cmpOp2) {
unsigned tmp = cmpReg1;
bool tmpIsKill = MO1IsKill;
cmpReg1 = cmpOp2;
@@ -582,42 +580,34 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
assert((QII->isNewValueJumpCandidate(cmpInstr)) &&
"This compare is not a New Value Jump candidate.");
unsigned opc = getNewValueJumpOpcode(cmpInstr, cmpOp2,
- isSecondOpNewified);
+ isSecondOpNewified,
+ jmpTarget, MBPI);
if (invertPredicate)
opc = QII->getInvertedPredicatedOpcode(opc);
- // Manage the conversions from CMPGEUri to either CMPEQrr
- // or CMPGTUri properly. See Arch spec for CMPGEUri instructions.
- // This has to be after the getNewValueJumpOpcode function call as
- // second operand of the compare could be modified in this logic.
- if (cmpInstr->getOpcode() == Hexagon::CMPGEUri) {
- if (cmpOp2 == 0) {
- cmpOp2 = cmpReg1;
- MO2IsKill = MO1IsKill;
- isSecondOpReg = true;
- } else
- --cmpOp2;
- }
-
- // Manage the conversions from CMPGEri to CMPGTUri properly.
- // See Arch spec for CMPGEri instructions.
- if (cmpInstr->getOpcode() == Hexagon::CMPGEri)
- --cmpOp2;
-
- if (isSecondOpReg) {
+ if (isSecondOpReg)
NewMI = BuildMI(*MBB, jmpPos, dl,
QII->get(opc))
.addReg(cmpReg1, getKillRegState(MO1IsKill))
.addReg(cmpOp2, getKillRegState(MO2IsKill))
.addMBB(jmpTarget);
- }
- else {
+
+ else if ((cmpInstr->getOpcode() == Hexagon::CMPEQri ||
+ cmpInstr->getOpcode() == Hexagon::CMPGTri) &&
+ cmpOp2 == -1 )
+ // Corresponding new-value compare jump instructions don't have the
+ // operand for -1 immediate value.
+ NewMI = BuildMI(*MBB, jmpPos, dl,
+ QII->get(opc))
+ .addReg(cmpReg1, getKillRegState(MO1IsKill))
+ .addMBB(jmpTarget);
+
+ else
NewMI = BuildMI(*MBB, jmpPos, dl,
QII->get(opc))
.addReg(cmpReg1, getKillRegState(MO1IsKill))
.addImm(cmpOp2)
.addMBB(jmpTarget);
- }
assert(NewMI && "New Value Jump Instruction Not created!");
if (cmpInstr->getOperand(0).isReg() &&
diff --git a/lib/Target/Hexagon/HexagonPeephole.cpp b/lib/Target/Hexagon/HexagonPeephole.cpp
index 576f1d7..6c4eb7e 100644
--- a/lib/Target/Hexagon/HexagonPeephole.cpp
+++ b/lib/Target/Hexagon/HexagonPeephole.cpp
@@ -73,6 +73,10 @@ static cl::opt<bool> DisableOptSZExt("disable-hexagon-optszext",
cl::Hidden, cl::ZeroOrMore, cl::init(false),
cl::desc("Disable Optimization of Sign/Zero Extends"));
+static cl::opt<bool> DisableOptExtTo64("disable-hexagon-opt-ext-to-64",
+ cl::Hidden, cl::ZeroOrMore, cl::init(false),
+ cl::desc("Disable Optimization of extensions to i64."));
+
namespace {
struct HexagonPeephole : public MachineFunctionPass {
const HexagonInstrInfo *QII;
@@ -142,6 +146,21 @@ bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
}
}
+ // Look for %vreg170<def> = COMBINE_ir_V4 (0, %vreg169)
+ // %vreg170:DoublRegs, %vreg169:IntRegs
+ if (!DisableOptExtTo64 &&
+ MI->getOpcode () == Hexagon::COMBINE_Ir_V4) {
+ assert (MI->getNumOperands() == 3);
+ MachineOperand &Dst = MI->getOperand(0);
+ MachineOperand &Src1 = MI->getOperand(1);
+ MachineOperand &Src2 = MI->getOperand(2);
+ if (Src1.getImm() != 0)
+ continue;
+ unsigned DstReg = Dst.getReg();
+ unsigned SrcReg = Src2.getReg();
+ PeepholeMap[DstReg] = SrcReg;
+ }
+
// Look for this sequence below
// %vregDoubleReg1 = LSRd_ri %vregDoubleReg0, 32
// %vregIntReg = COPY %vregDoubleReg1:subreg_loreg.
diff --git a/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/lib/Target/Hexagon/HexagonRegisterInfo.cpp
index f947dfc..d8b4e2f 100644
--- a/lib/Target/Hexagon/HexagonRegisterInfo.cpp
+++ b/lib/Target/Hexagon/HexagonRegisterInfo.cpp
@@ -14,25 +14,26 @@
#include "HexagonRegisterInfo.h"
#include "Hexagon.h"
-#include "HexagonMachineFunctionInfo.h"
#include "HexagonSubtarget.h"
#include "HexagonTargetMachine.h"
+#include "HexagonMachineFunctionInfo.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Type.h"
#include "llvm/MC/MachineLocation.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
@@ -215,28 +216,41 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
MI.getOperand(FIOperandNum).ChangeToRegister(resReg, false, false,true);
MI.getOperand(FIOperandNum+1).ChangeToImmediate(0);
} else if (TII.isMemOp(&MI)) {
- unsigned resReg = HEXAGON_RESERVED_REG_1;
- if (!MFI.hasVarSizedObjects() &&
- TII.isValidOffset(MI.getOpcode(), (FrameSize+Offset))) {
- MI.getOperand(FIOperandNum).ChangeToRegister(getStackRegister(),
- false, false, true);
- MI.getOperand(FIOperandNum+1).ChangeToImmediate(FrameSize+Offset);
- } else if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) {
- BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
- TII.get(Hexagon::CONST32_Int_Real), resReg).addImm(Offset);
- BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
- TII.get(Hexagon::ADD_rr),
- resReg).addReg(FrameReg).addReg(resReg);
- MI.getOperand(FIOperandNum).ChangeToRegister(resReg, false, false,
- true);
- MI.getOperand(FIOperandNum+1).ChangeToImmediate(0);
+ // use the constant extender if the instruction provides it
+ // and we are V4TOps.
+ if (Subtarget.hasV4TOps()) {
+ if (TII.isConstExtended(&MI)) {
+ MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false);
+ MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset);
+ TII.immediateExtend(&MI);
+ } else {
+ llvm_unreachable("Need to implement for memops");
+ }
} else {
- BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
- TII.get(Hexagon::ADD_ri),
- resReg).addReg(FrameReg).addImm(Offset);
- MI.getOperand(FIOperandNum).ChangeToRegister(resReg, false, false,
- true);
- MI.getOperand(FIOperandNum+1).ChangeToImmediate(0);
+ // Only V3 and older instructions here.
+ unsigned ResReg = HEXAGON_RESERVED_REG_1;
+ if (!MFI.hasVarSizedObjects() &&
+ TII.isValidOffset(MI.getOpcode(), (FrameSize+Offset))) {
+ MI.getOperand(FIOperandNum).ChangeToRegister(getStackRegister(),
+ false, false, false);
+ MI.getOperand(FIOperandNum+1).ChangeToImmediate(FrameSize+Offset);
+ } else if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) {
+ BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
+ TII.get(Hexagon::CONST32_Int_Real), ResReg).addImm(Offset);
+ BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
+ TII.get(Hexagon::ADD_rr), ResReg).addReg(FrameReg).
+ addReg(ResReg);
+ MI.getOperand(FIOperandNum).ChangeToRegister(ResReg, false, false,
+ true);
+ MI.getOperand(FIOperandNum+1).ChangeToImmediate(0);
+ } else {
+ BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
+ TII.get(Hexagon::ADD_ri), ResReg).addReg(FrameReg).
+ addImm(Offset);
+ MI.getOperand(FIOperandNum).ChangeToRegister(ResReg, false, false,
+ true);
+ MI.getOperand(FIOperandNum+1).ChangeToImmediate(0);
+ }
}
} else {
unsigned dstReg = MI.getOperand(0).getReg();
diff --git a/lib/Target/Hexagon/HexagonSubtarget.cpp b/lib/Target/Hexagon/HexagonSubtarget.cpp
index 4bacb8f..07d5ce1 100644
--- a/lib/Target/Hexagon/HexagonSubtarget.cpp
+++ b/lib/Target/Hexagon/HexagonSubtarget.cpp
@@ -29,8 +29,16 @@ EnableV3("enable-hexagon-v3", cl::Hidden,
static cl::opt<bool>
EnableMemOps(
"enable-hexagon-memops",
- cl::Hidden, cl::ZeroOrMore, cl::ValueDisallowed,
- cl::desc("Generate V4 memop instructions."));
+ cl::Hidden, cl::ZeroOrMore, cl::ValueDisallowed, cl::init(true),
+ cl::desc(
+ "Generate V4 MEMOP in code generation for Hexagon target"));
+
+static cl::opt<bool>
+DisableMemOps(
+ "disable-hexagon-memops",
+ cl::Hidden, cl::ZeroOrMore, cl::ValueDisallowed, cl::init(false),
+ cl::desc(
+ "Do not generate V4 MEMOP in code generation for Hexagon target"));
static cl::opt<bool>
EnableIEEERndNear(
@@ -64,7 +72,10 @@ HexagonSubtarget::HexagonSubtarget(StringRef TT, StringRef CPU, StringRef FS):
// Initialize scheduling itinerary for the specified CPU.
InstrItins = getInstrItineraryForCPU(CPUString);
- if (EnableMemOps)
+ // UseMemOps on by default unless disabled explicitly
+ if (DisableMemOps)
+ UseMemOps = false;
+ else if (EnableMemOps)
UseMemOps = true;
else
UseMemOps = false;
diff --git a/lib/Target/Hexagon/HexagonTargetMachine.cpp b/lib/Target/Hexagon/HexagonTargetMachine.cpp
index d9fef3e..ce45c62 100644
--- a/lib/Target/Hexagon/HexagonTargetMachine.cpp
+++ b/lib/Target/Hexagon/HexagonTargetMachine.cpp
@@ -35,6 +35,10 @@ opt<bool> DisableHexagonMISched("disable-hexagon-misched",
cl::Hidden, cl::ZeroOrMore, cl::init(false),
cl::desc("Disable Hexagon MI Scheduling"));
+static cl::opt<bool> DisableHexagonCFGOpt("disable-hexagon-cfgopt",
+ cl::Hidden, cl::ZeroOrMore, cl::init(false),
+ cl::desc("Disable Hexagon CFG Optimization"));
+
/// HexagonTargetMachineModule - Note that this is used on hosts that
/// cannot link in a library unless there are references into the
/// library. In particular, it seems that it is not possible to get
@@ -75,19 +79,20 @@ HexagonTargetMachine::HexagonTargetMachine(const Target &T, StringRef TT,
TSInfo(*this),
FrameLowering(Subtarget),
InstrItins(&Subtarget.getInstrItineraryData()) {
- setMCUseCFI(false);
+ setMCUseCFI(false);
}
// addPassesForOptimizations - Allow the backend (target) to add Target
// Independent Optimization passes to the Pass Manager.
bool HexagonTargetMachine::addPassesForOptimizations(PassManagerBase &PM) {
-
- PM.add(createConstantPropagationPass());
- PM.add(createLoopSimplifyPass());
- PM.add(createDeadCodeEliminationPass());
- PM.add(createConstantPropagationPass());
- PM.add(createLoopUnrollPass());
- PM.add(createLoopStrengthReducePass());
+ if (getOptLevel() != CodeGenOpt::None) {
+ PM.add(createConstantPropagationPass());
+ PM.add(createLoopSimplifyPass());
+ PM.add(createDeadCodeEliminationPass());
+ PM.add(createConstantPropagationPass());
+ PM.add(createLoopUnrollPass());
+ PM.add(createLoopStrengthReducePass());
+ }
return true;
}
@@ -121,38 +126,45 @@ TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) {
}
bool HexagonPassConfig::addInstSelector() {
- addPass(createHexagonRemoveExtendOps(getHexagonTargetMachine()));
+
+ if (getOptLevel() != CodeGenOpt::None)
+ addPass(createHexagonRemoveExtendOps(getHexagonTargetMachine()));
+
addPass(createHexagonISelDag(getHexagonTargetMachine(), getOptLevel()));
- addPass(createHexagonPeephole());
+
+ if (getOptLevel() != CodeGenOpt::None)
+ addPass(createHexagonPeephole());
+
return false;
}
bool HexagonPassConfig::addPreRegAlloc() {
- if (!DisableHardwareLoops) {
+ if (!DisableHardwareLoops && getOptLevel() != CodeGenOpt::None)
addPass(createHexagonHardwareLoops());
- }
return false;
}
bool HexagonPassConfig::addPostRegAlloc() {
- addPass(createHexagonCFGOptimizer(getHexagonTargetMachine()));
+ if (!DisableHexagonCFGOpt && getOptLevel() != CodeGenOpt::None)
+ addPass(createHexagonCFGOptimizer(getHexagonTargetMachine()));
return true;
}
bool HexagonPassConfig::addPreSched2() {
- addPass(&IfConverterID);
+ if (getOptLevel() != CodeGenOpt::None)
+ addPass(&IfConverterID);
return true;
}
bool HexagonPassConfig::addPreEmitPass() {
- if (!DisableHardwareLoops) {
+ if (!DisableHardwareLoops && getOptLevel() != CodeGenOpt::None)
addPass(createHexagonFixupHwLoops());
- }
- addPass(createHexagonNewValueJump());
+ if (getOptLevel() != CodeGenOpt::None)
+ addPass(createHexagonNewValueJump());
// Expand Spill code for predicate registers.
addPass(createHexagonExpandPredSpillCode(getHexagonTargetMachine()));
@@ -161,7 +173,8 @@ bool HexagonPassConfig::addPreEmitPass() {
addPass(createHexagonSplitTFRCondSets(getHexagonTargetMachine()));
// Create Packets.
- addPass(createHexagonPacketizer());
+ if (getOptLevel() != CodeGenOpt::None)
+ addPass(createHexagonPacketizer());
return false;
}
diff --git a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
index 866beb1..e592df9 100644
--- a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
+++ b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
@@ -48,19 +48,35 @@
#include "HexagonMachineFunctionInfo.h"
#include <map>
+#include <vector>
using namespace llvm;
+static cl::opt<bool> PacketizeVolatiles("hexagon-packetize-volatiles",
+ cl::ZeroOrMore, cl::Hidden, cl::init(true),
+ cl::desc("Allow non-solo packetization of volatile memory references"));
+
+extern cl::opt<bool> ScheduleInlineAsm;
+extern cl::opt<bool> CountDeadOutput;
+
+namespace llvm {
+ void initializeHexagonPacketizerPass(PassRegistry&);
+}
+
+
namespace {
class HexagonPacketizer : public MachineFunctionPass {
public:
static char ID;
- HexagonPacketizer() : MachineFunctionPass(ID) {}
+ HexagonPacketizer() : MachineFunctionPass(ID) {
+ initializeHexagonPacketizerPass(*PassRegistry::getPassRegistry());
+ }
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
AU.addRequired<MachineDominatorTree>();
+ AU.addRequired<MachineBranchProbabilityInfo>();
AU.addPreserved<MachineDominatorTree>();
AU.addRequired<MachineLoopInfo>();
AU.addPreserved<MachineLoopInfo>();
@@ -96,10 +112,17 @@ namespace {
// schedule this instruction.
bool FoundSequentialDependence;
+ /// \brief A handle to the branch probability pass.
+ const MachineBranchProbabilityInfo *MBPI;
+
+ // Track MIs with ignored dependece.
+ std::vector<MachineInstr*> IgnoreDepMIs;
+
public:
// Ctor.
HexagonPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI,
- MachineDominatorTree &MDT);
+ MachineDominatorTree &MDT,
+ const MachineBranchProbabilityInfo *MBPI);
// initPacketizerState - initialize some internal flags.
void initPacketizerState();
@@ -123,20 +146,20 @@ namespace {
private:
bool IsCallDependent(MachineInstr* MI, SDep::Kind DepType, unsigned DepReg);
bool PromoteToDotNew(MachineInstr* MI, SDep::Kind DepType,
- MachineBasicBlock::iterator &MII,
- const TargetRegisterClass* RC);
+ MachineBasicBlock::iterator &MII,
+ const TargetRegisterClass* RC);
bool CanPromoteToDotNew(MachineInstr* MI, SUnit* PacketSU,
- unsigned DepReg,
- std::map <MachineInstr*, SUnit*> MIToSUnit,
- MachineBasicBlock::iterator &MII,
- const TargetRegisterClass* RC);
+ unsigned DepReg,
+ std::map <MachineInstr*, SUnit*> MIToSUnit,
+ MachineBasicBlock::iterator &MII,
+ const TargetRegisterClass* RC);
bool CanPromoteToNewValue(MachineInstr* MI, SUnit* PacketSU,
- unsigned DepReg,
- std::map <MachineInstr*, SUnit*> MIToSUnit,
- MachineBasicBlock::iterator &MII);
+ unsigned DepReg,
+ std::map <MachineInstr*, SUnit*> MIToSUnit,
+ MachineBasicBlock::iterator &MII);
bool CanPromoteToNewValueStore(MachineInstr* MI, MachineInstr* PacketMI,
- unsigned DepReg,
- std::map <MachineInstr*, SUnit*> MIToSUnit);
+ unsigned DepReg,
+ std::map <MachineInstr*, SUnit*> MIToSUnit);
bool DemoteToDotOld(MachineInstr* MI);
bool ArePredicatesComplements(MachineInstr* MI1, MachineInstr* MI2,
std::map <MachineInstr*, SUnit*> MIToSUnit);
@@ -149,23 +172,34 @@ namespace {
bool canReserveResourcesForConstExt(MachineInstr *MI);
void reserveResourcesForConstExt(MachineInstr* MI);
bool isNewValueInst(MachineInstr* MI);
- bool isDotNewInst(MachineInstr* MI);
};
}
+INITIALIZE_PASS_BEGIN(HexagonPacketizer, "packets", "Hexagon Packetizer",
+ false, false)
+INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
+INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
+INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
+INITIALIZE_PASS_END(HexagonPacketizer, "packets", "Hexagon Packetizer",
+ false, false)
+
+
// HexagonPacketizerList Ctor.
HexagonPacketizerList::HexagonPacketizerList(
- MachineFunction &MF, MachineLoopInfo &MLI,MachineDominatorTree &MDT)
+ MachineFunction &MF, MachineLoopInfo &MLI,MachineDominatorTree &MDT,
+ const MachineBranchProbabilityInfo *MBPI)
: VLIWPacketizerList(MF, MLI, MDT, true){
+ this->MBPI = MBPI;
}
bool HexagonPacketizer::runOnMachineFunction(MachineFunction &Fn) {
const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo();
MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>();
MachineDominatorTree &MDT = getAnalysis<MachineDominatorTree>();
-
+ const MachineBranchProbabilityInfo *MBPI =
+ &getAnalysis<MachineBranchProbabilityInfo>();
// Instantiate the packetizer.
- HexagonPacketizerList Packetizer(Fn, MLI, MDT);
+ HexagonPacketizerList Packetizer(Fn, MLI, MDT, MBPI);
// DFA state table should not be empty.
assert(Packetizer.getResourceTracker() && "Empty DFA table!");
@@ -711,8 +745,10 @@ static int GetDotNewOp(const int opc) {
}
// Return .new predicate version for an instruction
-static int GetDotNewPredOp(const int opc) {
- switch (opc) {
+static int GetDotNewPredOp(MachineInstr *MI,
+ const MachineBranchProbabilityInfo *MBPI,
+ const HexagonInstrInfo *QII) {
+ switch (MI->getOpcode()) {
default: llvm_unreachable("Unknown .new type");
// Conditional stores
// Store byte conditionally
@@ -858,17 +894,15 @@ static int GetDotNewPredOp(const int opc) {
return Hexagon::STw_GP_cdnNotPt_V4;
// Condtional Jumps
- case Hexagon::JMP_c:
- return Hexagon::JMP_cdnPt;
-
- case Hexagon::JMP_cNot:
- return Hexagon::JMP_cdnNotPt;
+ case Hexagon::JMP_t:
+ case Hexagon::JMP_f:
+ return QII->getDotNewPredJumpOp(MI, MBPI);
- case Hexagon::JMPR_cPt:
- return Hexagon::JMPR_cdnPt_V3;
+ case Hexagon::JMPR_t:
+ return Hexagon::JMPR_tnew_tV3;
- case Hexagon::JMPR_cNotPt:
- return Hexagon::JMPR_cdnNotPt_V3;
+ case Hexagon::JMPR_f:
+ return Hexagon::JMPR_fnew_tV3;
// Conditional Transfers
case Hexagon::TFR_cPt:
@@ -1262,7 +1296,7 @@ bool HexagonPacketizerList::PromoteToDotNew(MachineInstr* MI,
int NewOpcode;
if (RC == &Hexagon::PredRegsRegClass)
- NewOpcode = GetDotNewPredOp(MI->getOpcode());
+ NewOpcode = GetDotNewPredOp(MI, MBPI, QII);
else
NewOpcode = GetDotNewOp(MI->getOpcode());
MI->setDesc(QII->get(NewOpcode));
@@ -1307,17 +1341,17 @@ static int GetDotOldOp(const int opc) {
case Hexagon::TFRI_cdnNotPt:
return Hexagon::TFRI_cNotPt;
- case Hexagon::JMP_cdnPt:
- return Hexagon::JMP_c;
+ case Hexagon::JMP_tnew_t:
+ return Hexagon::JMP_t;
- case Hexagon::JMP_cdnNotPt:
- return Hexagon::JMP_cNot;
+ case Hexagon::JMP_fnew_t:
+ return Hexagon::JMP_f;
- case Hexagon::JMPR_cdnPt_V3:
- return Hexagon::JMPR_cPt;
+ case Hexagon::JMPR_tnew_tV3:
+ return Hexagon::JMPR_t;
- case Hexagon::JMPR_cdnNotPt_V3:
- return Hexagon::JMPR_cNotPt;
+ case Hexagon::JMPR_fnew_tV3:
+ return Hexagon::JMPR_f;
// Load double word
@@ -1913,7 +1947,7 @@ static bool GetPredicateSense(MachineInstr* MI,
case Hexagon::STrih_imm_cdnPt_V4 :
case Hexagon::STriw_imm_cPt_V4 :
case Hexagon::STriw_imm_cdnPt_V4 :
- case Hexagon::JMP_cdnPt :
+ case Hexagon::JMP_tnew_t :
case Hexagon::LDrid_cPt :
case Hexagon::LDrid_cdnPt :
case Hexagon::LDrid_indexed_cPt :
@@ -2052,7 +2086,7 @@ static bool GetPredicateSense(MachineInstr* MI,
case Hexagon::STrih_imm_cdnNotPt_V4 :
case Hexagon::STriw_imm_cNotPt_V4 :
case Hexagon::STriw_imm_cdnNotPt_V4 :
- case Hexagon::JMP_cdnNotPt :
+ case Hexagon::JMP_fnew_t :
case Hexagon::LDrid_cNotPt :
case Hexagon::LDrid_cdnNotPt :
case Hexagon::LDrid_indexed_cNotPt :
@@ -2154,172 +2188,6 @@ static bool GetPredicateSense(MachineInstr* MI,
return false;
}
-bool HexagonPacketizerList::isDotNewInst(MachineInstr* MI) {
- const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
- if (QII->isNewValueInst(MI))
- return true;
-
- switch (MI->getOpcode()) {
- case Hexagon::TFR_cdnNotPt:
- case Hexagon::TFR_cdnPt:
- case Hexagon::TFRI_cdnNotPt:
- case Hexagon::TFRI_cdnPt:
- case Hexagon::LDrid_cdnPt :
- case Hexagon::LDrid_cdnNotPt :
- case Hexagon::LDrid_indexed_cdnPt :
- case Hexagon::LDrid_indexed_cdnNotPt :
- case Hexagon::POST_LDrid_cdnPt_V4 :
- case Hexagon::POST_LDrid_cdnNotPt_V4 :
- case Hexagon::LDriw_cdnPt :
- case Hexagon::LDriw_cdnNotPt :
- case Hexagon::LDriw_indexed_cdnPt :
- case Hexagon::LDriw_indexed_cdnNotPt :
- case Hexagon::POST_LDriw_cdnPt_V4 :
- case Hexagon::POST_LDriw_cdnNotPt_V4 :
- case Hexagon::LDrih_cdnPt :
- case Hexagon::LDrih_cdnNotPt :
- case Hexagon::LDrih_indexed_cdnPt :
- case Hexagon::LDrih_indexed_cdnNotPt :
- case Hexagon::POST_LDrih_cdnPt_V4 :
- case Hexagon::POST_LDrih_cdnNotPt_V4 :
- case Hexagon::LDrib_cdnPt :
- case Hexagon::LDrib_cdnNotPt :
- case Hexagon::LDrib_indexed_cdnPt :
- case Hexagon::LDrib_indexed_cdnNotPt :
- case Hexagon::POST_LDrib_cdnPt_V4 :
- case Hexagon::POST_LDrib_cdnNotPt_V4 :
- case Hexagon::LDriuh_cdnPt :
- case Hexagon::LDriuh_cdnNotPt :
- case Hexagon::LDriuh_indexed_cdnPt :
- case Hexagon::LDriuh_indexed_cdnNotPt :
- case Hexagon::POST_LDriuh_cdnPt_V4 :
- case Hexagon::POST_LDriuh_cdnNotPt_V4 :
- case Hexagon::LDriub_cdnPt :
- case Hexagon::LDriub_cdnNotPt :
- case Hexagon::LDriub_indexed_cdnPt :
- case Hexagon::LDriub_indexed_cdnNotPt :
- case Hexagon::POST_LDriub_cdnPt_V4 :
- case Hexagon::POST_LDriub_cdnNotPt_V4 :
-
- case Hexagon::LDrid_indexed_shl_cdnPt_V4 :
- case Hexagon::LDrid_indexed_shl_cdnNotPt_V4 :
- case Hexagon::LDrib_indexed_shl_cdnPt_V4 :
- case Hexagon::LDrib_indexed_shl_cdnNotPt_V4 :
- case Hexagon::LDriub_indexed_shl_cdnPt_V4 :
- case Hexagon::LDriub_indexed_shl_cdnNotPt_V4 :
- case Hexagon::LDrih_indexed_shl_cdnPt_V4 :
- case Hexagon::LDrih_indexed_shl_cdnNotPt_V4 :
- case Hexagon::LDriuh_indexed_shl_cdnPt_V4 :
- case Hexagon::LDriuh_indexed_shl_cdnNotPt_V4 :
- case Hexagon::LDriw_indexed_shl_cdnPt_V4 :
- case Hexagon::LDriw_indexed_shl_cdnNotPt_V4 :
-
-// Coditional add
- case Hexagon::ADD_ri_cdnPt:
- case Hexagon::ADD_ri_cdnNotPt:
- case Hexagon::ADD_rr_cdnPt:
- case Hexagon::ADD_rr_cdnNotPt:
-
- // Conditional logical operations
- case Hexagon::XOR_rr_cdnPt :
- case Hexagon::XOR_rr_cdnNotPt :
- case Hexagon::AND_rr_cdnPt :
- case Hexagon::AND_rr_cdnNotPt :
- case Hexagon::OR_rr_cdnPt :
- case Hexagon::OR_rr_cdnNotPt :
-
- // Conditonal subtract
- case Hexagon::SUB_rr_cdnPt :
- case Hexagon::SUB_rr_cdnNotPt :
-
- // Conditional combine
- case Hexagon::COMBINE_rr_cdnPt :
- case Hexagon::COMBINE_rr_cdnNotPt :
-
- // Conditional shift operations
- case Hexagon::ASLH_cdnPt_V4:
- case Hexagon::ASLH_cdnNotPt_V4:
- case Hexagon::ASRH_cdnPt_V4:
- case Hexagon::ASRH_cdnNotPt_V4:
- case Hexagon::SXTB_cdnPt_V4:
- case Hexagon::SXTB_cdnNotPt_V4:
- case Hexagon::SXTH_cdnPt_V4:
- case Hexagon::SXTH_cdnNotPt_V4:
- case Hexagon::ZXTB_cdnPt_V4:
- case Hexagon::ZXTB_cdnNotPt_V4:
- case Hexagon::ZXTH_cdnPt_V4:
- case Hexagon::ZXTH_cdnNotPt_V4:
-
- // Conditional stores
- case Hexagon::STrib_imm_cdnPt_V4 :
- case Hexagon::STrib_imm_cdnNotPt_V4 :
- case Hexagon::STrib_cdnPt_V4 :
- case Hexagon::STrib_cdnNotPt_V4 :
- case Hexagon::STrib_indexed_cdnPt_V4 :
- case Hexagon::STrib_indexed_cdnNotPt_V4 :
- case Hexagon::POST_STbri_cdnPt_V4 :
- case Hexagon::POST_STbri_cdnNotPt_V4 :
- case Hexagon::STrib_indexed_shl_cdnPt_V4 :
- case Hexagon::STrib_indexed_shl_cdnNotPt_V4 :
-
- // Store doubleword conditionally
- case Hexagon::STrid_indexed_cdnPt_V4 :
- case Hexagon::STrid_indexed_cdnNotPt_V4 :
- case Hexagon::STrid_indexed_shl_cdnPt_V4 :
- case Hexagon::STrid_indexed_shl_cdnNotPt_V4 :
- case Hexagon::POST_STdri_cdnPt_V4 :
- case Hexagon::POST_STdri_cdnNotPt_V4 :
-
- // Store halfword conditionally
- case Hexagon::STrih_cdnPt_V4 :
- case Hexagon::STrih_cdnNotPt_V4 :
- case Hexagon::STrih_indexed_cdnPt_V4 :
- case Hexagon::STrih_indexed_cdnNotPt_V4 :
- case Hexagon::STrih_imm_cdnPt_V4 :
- case Hexagon::STrih_imm_cdnNotPt_V4 :
- case Hexagon::STrih_indexed_shl_cdnPt_V4 :
- case Hexagon::STrih_indexed_shl_cdnNotPt_V4 :
- case Hexagon::POST_SThri_cdnPt_V4 :
- case Hexagon::POST_SThri_cdnNotPt_V4 :
-
- // Store word conditionally
- case Hexagon::STriw_cdnPt_V4 :
- case Hexagon::STriw_cdnNotPt_V4 :
- case Hexagon::STriw_indexed_cdnPt_V4 :
- case Hexagon::STriw_indexed_cdnNotPt_V4 :
- case Hexagon::STriw_imm_cdnPt_V4 :
- case Hexagon::STriw_imm_cdnNotPt_V4 :
- case Hexagon::STriw_indexed_shl_cdnPt_V4 :
- case Hexagon::STriw_indexed_shl_cdnNotPt_V4 :
- case Hexagon::POST_STwri_cdnPt_V4 :
- case Hexagon::POST_STwri_cdnNotPt_V4 :
-
- case Hexagon::LDd_GP_cdnPt_V4:
- case Hexagon::LDd_GP_cdnNotPt_V4:
- case Hexagon::LDb_GP_cdnPt_V4:
- case Hexagon::LDb_GP_cdnNotPt_V4:
- case Hexagon::LDub_GP_cdnPt_V4:
- case Hexagon::LDub_GP_cdnNotPt_V4:
- case Hexagon::LDh_GP_cdnPt_V4:
- case Hexagon::LDh_GP_cdnNotPt_V4:
- case Hexagon::LDuh_GP_cdnPt_V4:
- case Hexagon::LDuh_GP_cdnNotPt_V4:
- case Hexagon::LDw_GP_cdnPt_V4:
- case Hexagon::LDw_GP_cdnNotPt_V4:
-
- case Hexagon::STd_GP_cdnPt_V4:
- case Hexagon::STd_GP_cdnNotPt_V4:
- case Hexagon::STb_GP_cdnPt_V4:
- case Hexagon::STb_GP_cdnNotPt_V4:
- case Hexagon::STh_GP_cdnPt_V4:
- case Hexagon::STh_GP_cdnNotPt_V4:
- case Hexagon::STw_GP_cdnPt_V4:
- case Hexagon::STw_GP_cdnNotPt_V4:
- return true;
- }
- return false;
-}
-
static MachineOperand& GetPostIncrementOperand(MachineInstr *MI,
const HexagonInstrInfo *QII) {
assert(QII->isPostIncrement(MI) && "Not a post increment operation.");
@@ -2490,7 +2358,7 @@ bool HexagonPacketizerList::CanPromoteToNewValueStore( MachineInstr *MI,
// sense, i.e, either both should be negated or both should be none negated.
if (( predRegNumDst != predRegNumSrc) ||
- isDotNewInst(PacketMI) != isDotNewInst(MI) ||
+ QII->isDotNewInst(PacketMI) != QII->isDotNewInst(MI) ||
GetPredicateSense(MI, QII) != GetPredicateSense(PacketMI, QII)) {
return false;
}
@@ -2600,8 +2468,9 @@ bool HexagonPacketizerList::CanPromoteToDotNew( MachineInstr *MI,
MachineBasicBlock::iterator &MII,
const TargetRegisterClass* RC )
{
- // already a dot new instruction
- if (isDotNewInst(MI) && !IsNewifyStore(MI))
+ const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
+ // Already a dot new instruction.
+ if (QII->isDotNewInst(MI) && !IsNewifyStore(MI))
return false;
if (!isNewifiable(MI))
@@ -2616,7 +2485,6 @@ bool HexagonPacketizerList::CanPromoteToDotNew( MachineInstr *MI,
else {
// Create a dot new machine instruction to see if resources can be
// allocated. If not, bail out now.
- const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
int NewOpcode = GetDotNewOp(MI->getOpcode());
const MCInstrDesc &desc = QII->get(NewOpcode);
DebugLoc dl;
@@ -2759,7 +2627,7 @@ bool HexagonPacketizerList::ArePredicatesComplements (MachineInstr* MI1,
// !p0 is not complimentary to p0.new
return ((MI1->getOperand(1).getReg() == MI2->getOperand(1).getReg()) &&
(GetPredicateSense(MI1, QII) != GetPredicateSense(MI2, QII)) &&
- (isDotNewInst(MI1) == isDotNewInst(MI2)));
+ (QII->isDotNewInst(MI1) == QII->isDotNewInst(MI2)));
}
// initPacketizerState - Initialize packetizer flags
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
index 86f75d1..3deb8d1 100644
--- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
@@ -31,6 +31,7 @@ HexagonMCAsmInfo::HexagonMCAsmInfo(const Target &T, StringRef TT) {
AscizDirective = "\t.string\t";
WeakRefDirective = "\t.weak\t";
+ SupportsDebugInformation = true;
UsesELFSectionDirectiveForBSS = true;
ExceptionsType = ExceptionHandling::DwarfCFI;
}