aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/Hexagon/HexagonInstrInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Hexagon/HexagonInstrInfo.cpp')
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.cpp179
1 files changed, 146 insertions, 33 deletions
diff --git a/lib/Target/Hexagon/HexagonInstrInfo.cpp b/lib/Target/Hexagon/HexagonInstrInfo.cpp
index 9bae12c..fbf1ca9 100644
--- a/lib/Target/Hexagon/HexagonInstrInfo.cpp
+++ b/lib/Target/Hexagon/HexagonInstrInfo.cpp
@@ -62,10 +62,8 @@ const int Hexagon_MEMB_AUTOINC_MIN = -8;
void HexagonInstrInfo::anchor() {}
HexagonInstrInfo::HexagonInstrInfo(HexagonSubtarget &ST)
- : HexagonGenInstrInfo(Hexagon::ADJCALLSTACKDOWN, Hexagon::ADJCALLSTACKUP),
- RI(ST), Subtarget(ST) {
-}
-
+ : HexagonGenInstrInfo(Hexagon::ADJCALLSTACKDOWN, Hexagon::ADJCALLSTACKUP),
+ RI(), Subtarget(ST) {}
/// isLoadFromStackSlot - If the specified machine instruction is a direct
/// load from a stack slot, return the virtual or physical register number of
@@ -159,15 +157,19 @@ HexagonInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
}
BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB);
} else {
- BuildMI(&MBB, DL,
- get(BccOpc)).addReg(Cond[regPos].getReg()).addMBB(TBB);
+ // If Cond[0] is a basic block, insert ENDLOOP0.
+ if (Cond[0].isMBB())
+ BuildMI(&MBB, DL, get(Hexagon::ENDLOOP0)).addMBB(Cond[0].getMBB());
+ else
+ BuildMI(&MBB, DL,
+ get(BccOpc)).addReg(Cond[regPos].getReg()).addMBB(TBB);
}
return 1;
}
+ // We don't handle ENDLOOP0 with a conditional branch in AnalyzeBranch.
BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[regPos].getReg()).addMBB(TBB);
BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB);
-
return 2;
}
@@ -211,9 +213,11 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
return false;
--I;
}
-
+
+ bool JumpToBlock = I->getOpcode() == Hexagon::J2_jump &&
+ I->getOperand(0).isMBB();
// Delete the JMP if it's equivalent to a fall-through.
- if (AllowModify && I->getOpcode() == Hexagon::J2_jump &&
+ if (AllowModify && JumpToBlock &&
MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
DEBUG(dbgs()<< "\nErasing the jump to successor block\n";);
I->eraseFromParent();
@@ -243,6 +247,14 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
} while(I);
int LastOpcode = LastInst->getOpcode();
+ int SecLastOpcode = SecondLastInst ? SecondLastInst->getOpcode() : 0;
+ // If the branch target is not a basic block, it could be a tail call.
+ // (It is, if the target is a function.)
+ if (LastOpcode == Hexagon::J2_jump && !LastInst->getOperand(0).isMBB())
+ return true;
+ if (SecLastOpcode == Hexagon::J2_jump &&
+ !SecondLastInst->getOperand(0).isMBB())
+ return true;
bool LastOpcodeHasJMP_c = PredOpcodeHasJMP_c(LastOpcode);
bool LastOpcodeHasNot = PredOpcodeHasNot(LastOpcode);
@@ -270,8 +282,6 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
return true;
}
- int SecLastOpcode = SecondLastInst->getOpcode();
-
bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);
bool SecLastOpcodeHasNot = PredOpcodeHasNot(SecLastOpcode);
if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::J2_jump)) {
@@ -308,30 +318,35 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
unsigned HexagonInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
- int BOpc = Hexagon::J2_jump;
- int BccOpc = Hexagon::J2_jumpt;
- int BccOpcNot = Hexagon::J2_jumpf;
-
MachineBasicBlock::iterator I = MBB.end();
if (I == MBB.begin()) return 0;
--I;
- if (I->getOpcode() != BOpc && I->getOpcode() != BccOpc &&
- I->getOpcode() != BccOpcNot)
- return 0;
-
- // Remove the branch.
- I->eraseFromParent();
+ unsigned Opc1 = I->getOpcode();
+ switch (Opc1) {
+ case Hexagon::J2_jump:
+ case Hexagon::J2_jumpt:
+ case Hexagon::J2_jumpf:
+ case Hexagon::ENDLOOP0:
+ I->eraseFromParent();
+ break;
+ default:
+ return 0;
+ }
I = MBB.end();
if (I == MBB.begin()) return 1;
--I;
- if (I->getOpcode() != BccOpc && I->getOpcode() != BccOpcNot)
- return 1;
-
- // Remove the branch.
- I->eraseFromParent();
- return 2;
+ unsigned Opc2 = I->getOpcode();
+ switch (Opc2) {
+ case Hexagon::J2_jumpt:
+ case Hexagon::J2_jumpf:
+ case Hexagon::ENDLOOP0:
+ I->eraseFromParent();
+ return 2;
+ default:
+ return 1;
+ }
}
@@ -549,12 +564,95 @@ void HexagonInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
SmallVectorImpl<MachineInstr*> &NewMIs) const {
llvm_unreachable("Unimplemented");
}
+bool
+HexagonInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
+ const HexagonRegisterInfo &TRI = getRegisterInfo();
+ MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
+ MachineBasicBlock &MBB = *MI->getParent();
+ DebugLoc DL = MI->getDebugLoc();
+ unsigned Opc = MI->getOpcode();
+ switch (Opc) {
+ case Hexagon::TFR_PdTrue: {
+ unsigned Reg = MI->getOperand(0).getReg();
+ BuildMI(MBB, MI, DL, get(Hexagon::C2_orn), Reg)
+ .addReg(Reg, RegState::Undef)
+ .addReg(Reg, RegState::Undef);
+ MBB.erase(MI);
+ return true;
+ }
+ case Hexagon::TFR_PdFalse: {
+ unsigned Reg = MI->getOperand(0).getReg();
+ BuildMI(MBB, MI, DL, get(Hexagon::C2_andn), Reg)
+ .addReg(Reg, RegState::Undef)
+ .addReg(Reg, RegState::Undef);
+ MBB.erase(MI);
+ return true;
+ }
+ case Hexagon::VMULW: {
+ // Expand a 64-bit vector multiply into 2 32-bit scalar multiplies.
+ unsigned DstReg = MI->getOperand(0).getReg();
+ unsigned Src1Reg = MI->getOperand(1).getReg();
+ unsigned Src2Reg = MI->getOperand(2).getReg();
+ unsigned Src1SubHi = TRI.getSubReg(Src1Reg, Hexagon::subreg_hireg);
+ unsigned Src1SubLo = TRI.getSubReg(Src1Reg, Hexagon::subreg_loreg);
+ unsigned Src2SubHi = TRI.getSubReg(Src2Reg, Hexagon::subreg_hireg);
+ unsigned Src2SubLo = TRI.getSubReg(Src2Reg, Hexagon::subreg_loreg);
+ BuildMI(MBB, MI, MI->getDebugLoc(), get(Hexagon::M2_mpyi),
+ TRI.getSubReg(DstReg, Hexagon::subreg_hireg)).addReg(Src1SubHi)
+ .addReg(Src2SubHi);
+ BuildMI(MBB, MI, MI->getDebugLoc(), get(Hexagon::M2_mpyi),
+ TRI.getSubReg(DstReg, Hexagon::subreg_loreg)).addReg(Src1SubLo)
+ .addReg(Src2SubLo);
+ MBB.erase(MI);
+ MRI.clearKillFlags(Src1SubHi);
+ MRI.clearKillFlags(Src1SubLo);
+ MRI.clearKillFlags(Src2SubHi);
+ MRI.clearKillFlags(Src2SubLo);
+ return true;
+ }
+ case Hexagon::VMULW_ACC: {
+ // Expand 64-bit vector multiply with addition into 2 scalar multiplies.
+ unsigned DstReg = MI->getOperand(0).getReg();
+ unsigned Src1Reg = MI->getOperand(1).getReg();
+ unsigned Src2Reg = MI->getOperand(2).getReg();
+ unsigned Src3Reg = MI->getOperand(3).getReg();
+ unsigned Src1SubHi = TRI.getSubReg(Src1Reg, Hexagon::subreg_hireg);
+ unsigned Src1SubLo = TRI.getSubReg(Src1Reg, Hexagon::subreg_loreg);
+ unsigned Src2SubHi = TRI.getSubReg(Src2Reg, Hexagon::subreg_hireg);
+ unsigned Src2SubLo = TRI.getSubReg(Src2Reg, Hexagon::subreg_loreg);
+ unsigned Src3SubHi = TRI.getSubReg(Src3Reg, Hexagon::subreg_hireg);
+ unsigned Src3SubLo = TRI.getSubReg(Src3Reg, Hexagon::subreg_loreg);
+ BuildMI(MBB, MI, MI->getDebugLoc(), get(Hexagon::M2_maci),
+ TRI.getSubReg(DstReg, Hexagon::subreg_hireg)).addReg(Src1SubHi)
+ .addReg(Src2SubHi).addReg(Src3SubHi);
+ BuildMI(MBB, MI, MI->getDebugLoc(), get(Hexagon::M2_maci),
+ TRI.getSubReg(DstReg, Hexagon::subreg_loreg)).addReg(Src1SubLo)
+ .addReg(Src2SubLo).addReg(Src3SubLo);
+ MBB.erase(MI);
+ MRI.clearKillFlags(Src1SubHi);
+ MRI.clearKillFlags(Src1SubLo);
+ MRI.clearKillFlags(Src2SubHi);
+ MRI.clearKillFlags(Src2SubLo);
+ MRI.clearKillFlags(Src3SubHi);
+ MRI.clearKillFlags(Src3SubLo);
+ return true;
+ }
+ case Hexagon::TCRETURNi:
+ MI->setDesc(get(Hexagon::J2_jump));
+ return true;
+ case Hexagon::TCRETURNr:
+ MI->setDesc(get(Hexagon::J2_jumpr));
+ return true;
+ }
+
+ return false;
+}
MachineInstr *HexagonInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
- MachineInstr* MI,
- const SmallVectorImpl<unsigned> &Ops,
- int FI) const {
+ MachineInstr *MI,
+ ArrayRef<unsigned> Ops,
+ int FI) const {
// Hexagon_TODO: Implement.
return nullptr;
}
@@ -641,7 +739,7 @@ bool HexagonInstrInfo::isPredicable(MachineInstr *MI) const {
switch(Opc) {
case Hexagon::A2_tfrsi:
- return isInt<12>(MI->getOperand(1).getImm());
+ return (isOperandExtended(MI, 1) && isConstExtended(MI)) || isInt<12>(MI->getOperand(1).getImm());
case Hexagon::S2_storerd_io:
return isShiftedUInt<6,3>(MI->getOperand(1).getImm());
@@ -1036,6 +1134,8 @@ SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
//
bool HexagonInstrInfo::
ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
+ if (!Cond.empty() && Cond[0].isMBB())
+ return true;
if (!Cond.empty() && Cond[0].isImm() && Cond[0].getImm() == 0) {
Cond.erase(Cond.begin());
} else {
@@ -1521,7 +1621,6 @@ int HexagonInstrInfo::GetDotNewOp(const MachineInstr* MI) const {
switch (MI->getOpcode()) {
default: llvm_unreachable("Unknown .new type");
- // store new value byte
case Hexagon::S4_storerb_ur:
return Hexagon::S4_storerbnew_ur;
@@ -1531,6 +1630,20 @@ int HexagonInstrInfo::GetDotNewOp(const MachineInstr* MI) const {
case Hexagon::S4_storeri_ur:
return Hexagon::S4_storerinew_ur;
+ case Hexagon::S2_storerb_pci:
+ return Hexagon::S2_storerb_pci;
+
+ case Hexagon::S2_storeri_pci:
+ return Hexagon::S2_storeri_pci;
+
+ case Hexagon::S2_storerh_pci:
+ return Hexagon::S2_storerh_pci;
+
+ case Hexagon::S2_storerd_pci:
+ return Hexagon::S2_storerd_pci;
+
+ case Hexagon::S2_storerf_pci:
+ return Hexagon::S2_storerf_pci;
}
return 0;
}
@@ -1647,7 +1760,7 @@ bool HexagonInstrInfo::isConstExtended(MachineInstr *MI) const {
// We currently only handle isGlobal() because it is the only kind of
// object we are going to end up with here for now.
// In the future we probably should add isSymbol(), etc.
- if (MO.isGlobal() || MO.isSymbol())
+ if (MO.isGlobal() || MO.isSymbol() || MO.isBlockAddress())
return true;
// If the extendable operand is not 'Immediate' type, the instruction should