[Hexagon] Adding encodings for JR class instructions. Updating complier usages.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223967 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Colin LeMahieu
2014-12-10 21:24:10 +00:00
parent c0e334099c
commit f6492bc6b2
10 changed files with 188 additions and 185 deletions

View File

@ -59,13 +59,13 @@ private:
char HexagonCFGOptimizer::ID = 0; char HexagonCFGOptimizer::ID = 0;
static bool IsConditionalBranch(int Opc) { static bool IsConditionalBranch(int Opc) {
return (Opc == Hexagon::JMP_t) || (Opc == Hexagon::JMP_f) return (Opc == Hexagon::J2_jumpt) || (Opc == Hexagon::J2_jumpf)
|| (Opc == Hexagon::JMP_tnew_t) || (Opc == Hexagon::JMP_fnew_t); || (Opc == Hexagon::J2_jumptnewpt) || (Opc == Hexagon::J2_jumpfnewpt);
} }
static bool IsUnconditionalJump(int Opc) { static bool IsUnconditionalJump(int Opc) {
return (Opc == Hexagon::JMP); return (Opc == Hexagon::J2_jump);
} }
@ -75,20 +75,20 @@ HexagonCFGOptimizer::InvertAndChangeJumpTarget(MachineInstr* MI,
const HexagonInstrInfo *QII = QTM.getSubtargetImpl()->getInstrInfo(); const HexagonInstrInfo *QII = QTM.getSubtargetImpl()->getInstrInfo();
int NewOpcode = 0; int NewOpcode = 0;
switch(MI->getOpcode()) { switch(MI->getOpcode()) {
case Hexagon::JMP_t: case Hexagon::J2_jumpt:
NewOpcode = Hexagon::JMP_f; NewOpcode = Hexagon::J2_jumpf;
break; break;
case Hexagon::JMP_f: case Hexagon::J2_jumpf:
NewOpcode = Hexagon::JMP_t; NewOpcode = Hexagon::J2_jumpt;
break; break;
case Hexagon::JMP_tnew_t: case Hexagon::J2_jumptnewpt:
NewOpcode = Hexagon::JMP_fnew_t; NewOpcode = Hexagon::J2_jumpfnewpt;
break; break;
case Hexagon::JMP_fnew_t: case Hexagon::J2_jumpfnewpt:
NewOpcode = Hexagon::JMP_tnew_t; NewOpcode = Hexagon::J2_jumptnewpt;
break; break;
default: default:
@ -163,8 +163,8 @@ bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {
// The target of the unconditional branch must be JumpAroundTarget. // The target of the unconditional branch must be JumpAroundTarget.
// TODO: If not, we should not invert the unconditional branch. // TODO: If not, we should not invert the unconditional branch.
MachineBasicBlock* CondBranchTarget = nullptr; MachineBasicBlock* CondBranchTarget = nullptr;
if ((MI->getOpcode() == Hexagon::JMP_t) || if ((MI->getOpcode() == Hexagon::J2_jumpt) ||
(MI->getOpcode() == Hexagon::JMP_f)) { (MI->getOpcode() == Hexagon::J2_jumpf)) {
CondBranchTarget = MI->getOperand(1).getMBB(); CondBranchTarget = MI->getOperand(1).getMBB();
} }

View File

@ -1122,8 +1122,8 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L) {
// The loop ends with either: // The loop ends with either:
// - a conditional branch followed by an unconditional branch, or // - a conditional branch followed by an unconditional branch, or
// - a conditional branch to the loop start. // - a conditional branch to the loop start.
if (LastI->getOpcode() == Hexagon::JMP_t || if (LastI->getOpcode() == Hexagon::J2_jumpt ||
LastI->getOpcode() == Hexagon::JMP_f) { LastI->getOpcode() == Hexagon::J2_jumpf) {
// Delete one and change/add an uncond. branch to out of the loop. // Delete one and change/add an uncond. branch to out of the loop.
MachineBasicBlock *BranchTarget = LastI->getOperand(1).getMBB(); MachineBasicBlock *BranchTarget = LastI->getOperand(1).getMBB();
LastI = LastMBB->erase(LastI); LastI = LastMBB->erase(LastI);

View File

@ -186,7 +186,7 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern,
string InputType = ""; // Input is "imm" or "reg" type. string InputType = ""; // Input is "imm" or "reg" type.
string isMEMri = "false"; // Set to "true" for load/store with MEMri operand. string isMEMri = "false"; // Set to "true" for load/store with MEMri operand.
string isFloat = "false"; // Set to "true" for the floating-point load/store. string isFloat = "false"; // Set to "true" for the floating-point load/store.
string isBrTaken = ""; // Set to "true"/"false" for jump instructions string isBrTaken = !if(isTaken, "true", "false"); // Set to "true"/"false" for jump instructions
let PredSense = !if(isPredicated, !if(isPredicatedFalse, "false", "true"), let PredSense = !if(isPredicated, !if(isPredicatedFalse, "false", "true"),
""); "");

View File

@ -124,8 +124,8 @@ HexagonInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
const SmallVectorImpl<MachineOperand> &Cond, const SmallVectorImpl<MachineOperand> &Cond,
DebugLoc DL) const{ DebugLoc DL) const{
int BOpc = Hexagon::JMP; int BOpc = Hexagon::J2_jump;
int BccOpc = Hexagon::JMP_t; int BccOpc = Hexagon::J2_jumpt;
assert(TBB && "InsertBranch must not be told to insert a fallthrough"); assert(TBB && "InsertBranch must not be told to insert a fallthrough");
@ -134,7 +134,7 @@ HexagonInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
// If we want to reverse the branch an odd number of times, we want // If we want to reverse the branch an odd number of times, we want
// JMP_f. // JMP_f.
if (!Cond.empty() && Cond[0].isImm() && Cond[0].getImm() == 0) { if (!Cond.empty() && Cond[0].isImm() && Cond[0].getImm() == 0) {
BccOpc = Hexagon::JMP_f; BccOpc = Hexagon::J2_jumpf;
regPos = 1; regPos = 1;
} }
@ -213,7 +213,7 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
} }
// Delete the JMP if it's equivalent to a fall-through. // Delete the JMP if it's equivalent to a fall-through.
if (AllowModify && I->getOpcode() == Hexagon::JMP && if (AllowModify && I->getOpcode() == Hexagon::J2_jump &&
MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) { MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
DEBUG(dbgs()<< "\nErasing the jump to successor block\n";); DEBUG(dbgs()<< "\nErasing the jump to successor block\n";);
I->eraseFromParent(); I->eraseFromParent();
@ -249,7 +249,7 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
// If there is only one terminator instruction, process it. // If there is only one terminator instruction, process it.
if (LastInst && !SecondLastInst) { if (LastInst && !SecondLastInst) {
if (LastOpcode == Hexagon::JMP) { if (LastOpcode == Hexagon::J2_jump) {
TBB = LastInst->getOperand(0).getMBB(); TBB = LastInst->getOperand(0).getMBB();
return false; return false;
} }
@ -274,7 +274,7 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode); bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);
bool SecLastOpcodeHasNot = PredOpcodeHasNot(SecLastOpcode); bool SecLastOpcodeHasNot = PredOpcodeHasNot(SecLastOpcode);
if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::JMP)) { if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::J2_jump)) {
TBB = SecondLastInst->getOperand(1).getMBB(); TBB = SecondLastInst->getOperand(1).getMBB();
if (SecLastOpcodeHasNot) if (SecLastOpcodeHasNot)
Cond.push_back(MachineOperand::CreateImm(0)); Cond.push_back(MachineOperand::CreateImm(0));
@ -285,7 +285,7 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
// If the block ends with two Hexagon:JMPs, handle it. The second one is not // If the block ends with two Hexagon:JMPs, handle it. The second one is not
// executed, so remove it. // executed, so remove it.
if (SecLastOpcode == Hexagon::JMP && LastOpcode == Hexagon::JMP) { if (SecLastOpcode == Hexagon::J2_jump && LastOpcode == Hexagon::J2_jump) {
TBB = SecondLastInst->getOperand(0).getMBB(); TBB = SecondLastInst->getOperand(0).getMBB();
I = LastInst; I = LastInst;
if (AllowModify) if (AllowModify)
@ -295,7 +295,7 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
// If the block ends with an ENDLOOP, and JMP, handle it. // If the block ends with an ENDLOOP, and JMP, handle it.
if (SecLastOpcode == Hexagon::ENDLOOP0 && if (SecLastOpcode == Hexagon::ENDLOOP0 &&
LastOpcode == Hexagon::JMP) { LastOpcode == Hexagon::J2_jump) {
TBB = SecondLastInst->getOperand(0).getMBB(); TBB = SecondLastInst->getOperand(0).getMBB();
Cond.push_back(SecondLastInst->getOperand(0)); Cond.push_back(SecondLastInst->getOperand(0));
FBB = LastInst->getOperand(0).getMBB(); FBB = LastInst->getOperand(0).getMBB();
@ -308,9 +308,9 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
unsigned HexagonInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { unsigned HexagonInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
int BOpc = Hexagon::JMP; int BOpc = Hexagon::J2_jump;
int BccOpc = Hexagon::JMP_t; int BccOpc = Hexagon::J2_jumpt;
int BccOpcNot = Hexagon::JMP_f; int BccOpcNot = Hexagon::J2_jumpf;
MachineBasicBlock::iterator I = MBB.end(); MachineBasicBlock::iterator I = MBB.end();
if (I == MBB.begin()) return 0; if (I == MBB.begin()) return 0;
@ -1609,21 +1609,21 @@ int HexagonInstrInfo::GetDotNewPredOp(MachineInstr *MI,
switch (MI->getOpcode()) { switch (MI->getOpcode()) {
default: llvm_unreachable("Unknown .new type"); default: llvm_unreachable("Unknown .new type");
// Condtional Jumps // Condtional Jumps
case Hexagon::JMP_t: case Hexagon::J2_jumpt:
case Hexagon::JMP_f: case Hexagon::J2_jumpf:
return getDotNewPredJumpOp(MI, MBPI); return getDotNewPredJumpOp(MI, MBPI);
case Hexagon::JMPR_t: case Hexagon::J2_jumprt:
return Hexagon::JMPR_tnew_tV3; return Hexagon::J2_jumptnewpt;
case Hexagon::JMPR_f: case Hexagon::J2_jumprf:
return Hexagon::JMPR_fnew_tV3; return Hexagon::J2_jumprfnewpt;
case Hexagon::JMPret_t: case Hexagon::JMPrett:
return Hexagon::JMPret_tnew_tV3; return Hexagon::J2_jumprtnewpt;
case Hexagon::JMPret_f: case Hexagon::JMPretf:
return Hexagon::JMPret_fnew_tV3; return Hexagon::J2_jumprfnewpt;
// Conditional combine // Conditional combine
@ -1747,10 +1747,10 @@ HexagonInstrInfo::getDotNewPredJumpOp(MachineInstr *MI,
taken = true; taken = true;
switch (MI->getOpcode()) { switch (MI->getOpcode()) {
case Hexagon::JMP_t: case Hexagon::J2_jumpt:
return taken ? Hexagon::JMP_tnew_t : Hexagon::JMP_tnew_nt; return taken ? Hexagon::J2_jumptnewpt : Hexagon::J2_jumptnew;
case Hexagon::JMP_f: case Hexagon::J2_jumpf:
return taken ? Hexagon::JMP_fnew_t : Hexagon::JMP_fnew_nt; return taken ? Hexagon::J2_jumpfnewpt : Hexagon::J2_jumpfnew;
default: default:
llvm_unreachable("Unexpected jump instruction."); llvm_unreachable("Unexpected jump instruction.");
@ -1862,16 +1862,16 @@ short HexagonInstrInfo::getNonExtOpcode (const MachineInstr *MI) const {
} }
bool HexagonInstrInfo::PredOpcodeHasJMP_c(Opcode_t Opcode) const { bool HexagonInstrInfo::PredOpcodeHasJMP_c(Opcode_t Opcode) const {
return (Opcode == Hexagon::JMP_t) || return (Opcode == Hexagon::J2_jumpt) ||
(Opcode == Hexagon::JMP_f) || (Opcode == Hexagon::J2_jumpf) ||
(Opcode == Hexagon::JMP_tnew_t) || (Opcode == Hexagon::J2_jumptnewpt) ||
(Opcode == Hexagon::JMP_fnew_t) || (Opcode == Hexagon::J2_jumpfnewpt) ||
(Opcode == Hexagon::JMP_tnew_nt) || (Opcode == Hexagon::J2_jumpt) ||
(Opcode == Hexagon::JMP_fnew_nt); (Opcode == Hexagon::J2_jumpf);
} }
bool HexagonInstrInfo::PredOpcodeHasNot(Opcode_t Opcode) const { bool HexagonInstrInfo::PredOpcodeHasNot(Opcode_t Opcode) const {
return (Opcode == Hexagon::JMP_f) || return (Opcode == Hexagon::J2_jumpf) ||
(Opcode == Hexagon::JMP_fnew_t) || (Opcode == Hexagon::J2_jumpfnewpt) ||
(Opcode == Hexagon::JMP_fnew_nt); (Opcode == Hexagon::J2_jumpfnew);
} }

View File

@ -1264,22 +1264,33 @@ def VSPLICE_rrp : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
// CR - // CR -
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// JR +
//===----------------------------------------------------------------------===//
def retflag : SDNode<"HexagonISD::RET_FLAG", SDTNone, def retflag : SDNode<"HexagonISD::RET_FLAG", SDTNone,
[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
def eh_return: SDNode<"HexagonISD::EH_RETURN", SDTNone, def eh_return: SDNode<"HexagonISD::EH_RETURN", SDTNone, [SDNPHasChain]>;
[SDNPHasChain]>;
def SDHexagonBR_JT: SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; def SDHexagonBR_JT: SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
def HexagonBR_JT: SDNode<"HexagonISD::BR_JT", SDHexagonBR_JT, [SDNPHasChain]>; def HexagonBR_JT: SDNode<"HexagonISD::BR_JT", SDHexagonBR_JT, [SDNPHasChain]>;
let InputType = "imm", isBarrier = 1, isPredicable = 1, class CondStr<string CReg, bit True, bit New> {
Defs = [PC], isExtendable = 1, opExtendable = 0, isExtentSigned = 1, string S = "if (" # !if(True,"","!") # CReg # !if(New,".new","") # ") ";
opExtentBits = 24, isCodeGenOnly = 0 in }
class T_JMP <dag InsDag, list<dag> JumpList = []> class JumpOpcStr<string Mnemonic, bit New, bit Taken> {
: JInst<(outs), InsDag, string S = Mnemonic # !if(New, !if(Taken,":t",":nt"), "");
"jump $dst" , JumpList> { }
bits<24> dst;
let isBranch = 1, isBarrier = 1, Defs = [PC], hasSideEffects = 0,
isPredicable = 1,
isExtendable = 1, opExtendable = 0, isExtentSigned = 1,
opExtentBits = 24, opExtentAlign = 2, InputType = "imm" in
class T_JMP<string ExtStr>
: JInst<(outs), (ins brtarget:$dst),
"jump " # ExtStr # "$dst",
[], "", J_tc_2early_SLOT23> {
bits<24> dst;
let IClass = 0b0101; let IClass = 0b0101;
let Inst{27-25} = 0b100; let Inst{27-25} = 0b100;
@ -1287,16 +1298,16 @@ class T_JMP <dag InsDag, list<dag> JumpList = []>
let Inst{13-1} = dst{14-2}; let Inst{13-1} = dst{14-2};
} }
let InputType = "imm", isExtendable = 1, opExtendable = 1, isExtentSigned = 1, let isBranch = 1, Defs = [PC], hasSideEffects = 0, isPredicated = 1,
Defs = [PC], isPredicated = 1, opExtentBits = 17 in isExtendable = 1, opExtendable = 1, isExtentSigned = 1,
class T_JMP_c <bit PredNot, bit isPredNew, bit isTak>: opExtentBits = 17, opExtentAlign = 2, InputType = "imm" in
JInst<(outs ), (ins PredRegs:$src, brtarget:$dst), class T_JMP_c<bit PredNot, bit isPredNew, bit isTak, string ExtStr>
!if(PredNot, "if (!$src", "if ($src")# : JInst<(outs), (ins PredRegs:$src, brtarget:$dst),
!if(isPredNew, ".new) ", ") ")#"jump"# CondStr<"$src", !if(PredNot,0,1), isPredNew>.S #
!if(isPredNew, !if(isTak, ":t ", ":nt "), " ")#"$dst"> { JumpOpcStr<"jump", isPredNew, isTak>.S # " " #
ExtStr # "$dst",
[], "", J_tc_2early_SLOT23>, ImmRegRel {
let isTaken = isTak; let isTaken = isTak;
let isBrTaken = !if(isPredNew, !if(isTaken, "true", "false"), "");
let isPredicatedFalse = PredNot; let isPredicatedFalse = PredNot;
let isPredicatedNew = isPredNew; let isPredicatedNew = isPredNew;
bits<2> src; bits<2> src;
@ -1315,11 +1326,28 @@ class T_JMP_c <bit PredNot, bit isPredNew, bit isTak>:
let Inst{7-1} = dst{8-2}; let Inst{7-1} = dst{8-2};
} }
let isBarrier = 1, Defs = [PC], isPredicable = 1, InputType = "reg" in multiclass JMP_Pred<bit PredNot, string ExtStr> {
class T_JMPr<dag InsDag = (ins IntRegs:$dst)> def NAME : T_JMP_c<PredNot, 0, 0, ExtStr>;
: JRInst<(outs ), InsDag, // Predicate new
"jumpr $dst" , def NAME#newpt : T_JMP_c<PredNot, 1, 1, ExtStr>; // taken
[]> { def NAME#new : T_JMP_c<PredNot, 1, 0, ExtStr>; // not taken
}
multiclass JMP_base<string BaseOp, string ExtStr> {
let BaseOpcode = BaseOp in {
def NAME : T_JMP<ExtStr>;
defm t : JMP_Pred<0, ExtStr>;
defm f : JMP_Pred<1, ExtStr>;
}
}
// Jumps to address stored in a register, JUMPR_MISC
// if ([[!]P[.new]]) jumpr[:t/nt] Rs
let isBranch = 1, isIndirectBranch = 1, isBarrier = 1, Defs = [PC],
isPredicable = 1, hasSideEffects = 0, InputType = "reg" in
class T_JMPr
: JRInst<(outs), (ins IntRegs:$dst),
"jumpr $dst", [], "", J_tc_2early_SLOT2> {
bits<5> dst; bits<5> dst;
let IClass = 0b0101; let IClass = 0b0101;
@ -1327,15 +1355,15 @@ class T_JMPr<dag InsDag = (ins IntRegs:$dst)>
let Inst{20-16} = dst; let Inst{20-16} = dst;
} }
let Defs = [PC], isPredicated = 1, InputType = "reg" in let isBranch = 1, isIndirectBranch = 1, Defs = [PC], isPredicated = 1,
class T_JMPr_c <bit PredNot, bit isPredNew, bit isTak>: hasSideEffects = 0, InputType = "reg" in
JRInst <(outs ), (ins PredRegs:$src, IntRegs:$dst), class T_JMPr_c <bit PredNot, bit isPredNew, bit isTak>
!if(PredNot, "if (!$src", "if ($src")# : JRInst <(outs), (ins PredRegs:$src, IntRegs:$dst),
!if(isPredNew, ".new) ", ") ")#"jumpr"# CondStr<"$src", !if(PredNot,0,1), isPredNew>.S #
!if(isPredNew, !if(isTak, ":t ", ":nt "), " ")#"$dst"> { JumpOpcStr<"jumpr", isPredNew, isTak>.S # " $dst", [],
"", J_tc_2early_SLOT2> {
let isTaken = isTak; let isTaken = isTak;
let isBrTaken = !if(isPredNew, !if(isTaken, "true", "false"), "");
let isPredicatedFalse = PredNot; let isPredicatedFalse = PredNot;
let isPredicatedNew = isPredNew; let isPredicatedNew = isPredNew;
bits<2> src; bits<2> src;
@ -1349,37 +1377,20 @@ class T_JMPr_c <bit PredNot, bit isPredNew, bit isTak>:
let Inst{12} = !if(isPredNew, isTak, zero); let Inst{12} = !if(isPredNew, isTak, zero);
let Inst{11} = isPredNew; let Inst{11} = isPredNew;
let Inst{9-8} = src; 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> { multiclass JMPR_Pred<bit PredNot> {
def NAME: T_JMPr_c<PredNot, 0, 0>; def NAME: T_JMPr_c<PredNot, 0, 0>;
// Predicate new // Predicate new
def NAME#new_tV3 : T_JMPr_c<PredNot, 1, 1>; // taken def NAME#newpt : T_JMPr_c<PredNot, 1, 1>; // taken
def NAME#new_ntV3 : T_JMPr_c<PredNot, 1, 0>; // not taken def NAME#new : T_JMPr_c<PredNot, 1, 0>; // not taken
} }
multiclass JMPR_base<string BaseOp> { multiclass JMPR_base<string BaseOp> {
let BaseOpcode = BaseOp in { let BaseOpcode = BaseOp in {
def NAME : T_JMPr; def NAME : T_JMPr;
defm _t : JMPR_Pred<0>; defm t : JMPR_Pred<0>;
defm _f : JMPR_Pred<1>; defm f : JMPR_Pred<1>;
} }
} }
@ -1411,36 +1422,40 @@ let Defs = VolatileV3.Regs, isCodeGenOnly = 0 in {
def J2_callrf : JUMPR_MISC_CALLR<1, 1, (ins PredRegs:$Pu, IntRegs:$Rs)>; def J2_callrf : JUMPR_MISC_CALLR<1, 1, (ins PredRegs:$Pu, IntRegs:$Rs)>;
} }
let isTerminator = 1, hasSideEffects = 0 in { let isTerminator = 1, hasSideEffects = 0, isCodeGenOnly = 0 in {
let isBranch = 1 in defm J2_jump : JMP_base<"JMP", "">, PredNewRel;
defm JMP : JMP_base<"JMP">, PredNewRel;
let isBranch = 1, isIndirectBranch = 1 in // Deal with explicit assembly
defm JMPR : JMPR_base<"JMPr">, PredNewRel; // - never extened a jump #, always extend a jump ##
let isAsmParserOnly = 1 in {
defm J2_jump_ext : JMP_base<"JMP", "##">;
defm J2_jump_noext : JMP_base<"JMP", "#">;
}
let isReturn = 1, isCodeGenOnly = 1 in defm J2_jumpr : JMPR_base<"JMPr">, PredNewRel;
defm JMPret : JMPR_base<"JMPret">, PredNewRel;
let isReturn = 1, isCodeGenOnly = 1 in
defm JMPret : JMPR_base<"JMPret">, PredNewRel;
} }
def : Pat<(retflag), def: Pat<(br bb:$dst),
(JMPret (i32 R31))>; (J2_jump brtarget:$dst)>;
def: Pat<(retflag),
def : Pat <(brcond (i1 PredRegs:$src1), bb:$offset), (JMPret (i32 R31))>;
(JMP_t (i1 PredRegs:$src1), bb:$offset)>; def: Pat<(brcond (i1 PredRegs:$src1), bb:$offset),
(J2_jumpt PredRegs:$src1, bb:$offset)>;
// A return through builtin_eh_return. // A return through builtin_eh_return.
let isReturn = 1, isTerminator = 1, isBarrier = 1, hasSideEffects = 0, let isReturn = 1, isTerminator = 1, isBarrier = 1, hasSideEffects = 0,
isCodeGenOnly = 1, Defs = [PC], Uses = [R28], isPredicable = 0 in isCodeGenOnly = 1, Defs = [PC], Uses = [R28], isPredicable = 0 in
def EH_RETURN_JMPR : T_JMPr; def EH_RETURN_JMPR : T_JMPr;
def : Pat<(eh_return), def: Pat<(eh_return),
(EH_RETURN_JMPR (i32 R31))>; (EH_RETURN_JMPR (i32 R31))>;
def: Pat<(HexagonBR_JT (i32 IntRegs:$dst)),
def : Pat<(HexagonBR_JT (i32 IntRegs:$dst)), (J2_jumpr IntRegs:$dst)>;
(JMPR (i32 IntRegs:$dst))>; def: Pat<(brind (i32 IntRegs:$dst)),
(J2_jumpr IntRegs:$dst)>;
def : Pat<(brind (i32 IntRegs:$dst)),
(JMPR (i32 IntRegs:$dst))>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// JR - // JR -
@ -2639,15 +2654,9 @@ let isCall = 1, hasSideEffects = 0,
"call $dst", []>; "call $dst", []>;
} }
// Call subroutine from register. // Call subroutine indirectly.
let isCall = 1, hasSideEffects = 0, let Defs = VolatileV3.Regs, isCodeGenOnly = 0 in
Defs = [D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, def J2_callr : JUMPR_MISC_CALLR<0, 1>;
R22, R23, R28, R31, P0, P1, P2, P3, LC0, LC1, SA0, SA1] in {
def CALLR : JRInst<(outs), (ins IntRegs:$dst),
"callr $dst",
[]>;
}
// Indirect tail-call. // Indirect tail-call.
let isCodeGenOnly = 1, isCall = 1, isReturn = 1 in let isCodeGenOnly = 1, isCall = 1, isReturn = 1 in
@ -2656,13 +2665,15 @@ def TCRETURNR : T_JMPr;
// Direct tail-calls. // Direct tail-calls.
let isCall = 1, isReturn = 1, isBarrier = 1, isPredicable = 0, let isCall = 1, isReturn = 1, isBarrier = 1, isPredicable = 0,
isTerminator = 1, isCodeGenOnly = 1 in { isTerminator = 1, isCodeGenOnly = 1 in {
def TCRETURNtg : T_JMP<(ins calltarget:$dst)>; def TCRETURNtg : JInst<(outs), (ins calltarget:$dst), "jump $dst",
def TCRETURNtext : T_JMP<(ins calltarget:$dst)>; [], "", J_tc_2early_SLOT23>;
def TCRETURNtext : JInst<(outs), (ins calltarget:$dst), "jump $dst",
[], "", J_tc_2early_SLOT23>;
} }
// Map call instruction. // Map call instruction.
def : Pat<(call (i32 IntRegs:$dst)), def : Pat<(call (i32 IntRegs:$dst)),
(CALLR (i32 IntRegs:$dst))>, Requires<[HasV2TOnly]>; (J2_callr (i32 IntRegs:$dst))>, Requires<[HasV2TOnly]>;
def : Pat<(call tglobaladdr:$dst), def : Pat<(call tglobaladdr:$dst),
(CALL tglobaladdr:$dst)>, Requires<[HasV2TOnly]>; (CALL tglobaladdr:$dst)>, Requires<[HasV2TOnly]>;
def : Pat<(call texternalsym:$dst), def : Pat<(call texternalsym:$dst),
@ -2774,7 +2785,7 @@ def : Pat <(select (not (i1 PredRegs:$src1)), IntRegs:$src2, s12ImmPred:$src3),
// Map from p0 = pnot(p0); if (p0) jump => if (!p0) jump. // Map from p0 = pnot(p0); if (p0) jump => if (!p0) jump.
def : Pat <(brcond (not (i1 PredRegs:$src1)), bb:$offset), def : Pat <(brcond (not (i1 PredRegs:$src1)), bb:$offset),
(JMP_f (i1 PredRegs:$src1), bb:$offset)>; (J2_jumpf (i1 PredRegs:$src1), bb:$offset)>;
// Map from p2 = pnot(p2); p1 = and(p0, p2) => p1 = and(p0, !p2). // Map from p2 = pnot(p2); p1 = and(p0, p2) => p1 = and(p0, !p2).
def : Pat <(and (i1 PredRegs:$src1), (not (i1 PredRegs:$src2))), def : Pat <(and (i1 PredRegs:$src1), (not (i1 PredRegs:$src2))),
@ -2807,46 +2818,46 @@ def : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i8)),
subreg_loreg))))))>; subreg_loreg))))))>;
// We want to prevent emitting pnot's as much as possible. // We want to prevent emitting pnot's as much as possible.
// Map brcond with an unsupported setcc to a JMP_f. // Map brcond with an unsupported setcc to a J2_jumpf.
def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2))), def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
bb:$offset), bb:$offset),
(JMP_f (C2_cmpeq (i32 IntRegs:$src1), (i32 IntRegs:$src2)), (J2_jumpf (C2_cmpeq (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
bb:$offset)>; bb:$offset)>;
def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), s10ImmPred:$src2)), def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), s10ImmPred:$src2)),
bb:$offset), bb:$offset),
(JMP_f (C2_cmpeqi (i32 IntRegs:$src1), s10ImmPred:$src2), bb:$offset)>; (J2_jumpf (C2_cmpeqi (i32 IntRegs:$src1), s10ImmPred:$src2), bb:$offset)>;
def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 -1))), bb:$offset), def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 -1))), bb:$offset),
(JMP_f (i1 PredRegs:$src1), bb:$offset)>; (J2_jumpf (i1 PredRegs:$src1), bb:$offset)>;
def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 0))), bb:$offset), def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 0))), bb:$offset),
(JMP_t (i1 PredRegs:$src1), bb:$offset)>; (J2_jumpt (i1 PredRegs:$src1), bb:$offset)>;
// cmp.lt(Rs, Imm) -> !cmp.ge(Rs, Imm) -> !cmp.gt(Rs, Imm-1) // cmp.lt(Rs, Imm) -> !cmp.ge(Rs, Imm) -> !cmp.gt(Rs, Imm-1)
def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), s8ImmPred:$src2)), def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), s8ImmPred:$src2)),
bb:$offset), bb:$offset),
(JMP_f (C2_cmpgti (i32 IntRegs:$src1), (J2_jumpf (C2_cmpgti (i32 IntRegs:$src1),
(DEC_CONST_SIGNED s8ImmPred:$src2)), bb:$offset)>; (DEC_CONST_SIGNED s8ImmPred:$src2)), bb:$offset)>;
// cmp.lt(r0, r1) -> cmp.gt(r1, r0) // cmp.lt(r0, r1) -> cmp.gt(r1, r0)
def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))), def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
bb:$offset), bb:$offset),
(JMP_t (C2_cmpgt (i32 IntRegs:$src2), (i32 IntRegs:$src1)), bb:$offset)>; (J2_jumpt (C2_cmpgt (i32 IntRegs:$src2), (i32 IntRegs:$src1)), bb:$offset)>;
def : Pat <(brcond (i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), def : Pat <(brcond (i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
bb:$offset), bb:$offset),
(JMP_f (C2_cmpgtup (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)), (J2_jumpf (C2_cmpgtup (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)),
bb:$offset)>; bb:$offset)>;
def : Pat <(brcond (i1 (setule (i32 IntRegs:$src1), (i32 IntRegs:$src2))), def : Pat <(brcond (i1 (setule (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
bb:$offset), bb:$offset),
(JMP_f (C2_cmpgtu (i32 IntRegs:$src1), (i32 IntRegs:$src2)), (J2_jumpf (C2_cmpgtu (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
bb:$offset)>; bb:$offset)>;
def : Pat <(brcond (i1 (setule (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), def : Pat <(brcond (i1 (setule (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
bb:$offset), bb:$offset),
(JMP_f (C2_cmpgtup (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)), (J2_jumpf (C2_cmpgtup (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
bb:$offset)>; bb:$offset)>;
// Map from a 64-bit select to an emulated 64-bit mux. // Map from a 64-bit select to an emulated 64-bit mux.

View File

@ -2204,7 +2204,7 @@ def CMPbEQri_V4 : MInst<(outs PredRegs:$dst),
def : Pat <(brcond (i1 (setne (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2)), def : Pat <(brcond (i1 (setne (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2)),
bb:$offset), bb:$offset),
(JMP_f (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2), (J2_jumpf (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2),
bb:$offset)>, bb:$offset)>,
Requires<[HasV4T]>; Requires<[HasV4T]>;

View File

@ -473,15 +473,6 @@ def : Pat <(f64 (bitconvert (i64 DoubleRegs:$src))),
(f64 (A2_tfrp DoubleRegs:$src))>, (f64 (A2_tfrp DoubleRegs:$src))>,
Requires<[HasV5T]>; Requires<[HasV5T]>;
// Floating point fused multiply-add.
def FMADD_dp : ALU64_acc<(outs DoubleRegs:$dst),
(ins DoubleRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3),
"$dst += dfmpy($src2, $src3)",
[(set (f64 DoubleRegs:$dst),
(fma DoubleRegs:$src2, DoubleRegs:$src3, DoubleRegs:$src1))],
"$src1 = $dst">,
Requires<[HasV5T]>;
def FMADD_sp : ALU64_acc<(outs IntRegs:$dst), def FMADD_sp : ALU64_acc<(outs IntRegs:$dst),
(ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3), (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
"$dst += sfmpy($src2, $src3)", "$dst += sfmpy($src2, $src3)",
@ -492,15 +483,6 @@ def FMADD_sp : ALU64_acc<(outs IntRegs:$dst),
// Floating point max/min. // Floating point max/min.
let AddedComplexity = 100 in
def FMAX_dp : ALU64_rr<(outs DoubleRegs:$dst),
(ins DoubleRegs:$src1, DoubleRegs:$src2),
"$dst = dfmax($src1, $src2)",
[(set DoubleRegs:$dst, (f64 (select (i1 (setolt DoubleRegs:$src2,
DoubleRegs:$src1)),
DoubleRegs:$src1,
DoubleRegs:$src2)))]>,
Requires<[HasV5T]>;
let AddedComplexity = 100 in let AddedComplexity = 100 in
def FMAX_sp : ALU64_rr<(outs IntRegs:$dst), def FMAX_sp : ALU64_rr<(outs IntRegs:$dst),
@ -512,16 +494,6 @@ def FMAX_sp : ALU64_rr<(outs IntRegs:$dst),
IntRegs:$src2)))]>, IntRegs:$src2)))]>,
Requires<[HasV5T]>; Requires<[HasV5T]>;
let AddedComplexity = 100 in
def FMIN_dp : ALU64_rr<(outs DoubleRegs:$dst),
(ins DoubleRegs:$src1, DoubleRegs:$src2),
"$dst = dfmin($src1, $src2)",
[(set DoubleRegs:$dst, (f64 (select (i1 (setogt DoubleRegs:$src2,
DoubleRegs:$src1)),
DoubleRegs:$src1,
DoubleRegs:$src2)))]>,
Requires<[HasV5T]>;
let AddedComplexity = 100 in let AddedComplexity = 100 in
def FMIN_sp : ALU64_rr<(outs IntRegs:$dst), def FMIN_sp : ALU64_rr<(outs IntRegs:$dst),
(ins IntRegs:$src1, IntRegs:$src2), (ins IntRegs:$src1, IntRegs:$src2),

View File

@ -412,12 +412,12 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
DEBUG(dbgs() << "Instr: "; MI->dump(); dbgs() << "\n"); DEBUG(dbgs() << "Instr: "; MI->dump(); dbgs() << "\n");
if (!foundJump && if (!foundJump &&
(MI->getOpcode() == Hexagon::JMP_t || (MI->getOpcode() == Hexagon::J2_jumpt ||
MI->getOpcode() == Hexagon::JMP_f || MI->getOpcode() == Hexagon::J2_jumpf ||
MI->getOpcode() == Hexagon::JMP_tnew_t || MI->getOpcode() == Hexagon::J2_jumptnewpt ||
MI->getOpcode() == Hexagon::JMP_tnew_nt || MI->getOpcode() == Hexagon::J2_jumptnew ||
MI->getOpcode() == Hexagon::JMP_fnew_t || MI->getOpcode() == Hexagon::J2_jumpfnewpt ||
MI->getOpcode() == Hexagon::JMP_fnew_nt)) { MI->getOpcode() == Hexagon::J2_jumpfnew)) {
// This is where you would insert your compare and // This is where you would insert your compare and
// instr that feeds compare // instr that feeds compare
jmpPos = MII; jmpPos = MII;
@ -453,9 +453,9 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
jmpTarget = MI->getOperand(1).getMBB(); jmpTarget = MI->getOperand(1).getMBB();
foundJump = true; foundJump = true;
if (MI->getOpcode() == Hexagon::JMP_f || if (MI->getOpcode() == Hexagon::J2_jumpf ||
MI->getOpcode() == Hexagon::JMP_fnew_t || MI->getOpcode() == Hexagon::J2_jumpfnewpt ||
MI->getOpcode() == Hexagon::JMP_fnew_nt) { MI->getOpcode() == Hexagon::J2_jumpfnew) {
invertPredicate = true; invertPredicate = true;
} }
continue; continue;

View File

@ -264,7 +264,7 @@ bool HexagonPacketizer::runOnMachineFunction(MachineFunction &Fn) {
static bool IsIndirectCall(MachineInstr* MI) { static bool IsIndirectCall(MachineInstr* MI) {
return ((MI->getOpcode() == Hexagon::CALLR) || return ((MI->getOpcode() == Hexagon::J2_callr) ||
(MI->getOpcode() == Hexagon::CALLRv3)); (MI->getOpcode() == Hexagon::CALLRv3));
} }
@ -366,7 +366,7 @@ static bool IsRegDependence(const SDep::Kind DepType) {
} }
static bool IsDirectJump(MachineInstr* MI) { static bool IsDirectJump(MachineInstr* MI) {
return (MI->getOpcode() == Hexagon::JMP); return (MI->getOpcode() == Hexagon::J2_jump);
} }
static bool IsSchedBarrier(MachineInstr* MI) { static bool IsSchedBarrier(MachineInstr* MI) {

View File

@ -1,6 +1,26 @@
# RUN: llvm-mc -triple hexagon -disassemble < %s | FileCheck %s # RUN: llvm-mc -triple hexagon -disassemble < %s | FileCheck %s
0x00 0xc0 0xb5 0x50
# CHECK: callr r21
0x00 0xc1 0x15 0x51 0x00 0xc1 0x15 0x51
# CHECK: if (p1) callr r21 # CHECK: if (p1) callr r21
0x00 0xc3 0x35 0x51 0x00 0xc3 0x35 0x51
# CHECK: if (!p3) callr r21 # CHECK: if (!p3) callr r21
0x00 0xc0 0x95 0x52
# CHECK: jumpr r21
0x00 0xc1 0x55 0x53
# CHECK: if (p1) jumpr r21
0x03 0x40 0x45 0x85 0x00 0xcb 0x55 0x53
# CHECK: p3 = r5
# CHECK-NEXT: if (p3.new) jumpr:nt r21
0x03 0x40 0x45 0x85 0x00 0xdb 0x55 0x53
# CHECK: p3 = r5
# CHECK-NEXT: if (p3.new) jumpr:t r21
0x00 0xc3 0x75 0x53
# CHECK: if (!p3) jumpr r21
0x03 0x40 0x45 0x85 0x00 0xcb 0x75 0x53
# CHECK: p3 = r5
# CHECK-NEXT: if (!p3.new) jumpr:nt r21
0x03 0x40 0x45 0x85 0x00 0xdb 0x75 0x53
# CHECK: p3 = r5
# CHECK-NEXT: if (!p3.new) jumpr:t r21