summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-05-28 10:41:11 +0000
committerRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-05-28 10:41:11 +0000
commit0fb90ab0cb8861eebaa61d0b16e17f7191364a85 (patch)
treece323f9c7016dfc88f32a9799b4afbc509d21f8e /llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
parentc08f218b4809b3466b6c48bd31e5a06783249337 (diff)
downloadbcm5719-llvm-0fb90ab0cb8861eebaa61d0b16e17f7191364a85.tar.gz
bcm5719-llvm-0fb90ab0cb8861eebaa61d0b16e17f7191364a85.zip
[SystemZ] Register compare-and-branch support
This patch adds support for the CRJ and CGRJ instructions. Support for the immediate forms will be a separate patch. The architecture has a large number of comparison instructions. I think it's generally better to concentrate on using the "best" comparison instruction first and foremost, then only use something like CRJ if CR really was the natual choice of comparison instruction. The patch therefore opportunistically converts separate CR and BRC instructions into a single CRJ while emitting instructions in ISelLowering. llvm-svn: 182764
Diffstat (limited to 'llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp')
-rw-r--r--llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp29
1 files changed, 27 insertions, 2 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
index 6296e4a4800..dcce5a7b7f7 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
@@ -132,6 +132,10 @@ bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
if (!Branch.Target->isMBB())
return true;
+ // Punt on compound branches.
+ if (Branch.Type != SystemZII::BranchNormal)
+ return true;
+
if (Branch.CCMask == SystemZ::CCMASK_ANY) {
// Handle unconditional branches.
if (!AllowModify) {
@@ -361,11 +365,21 @@ SystemZInstrInfo::getBranchInfo(const MachineInstr *MI) const {
case SystemZ::BR:
case SystemZ::J:
case SystemZ::JG:
- return SystemZII::Branch(SystemZ::CCMASK_ANY, &MI->getOperand(0));
+ return SystemZII::Branch(SystemZII::BranchNormal, SystemZ::CCMASK_ANY,
+ &MI->getOperand(0));
case SystemZ::BRC:
case SystemZ::BRCL:
- return SystemZII::Branch(MI->getOperand(0).getImm(), &MI->getOperand(1));
+ return SystemZII::Branch(SystemZII::BranchNormal,
+ MI->getOperand(0).getImm(), &MI->getOperand(1));
+
+ case SystemZ::CRJ:
+ return SystemZII::Branch(SystemZII::BranchC, MI->getOperand(2).getImm(),
+ &MI->getOperand(3));
+
+ case SystemZ::CGRJ:
+ return SystemZII::Branch(SystemZII::BranchCG, MI->getOperand(2).getImm(),
+ &MI->getOperand(3));
default:
llvm_unreachable("Unrecognized branch opcode");
@@ -426,6 +440,17 @@ unsigned SystemZInstrInfo::getOpcodeForOffset(unsigned Opcode,
return 0;
}
+unsigned SystemZInstrInfo::getCompareAndBranch(unsigned Opcode) const {
+ switch (Opcode) {
+ case SystemZ::CR:
+ return SystemZ::CRJ;
+ case SystemZ::CGR:
+ return SystemZ::CGRJ;
+ default:
+ return 0;
+ }
+}
+
void SystemZInstrInfo::loadImmediate(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
unsigned Reg, uint64_t Value) const {
OpenPOWER on IntegriCloud