mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Hexagon: Use multiclass for Jump instructions.
llvm-svn: 180885
This commit is contained in:
parent
d290020e45
commit
a3587dd6bb
@ -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"]];
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -1119,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);
|
||||
|
@ -1353,7 +1353,6 @@ HexagonTargetLowering::HexagonTargetLowering(HexagonTargetMachine
|
||||
|
||||
}
|
||||
|
||||
setOperationAction(ISD::BRIND, MVT::Other, Expand);
|
||||
if (EmitJumpTables) {
|
||||
setOperationAction(ISD::BR_JT, MVT::Other, Custom);
|
||||
} else {
|
||||
@ -1435,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);
|
||||
@ -1490,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";
|
||||
}
|
||||
}
|
||||
|
||||
@ -1510,11 +1510,39 @@ bool HexagonTargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
|
||||
return ((VT1.getSimpleVT() == MVT::i64) && (VT2.getSimpleVT() == MVT::i32));
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
int SecLastOpcode = SecondLastInst->getOpcode();
|
||||
|
||||
// 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) {
|
||||
bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);
|
||||
bool SecLastOpcodeHasNot = PredOpcodeHasNot(SecLastOpcode);
|
||||
if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::JMP)) {
|
||||
TBB = SecondLastInst->getOperand(1).getMBB();
|
||||
Cond.push_back(SecondLastInst->getOperand(0));
|
||||
FBB = LastInst->getOperand(0).getMBB();
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the block ends with Hexagon::JMP_cNot and Hexagon:JMP, handle it.
|
||||
if ((SecondLastInst->getOpcode() == Hexagon::JMP_cNot) &&
|
||||
LastInst->getOpcode() == Hexagon::JMP) {
|
||||
TBB = SecondLastInst->getOperand(1).getMBB();
|
||||
Cond.push_back(MachineOperand::CreateImm(0));
|
||||
if (SecLastOpcodeHasNot)
|
||||
Cond.push_back(MachineOperand::CreateImm(0));
|
||||
Cond.push_back(SecondLastInst->getOperand(0));
|
||||
FBB = LastInst->getOperand(0).getMBB();
|
||||
return false;
|
||||
@ -263,8 +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;
|
||||
@ -984,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;
|
||||
@ -1023,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;
|
||||
@ -1094,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:
|
||||
@ -1480,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;
|
||||
@ -1511,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:
|
||||
@ -2555,3 +2576,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);
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "HexagonRegisterInfo.h"
|
||||
#include "MCTargetDesc/HexagonBaseInfo.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetFrameLowering.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
|
||||
@ -28,6 +29,8 @@ namespace llvm {
|
||||
class HexagonInstrInfo : public HexagonGenInstrInfo {
|
||||
const HexagonRegisterInfo RI;
|
||||
const HexagonSubtarget& Subtarget;
|
||||
typedef unsigned Opcode_t;
|
||||
|
||||
public:
|
||||
explicit HexagonInstrInfo(HexagonSubtarget &ST);
|
||||
|
||||
@ -197,6 +200,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;
|
||||
|
||||
|
@ -737,113 +737,154 @@ def XOR_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, PredRegs:$src2),
|
||||
// CR -
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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)]>;
|
||||
}
|
||||
|
||||
// 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)]>;
|
||||
}
|
||||
|
||||
// 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 isTerminator = 1, isBranch = 1, neverHasSideEffects = 1, Defs = [PC],
|
||||
isPredicated = 1 in {
|
||||
def BRCOND : JInst < (outs), (ins PredRegs:$pred, brtarget:$dst),
|
||||
"if ($pred) jump $dst",
|
||||
[]>;
|
||||
}
|
||||
|
||||
// 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",
|
||||
[]>;
|
||||
}
|
||||
|
||||
// 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",
|
||||
[]>;
|
||||
}
|
||||
|
||||
// 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",
|
||||
[]>;
|
||||
}
|
||||
|
||||
// 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",
|
||||
[]>;
|
||||
}
|
||||
//===----------------------------------------------------------------------===//
|
||||
// J -
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// JR +
|
||||
//===----------------------------------------------------------------------===//
|
||||
def retflag : SDNode<"HexagonISD::RET_FLAG", SDTNone,
|
||||
[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
|
||||
def eh_return: SDNode<"HexagonISD::EH_RETURN", SDTNone,
|
||||
[SDNPHasChain]>;
|
||||
|
||||
// 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)]>;
|
||||
def SDHexagonBR_JT: SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
|
||||
def HexagonBR_JT: SDNode<"HexagonISD::BR_JT", SDHexagonBR_JT, [SDNPHasChain]>;
|
||||
|
||||
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};
|
||||
}
|
||||
|
||||
// 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 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};
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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",
|
||||
[]>;
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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>;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
multiclass JMPR_base<string BaseOp> {
|
||||
let BaseOpcode = BaseOp in {
|
||||
def NAME : T_JMPr;
|
||||
defm _t : JMPR_Pred<0>;
|
||||
defm _f : JMPR_Pred<1>;
|
||||
}
|
||||
}
|
||||
|
||||
let isTerminator = 1, neverHasSideEffects = 1 in {
|
||||
let isBranch = 1 in
|
||||
defm JMP : JMP_base<"JMP">, PredNewRel;
|
||||
|
||||
let isBranch = 1, isIndirectBranch = 1 in
|
||||
defm JMPR : JMPR_base<"JMPr">, PredNewRel;
|
||||
|
||||
let isReturn = 1, isCodeGenOnly = 1 in
|
||||
defm JMPret : JMPR_base<"JMPret">, PredNewRel;
|
||||
}
|
||||
|
||||
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 -
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -1986,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", []>;
|
||||
|
||||
// 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)>;
|
||||
}
|
||||
|
||||
let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1 in {
|
||||
def TCRETURNR : JInst<(outs), (ins IntRegs:$dst),
|
||||
"jumpr $dst // TAILCALL", []>;
|
||||
}
|
||||
// Map call instruction.
|
||||
def : Pat<(call (i32 IntRegs:$dst)),
|
||||
(CALLR (i32 IntRegs:$dst))>, Requires<[HasV2TOnly]>;
|
||||
@ -2124,7 +2163,7 @@ def : Pat <(select (not (i1 PredRegs:$src1)), IntRegs:$src2, s12ImmPred:$src3),
|
||||
|
||||
// Map from p0 = pnot(p0); if (p0) jump => if (!p0) jump.
|
||||
def : Pat <(brcond (not (i1 PredRegs:$src1)), bb:$offset),
|
||||
(JMP_cNot (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 (i1 PredRegs:$src1), (not (i1 PredRegs:$src2))),
|
||||
@ -2157,46 +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 (CMPGTri (i32 IntRegs:$src1),
|
||||
(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 (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)), 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.
|
||||
@ -2645,19 +2684,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),
|
||||
|
@ -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 -
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -2145,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]>;
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -373,12 +373,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;
|
||||
@ -414,9 +414,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;
|
||||
|
@ -857,17 +857,17 @@ 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_t:
|
||||
return Hexagon::JMP_f;
|
||||
|
||||
case Hexagon::JMP_cNot:
|
||||
return Hexagon::JMP_cdnNotPt;
|
||||
case Hexagon::JMP_f:
|
||||
return Hexagon::JMP_fnew_t;
|
||||
|
||||
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:
|
||||
@ -1306,17 +1306,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
|
||||
|
||||
@ -1912,7 +1912,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 :
|
||||
@ -2051,7 +2051,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 :
|
||||
|
Loading…
Reference in New Issue
Block a user