summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorUlrich Weigand <ulrich.weigand@de.ibm.com>2016-11-11 12:48:26 +0000
committerUlrich Weigand <ulrich.weigand@de.ibm.com>2016-11-11 12:48:26 +0000
commita0e7325023aea4bc6604e0222dce532cca4954de (patch)
treec62177d980b2d663a91a734a77e99f3e77dd6300 /llvm/lib
parent92c2c672e5be7d4f15f4d40bb46fe7b6f403a311 (diff)
downloadbcm5719-llvm-a0e7325023aea4bc6604e0222dce532cca4954de.tar.gz
bcm5719-llvm-a0e7325023aea4bc6604e0222dce532cca4954de.zip
[SystemZ] Support CL(G)T instructions
This adds support for the compare logical and trap (memory) instructions that were added as part of the miscellaneous instruction extensions feature with zEC12. llvm-svn: 286587
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/SystemZ/SystemZElimCompare.cpp14
-rw-r--r--llvm/lib/Target/SystemZ/SystemZInstrFormats.td25
-rw-r--r--llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp12
-rw-r--r--llvm/lib/Target/SystemZ/SystemZInstrInfo.td8
-rw-r--r--llvm/lib/Target/SystemZ/SystemZScheduleZ13.td1
-rw-r--r--llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td1
6 files changed, 58 insertions, 3 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp b/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp
index 0b5c9dc3bf0..6b07c540400 100644
--- a/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp
@@ -403,6 +403,9 @@ bool SystemZElimCompare::fuseCompareOperations(
return false;
// Make sure that the operands are available at the branch.
+ // SrcReg2 is the register if the source operand is a register,
+ // 0 if the source operand is immediate, and the base register
+ // if the source operand is memory (index is not supported).
unsigned SrcReg = Compare.getOperand(0).getReg();
unsigned SrcReg2 =
Compare.getOperand(1).isReg() ? Compare.getOperand(1).getReg() : 0;
@@ -435,11 +438,16 @@ bool SystemZElimCompare::fuseCompareOperations(
Branch->RemoveOperand(0);
// Rebuild Branch as a fused compare and branch.
+ // SrcNOps is the number of MI operands of the compare instruction
+ // that we need to copy over.
+ unsigned SrcNOps = 2;
+ if (FusedOpcode == SystemZ::CLT || FusedOpcode == SystemZ::CLGT)
+ SrcNOps = 3;
Branch->setDesc(TII->get(FusedOpcode));
MachineInstrBuilder MIB(*Branch->getParent()->getParent(), Branch);
- MIB.addOperand(Compare.getOperand(0))
- .addOperand(Compare.getOperand(1))
- .addOperand(CCMask);
+ for (unsigned I = 0; I < SrcNOps; I++)
+ MIB.addOperand(Compare.getOperand(I));
+ MIB.addOperand(CCMask);
if (Type == SystemZII::CompareAndBranch) {
// Only conditional branches define CC, as they may be converted back
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td
index 8671db6a8ee..94d9c72bbb9 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td
@@ -1879,6 +1879,31 @@ multiclass CmpBranchRISPair<string mnemonic, bits<16> opcode,
def Asm : AsmCmpBranchRIS<mnemonic, opcode, cls, imm>;
}
+class CmpBranchRSYb<string mnemonic, bits<16> opcode,
+ RegisterOperand cls>
+ : InstRSYb<opcode, (outs), (ins cls:$R1, bdaddr20only:$BD2, cond4:$M3),
+ mnemonic#"$M3\t$R1, $BD2", []>;
+
+class AsmCmpBranchRSYb<string mnemonic, bits<16> opcode,
+ RegisterOperand cls>
+ : InstRSYb<opcode, (outs), (ins cls:$R1, bdaddr20only:$BD2, imm32zx4:$M3),
+ mnemonic#"\t$R1, $M3, $BD2", []>;
+
+multiclass CmpBranchRSYbPair<string mnemonic, bits<16> opcode,
+ RegisterOperand cls> {
+ let isCodeGenOnly = 1 in
+ def "" : CmpBranchRSYb<mnemonic, opcode, cls>;
+ def Asm : AsmCmpBranchRSYb<mnemonic, opcode, cls>;
+}
+
+class FixedCmpBranchRSYb<CondVariant V, string mnemonic, bits<16> opcode,
+ RegisterOperand cls>
+ : InstRSYb<opcode, (outs), (ins cls:$R1, bdaddr20only:$BD2),
+ mnemonic#V.suffix#"\t$R1, $BD2", []> {
+ let isAsmParserOnly = V.alternate;
+ let M3 = V.ccmask;
+}
+
class BranchUnaryRI<string mnemonic, bits<12> opcode, RegisterOperand cls>
: InstRIb<opcode, (outs cls:$R1), (ins cls:$R1src, brtarget16:$RI2),
mnemonic##"\t$R1, $RI2", []> {
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
index d781ec742e0..7374083e6e6 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
@@ -1416,6 +1416,14 @@ unsigned SystemZInstrInfo::getFusedCompare(unsigned Opcode,
case SystemZ::CLGFI:
if (!(MI && isUInt<8>(MI->getOperand(1).getImm())))
return 0;
+ break;
+ case SystemZ::CL:
+ case SystemZ::CLG:
+ if (!STI.hasMiscellaneousExtensions())
+ return 0;
+ if (!(MI && MI->getOperand(3).getReg() == 0))
+ return 0;
+ break;
}
switch (Type) {
case SystemZII::CompareAndBranch:
@@ -1499,6 +1507,10 @@ unsigned SystemZInstrInfo::getFusedCompare(unsigned Opcode,
return SystemZ::CLFIT;
case SystemZ::CLGFI:
return SystemZ::CLGIT;
+ case SystemZ::CL:
+ return SystemZ::CLT;
+ case SystemZ::CLG:
+ return SystemZ::CLGT;
default:
return 0;
}
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
index 31d737d231f..105eb87884e 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -192,6 +192,10 @@ let isTerminator = 1, hasCtrlDep = 1 in {
defm CGIT : CmpBranchRIEaPair<"cgit", 0xEC70, GR64, imm64sx16>;
defm CLFIT : CmpBranchRIEaPair<"clfit", 0xEC73, GR32, imm32zx16>;
defm CLGIT : CmpBranchRIEaPair<"clgit", 0xEC71, GR64, imm64zx16>;
+ let Predicates = [FeatureMiscellaneousExtensions] in {
+ defm CLT : CmpBranchRSYbPair<"clt", 0xEB23, GR32>;
+ defm CLGT : CmpBranchRSYbPair<"clgt", 0xEB2B, GR64>;
+ }
foreach V = [ "E", "H", "L", "HE", "LE", "LH",
"NE", "NH", "NL", "NHE", "NLE", "NLH" ] in {
@@ -207,6 +211,10 @@ let isTerminator = 1, hasCtrlDep = 1 in {
imm32zx16>;
def CLGITAsm#V : FixedCmpBranchRIEa<ICV<V>, "clgit", 0xEC71, GR64,
imm64zx16>;
+ let Predicates = [FeatureMiscellaneousExtensions] in {
+ def CLTAsm#V : FixedCmpBranchRSYb<ICV<V>, "clt", 0xEB23, GR32>;
+ def CLGTAsm#V : FixedCmpBranchRSYb<ICV<V>, "clgt", 0xEB2B, GR64>;
+ }
}
}
diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td b/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td
index 8c6ed7dc050..e3a45b85024 100644
--- a/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td
+++ b/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td
@@ -134,6 +134,7 @@ def : InstRW<[VBU], (instregex "(Cond)?Trap$")>;
def : InstRW<[FXb], (instregex "C(G)?(I|R)T(Asm.*)?$")>;
def : InstRW<[FXb], (instregex "CL(G)?RT(Asm.*)?$")>;
def : InstRW<[FXb], (instregex "CL(F|G)IT(Asm.*)?$")>;
+def : InstRW<[FXb, LSU, Lat5], (instregex "CL(G)?T(Asm.*)?$")>;
//===----------------------------------------------------------------------===//
// Call and return instructions
diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td b/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td
index 3f3391b843b..6380f16b889 100644
--- a/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td
+++ b/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td
@@ -111,6 +111,7 @@ def : InstRW<[VBU], (instregex "(Cond)?Trap$")>;
def : InstRW<[FXU], (instregex "C(G)?(I|R)T(Asm.*)?$")>;
def : InstRW<[FXU], (instregex "CL(G)?RT(Asm.*)?$")>;
def : InstRW<[FXU], (instregex "CL(F|G)IT(Asm.*)?$")>;
+def : InstRW<[FXU, LSU, Lat5], (instregex "CL(G)?T(Asm.*)?$")>;
//===----------------------------------------------------------------------===//
// Call and return instructions
OpenPOWER on IntegriCloud