summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-07-25 09:11:15 +0000
committerRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-07-25 09:11:15 +0000
commitbf99364f819465536a6b230b95735b239e3fc7a5 (patch)
tree5839fbe196bb47163f76bda386eda7a3a012d940
parentcf20e45cc4cb77bcb16363531e600883cd27ff80 (diff)
downloadllvm-bf99364f819465536a6b230b95735b239e3fc7a5.tar.gz
llvm-bf99364f819465536a6b230b95735b239e3fc7a5.tar.bz2
llvm-bf99364f819465536a6b230b95735b239e3fc7a5.tar.xz
[SystemZ] Add LOCR and LOCGR
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187113 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/SystemZ/SystemZInstrFormats.td30
-rw-r--r--lib/Target/SystemZ/SystemZInstrInfo.cpp52
-rw-r--r--lib/Target/SystemZ/SystemZInstrInfo.h17
-rw-r--r--lib/Target/SystemZ/SystemZInstrInfo.td12
-rw-r--r--lib/Target/SystemZ/SystemZTargetMachine.cpp7
-rw-r--r--test/CodeGen/SystemZ/cond-move-01.ll25
-rw-r--r--test/MC/Disassembler/SystemZ/insns.txt96
-rw-r--r--test/MC/SystemZ/insn-bad-z196.s16
-rw-r--r--test/MC/SystemZ/insn-good-z196.s72
9 files changed, 327 insertions, 0 deletions
diff --git a/lib/Target/SystemZ/SystemZInstrFormats.td b/lib/Target/SystemZ/SystemZInstrFormats.td
index 8199c176d7..b4e5531326 100644
--- a/lib/Target/SystemZ/SystemZInstrFormats.td
+++ b/lib/Target/SystemZ/SystemZInstrFormats.td
@@ -680,6 +680,36 @@ class UnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
let OpType = "reg";
}
+// These instructions are generated by if conversion. The old value of R1
+// is added as an implicit use.
+class CondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
+ RegisterOperand cls2>
+ : InstRRF<opcode, (outs cls1:$R1), (ins cls2:$R2, cond4:$R3),
+ mnemonic#"r$R3\t$R1, $R2", []>,
+ Requires<[FeatureLoadStoreOnCond]>;
+
+// Like CondUnaryRRF, but used for the raw assembly form. The condition-code
+// mask is the third operand rather than being part of the mnemonic.
+class AsmCondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
+ RegisterOperand cls2>
+ : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2, uimm8zx4:$R3),
+ mnemonic#"r\t$R1, $R2, $R3", []>,
+ Requires<[FeatureLoadStoreOnCond]> {
+ let Constraints = "$R1 = $R1src";
+ let DisableEncoding = "$R1src";
+}
+
+// Like CondUnaryRRF, but with a fixed CC mask.
+class FixedCondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
+ RegisterOperand cls2, bits<4> ccmask>
+ : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2),
+ mnemonic#"\t$R1, $R2", []>,
+ Requires<[FeatureLoadStoreOnCond]> {
+ let Constraints = "$R1 = $R1src";
+ let DisableEncoding = "$R1src";
+ let R3 = ccmask;
+}
+
class UnaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
RegisterOperand cls, Immediate imm>
: InstRI<opcode, (outs cls:$R1), (ins imm:$I2),
diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp
index 3a502a0117..53a94a0c94 100644
--- a/lib/Target/SystemZ/SystemZInstrInfo.cpp
+++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp
@@ -277,6 +277,58 @@ SystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
return Count;
}
+// If Opcode is a move that has a conditional variant, return that variant,
+// otherwise return 0.
+static unsigned getConditionalMove(unsigned Opcode) {
+ switch (Opcode) {
+ case SystemZ::LR: return SystemZ::LOCR;
+ case SystemZ::LGR: return SystemZ::LOCGR;
+ default: return 0;
+ }
+}
+
+bool SystemZInstrInfo::isPredicable(MachineInstr *MI) const {
+ unsigned Opcode = MI->getOpcode();
+ if (TM.getSubtargetImpl()->hasLoadStoreOnCond() &&
+ getConditionalMove(Opcode))
+ return true;
+ return false;
+}
+
+bool SystemZInstrInfo::
+isProfitableToIfCvt(MachineBasicBlock &MBB,
+ unsigned NumCycles, unsigned ExtraPredCycles,
+ const BranchProbability &Probability) const {
+ // For now only convert single instructions.
+ return NumCycles == 1;
+}
+
+bool SystemZInstrInfo::
+isProfitableToIfCvt(MachineBasicBlock &TMBB,
+ unsigned NumCyclesT, unsigned ExtraPredCyclesT,
+ MachineBasicBlock &FMBB,
+ unsigned NumCyclesF, unsigned ExtraPredCyclesF,
+ const BranchProbability &Probability) const {
+ // For now avoid converting mutually-exclusive cases.
+ return false;
+}
+
+bool SystemZInstrInfo::
+PredicateInstruction(MachineInstr *MI,
+ const SmallVectorImpl<MachineOperand> &Pred) const {
+ unsigned CCMask = Pred[0].getImm();
+ assert(CCMask > 0 && CCMask < 15 && "Invalid predicate");
+ unsigned Opcode = MI->getOpcode();
+ if (TM.getSubtargetImpl()->hasLoadStoreOnCond()) {
+ if (unsigned CondOpcode = getConditionalMove(Opcode)) {
+ MI->setDesc(get(CondOpcode));
+ MachineInstrBuilder(*MI->getParent()->getParent(), MI).addImm(CCMask);
+ return true;
+ }
+ }
+ return false;
+}
+
void
SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI, DebugLoc DL,
diff --git a/lib/Target/SystemZ/SystemZInstrInfo.h b/lib/Target/SystemZ/SystemZInstrInfo.h
index 2050e8ec7c..4fc240e5fb 100644
--- a/lib/Target/SystemZ/SystemZInstrInfo.h
+++ b/lib/Target/SystemZ/SystemZInstrInfo.h
@@ -104,6 +104,23 @@ public:
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond,
DebugLoc DL) const LLVM_OVERRIDE;
+ virtual bool isPredicable(MachineInstr *MI) const LLVM_OVERRIDE;
+ virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
+ unsigned ExtraPredCycles,
+ const BranchProbability &Probability) const
+ LLVM_OVERRIDE;
+ virtual bool isProfitableToIfCvt(MachineBasicBlock &TMBB,
+ unsigned NumCyclesT,
+ unsigned ExtraPredCyclesT,
+ MachineBasicBlock &FMBB,
+ unsigned NumCyclesF,
+ unsigned ExtraPredCyclesF,
+ const BranchProbability &Probability) const
+ LLVM_OVERRIDE;
+ virtual bool
+ PredicateInstruction(MachineInstr *MI,
+ const SmallVectorImpl<MachineOperand> &Pred) const
+ LLVM_OVERRIDE;
virtual void copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI, DebugLoc DL,
unsigned DestReg, unsigned SrcReg,
diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td
index 46cd764478..826aa271d0 100644
--- a/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -112,6 +112,8 @@ multiclass CondExtendedMnemonic<bits<4> ccmask, string name> {
def JG : InstRIL<0xC04, (outs), (ins brtarget32:$I2),
"jg"##name##"\t$I2", []>;
}
+ def LOCR : FixedCondUnaryRRF<"locr"##name, 0xB9F2, GR32, GR32, ccmask>;
+ def LOCGR : FixedCondUnaryRRF<"locgr"##name, 0xB9E2, GR64, GR64, ccmask>;
def LOC : FixedCondUnaryRSY<"loc"##name, 0xEBF2, GR32, ccmask, 4>;
def LOCG : FixedCondUnaryRSY<"locg"##name, 0xEBE2, GR64, ccmask, 8>;
def STOC : FixedCondStoreRSY<"stoc"##name, 0xEBF3, GR32, ccmask, 4>;
@@ -225,6 +227,16 @@ let neverHasSideEffects = 1 in {
def LGR : UnaryRRE<"lg", 0xB904, null_frag, GR64, GR64>;
}
+// Move on condition.
+let isCodeGenOnly = 1, Uses = [CC] in {
+ def LOCR : CondUnaryRRF<"loc", 0xB9F2, GR32, GR32>;
+ def LOCGR : CondUnaryRRF<"locg", 0xB9E2, GR64, GR64>;
+}
+let Uses = [CC] in {
+ def AsmLOCR : AsmCondUnaryRRF<"loc", 0xB9F2, GR32, GR32>;
+ def AsmLOCGR : AsmCondUnaryRRF<"locg", 0xB9E2, GR64, GR64>;
+}
+
// Immediate moves.
let neverHasSideEffects = 1, isAsCheapAsAMove = 1, isMoveImm = 1,
isReMaterializable = 1 in {
diff --git a/lib/Target/SystemZ/SystemZTargetMachine.cpp b/lib/Target/SystemZ/SystemZTargetMachine.cpp
index 6e7540cec1..437ea61558 100644
--- a/lib/Target/SystemZ/SystemZTargetMachine.cpp
+++ b/lib/Target/SystemZ/SystemZTargetMachine.cpp
@@ -48,6 +48,7 @@ public:
}
virtual bool addInstSelector() LLVM_OVERRIDE;
+ virtual bool addPreSched2() LLVM_OVERRIDE;
virtual bool addPreEmitPass() LLVM_OVERRIDE;
};
} // end anonymous namespace
@@ -57,6 +58,12 @@ bool SystemZPassConfig::addInstSelector() {
return false;
}
+bool SystemZPassConfig::addPreSched2() {
+ if (getSystemZTargetMachine().getSubtargetImpl()->hasLoadStoreOnCond())
+ addPass(&IfConverterID);
+ return true;
+}
+
bool SystemZPassConfig::addPreEmitPass() {
addPass(createSystemZLongBranchPass(getSystemZTargetMachine()));
return true;
diff --git a/test/CodeGen/SystemZ/cond-move-01.ll b/test/CodeGen/SystemZ/cond-move-01.ll
new file mode 100644
index 0000000000..3ddc820dc1
--- /dev/null
+++ b/test/CodeGen/SystemZ/cond-move-01.ll
@@ -0,0 +1,25 @@
+; Test LOCR and LOCGR.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
+
+; Test LOCR.
+define i32 @f1(i32 %a, i32 %b, i32 %limit) {
+; CHECK-LABEL: f1:
+; CHECK: clfi %r4, 42
+; CHECK: locrnl %r2, %r3
+; CHECK: br %r14
+ %cond = icmp ult i32 %limit, 42
+ %res = select i1 %cond, i32 %a, i32 %b
+ ret i32 %res
+}
+
+; Test LOCGR.
+define i64 @f2(i64 %a, i64 %b, i64 %limit) {
+; CHECK-LABEL: f2:
+; CHECK: clgfi %r4, 42
+; CHECK: locgrnl %r2, %r3
+; CHECK: br %r14
+ %cond = icmp ult i64 %limit, 42
+ %res = select i1 %cond, i64 %a, i64 %b
+ ret i64 %res
+}
diff --git a/test/MC/Disassembler/SystemZ/insns.txt b/test/MC/Disassembler/SystemZ/insns.txt
index 23f45a6067..cf26b653b2 100644
--- a/test/MC/Disassembler/SystemZ/insns.txt
+++ b/test/MC/Disassembler/SystemZ/insns.txt
@@ -3358,6 +3358,102 @@
# CHECK: locg %r7, 6399(%r8), 15
0xeb 0x7f 0x88 0xff 0x01 0xe2
+# CHECK: locr %r11, %r3, 0
+0xb9 0xf2 0x00 0xb3
+
+# CHECK: locro %r11, %r3
+0xb9 0xf2 0x10 0xb3
+
+# CHECK: locrh %r11, %r3
+0xb9 0xf2 0x20 0xb3
+
+# CHECK: locrnle %r11, %r3
+0xb9 0xf2 0x30 0xb3
+
+# CHECK: locrl %r11, %r3
+0xb9 0xf2 0x40 0xb3
+
+# CHECK: locrnhe %r11, %r3
+0xb9 0xf2 0x50 0xb3
+
+# CHECK: locrlh %r11, %r3
+0xb9 0xf2 0x60 0xb3
+
+# CHECK: locrne %r11, %r3
+0xb9 0xf2 0x70 0xb3
+
+# CHECK: locre %r11, %r3
+0xb9 0xf2 0x80 0xb3
+
+# CHECK: locrnlh %r11, %r3
+0xb9 0xf2 0x90 0xb3
+
+# CHECK: locrhe %r11, %r3
+0xb9 0xf2 0xa0 0xb3
+
+# CHECK: locrnl %r11, %r3
+0xb9 0xf2 0xb0 0xb3
+
+# CHECK: locrle %r11, %r3
+0xb9 0xf2 0xc0 0xb3
+
+# CHECK: locrnh %r11, %r3
+0xb9 0xf2 0xd0 0xb3
+
+# CHECK: locrno %r11, %r3
+0xb9 0xf2 0xe0 0xb3
+
+# CHECK: locr %r11, %r3, 15
+0xb9 0xf2 0xf0 0xb3
+
+# CHECK: locgr %r11, %r3, 0
+0xb9 0xe2 0x00 0xb3
+
+# CHECK: locgro %r11, %r3
+0xb9 0xe2 0x10 0xb3
+
+# CHECK: locgrh %r11, %r3
+0xb9 0xe2 0x20 0xb3
+
+# CHECK: locgrnle %r11, %r3
+0xb9 0xe2 0x30 0xb3
+
+# CHECK: locgrl %r11, %r3
+0xb9 0xe2 0x40 0xb3
+
+# CHECK: locgrnhe %r11, %r3
+0xb9 0xe2 0x50 0xb3
+
+# CHECK: locgrlh %r11, %r3
+0xb9 0xe2 0x60 0xb3
+
+# CHECK: locgrne %r11, %r3
+0xb9 0xe2 0x70 0xb3
+
+# CHECK: locgre %r11, %r3
+0xb9 0xe2 0x80 0xb3
+
+# CHECK: locgrnlh %r11, %r3
+0xb9 0xe2 0x90 0xb3
+
+# CHECK: locgrhe %r11, %r3
+0xb9 0xe2 0xa0 0xb3
+
+# CHECK: locgrnl %r11, %r3
+0xb9 0xe2 0xb0 0xb3
+
+# CHECK: locgrle %r11, %r3
+0xb9 0xe2 0xc0 0xb3
+
+# CHECK: locgrnh %r11, %r3
+0xb9 0xe2 0xd0 0xb3
+
+# CHECK: locgrno %r11, %r3
+0xb9 0xe2 0xe0 0xb3
+
+# CHECK: locgr %r11, %r3, 15
+0xb9 0xe2 0xf0 0xb3
+
# CHECK: lpdbr %f0, %f9
0xb3 0x10 0x00 0x09
diff --git a/test/MC/SystemZ/insn-bad-z196.s b/test/MC/SystemZ/insn-bad-z196.s
index 5243eb57cd..a5e21894a3 100644
--- a/test/MC/SystemZ/insn-bad-z196.s
+++ b/test/MC/SystemZ/insn-bad-z196.s
@@ -59,6 +59,22 @@
locg %r0,0(%r1,%r2),1
#CHECK: error: invalid operand
+#CHECK: locgr %r0,%r0,-1
+#CHECK: error: invalid operand
+#CHECK: locgr %r0,%r0,16
+
+ locgr %r0,%r0,-1
+ locgr %r0,%r0,16
+
+#CHECK: error: invalid operand
+#CHECK: locr %r0,%r0,-1
+#CHECK: error: invalid operand
+#CHECK: locr %r0,%r0,16
+
+ locr %r0,%r0,-1
+ locr %r0,%r0,16
+
+#CHECK: error: invalid operand
#CHECK: sllk %r0,%r0,-524289
#CHECK: error: invalid operand
#CHECK: sllk %r0,%r0,524288
diff --git a/test/MC/SystemZ/insn-good-z196.s b/test/MC/SystemZ/insn-good-z196.s
index 5b452b5081..f5213b910b 100644
--- a/test/MC/SystemZ/insn-good-z196.s
+++ b/test/MC/SystemZ/insn-good-z196.s
@@ -217,6 +217,78 @@
locgnh %r1,2(%r3)
locgno %r1,2(%r3)
+#CHECK: locgr %r1, %r2, 0 # encoding: [0xb9,0xe2,0x00,0x12]
+#CHECK: locgr %r1, %r2, 15 # encoding: [0xb9,0xe2,0xf0,0x12]
+
+ locgr %r1,%r2,0
+ locgr %r1,%r2,15
+
+#CHECK: locgro %r1, %r3 # encoding: [0xb9,0xe2,0x10,0x13]
+#CHECK: locgrh %r1, %r3 # encoding: [0xb9,0xe2,0x20,0x13]
+#CHECK: locgrnle %r1, %r3 # encoding: [0xb9,0xe2,0x30,0x13]
+#CHECK: locgrl %r1, %r3 # encoding: [0xb9,0xe2,0x40,0x13]
+#CHECK: locgrnhe %r1, %r3 # encoding: [0xb9,0xe2,0x50,0x13]
+#CHECK: locgrlh %r1, %r3 # encoding: [0xb9,0xe2,0x60,0x13]
+#CHECK: locgrne %r1, %r3 # encoding: [0xb9,0xe2,0x70,0x13]
+#CHECK: locgre %r1, %r3 # encoding: [0xb9,0xe2,0x80,0x13]
+#CHECK: locgrnlh %r1, %r3 # encoding: [0xb9,0xe2,0x90,0x13]
+#CHECK: locgrhe %r1, %r3 # encoding: [0xb9,0xe2,0xa0,0x13]
+#CHECK: locgrnl %r1, %r3 # encoding: [0xb9,0xe2,0xb0,0x13]
+#CHECK: locgrle %r1, %r3 # encoding: [0xb9,0xe2,0xc0,0x13]
+#CHECK: locgrnh %r1, %r3 # encoding: [0xb9,0xe2,0xd0,0x13]
+#CHECK: locgrno %r1, %r3 # encoding: [0xb9,0xe2,0xe0,0x13]
+
+ locgro %r1,%r3
+ locgrh %r1,%r3
+ locgrnle %r1,%r3
+ locgrl %r1,%r3
+ locgrnhe %r1,%r3
+ locgrlh %r1,%r3
+ locgrne %r1,%r3
+ locgre %r1,%r3
+ locgrnlh %r1,%r3
+ locgrhe %r1,%r3
+ locgrnl %r1,%r3
+ locgrle %r1,%r3
+ locgrnh %r1,%r3
+ locgrno %r1,%r3
+
+#CHECK: locr %r1, %r2, 0 # encoding: [0xb9,0xf2,0x00,0x12]
+#CHECK: locr %r1, %r2, 15 # encoding: [0xb9,0xf2,0xf0,0x12]
+
+ locr %r1,%r2,0
+ locr %r1,%r2,15
+
+#CHECK: locro %r1, %r3 # encoding: [0xb9,0xf2,0x10,0x13]
+#CHECK: locrh %r1, %r3 # encoding: [0xb9,0xf2,0x20,0x13]
+#CHECK: locrnle %r1, %r3 # encoding: [0xb9,0xf2,0x30,0x13]
+#CHECK: locrl %r1, %r3 # encoding: [0xb9,0xf2,0x40,0x13]
+#CHECK: locrnhe %r1, %r3 # encoding: [0xb9,0xf2,0x50,0x13]
+#CHECK: locrlh %r1, %r3 # encoding: [0xb9,0xf2,0x60,0x13]
+#CHECK: locrne %r1, %r3 # encoding: [0xb9,0xf2,0x70,0x13]
+#CHECK: locre %r1, %r3 # encoding: [0xb9,0xf2,0x80,0x13]
+#CHECK: locrnlh %r1, %r3 # encoding: [0xb9,0xf2,0x90,0x13]
+#CHECK: locrhe %r1, %r3 # encoding: [0xb9,0xf2,0xa0,0x13]
+#CHECK: locrnl %r1, %r3 # encoding: [0xb9,0xf2,0xb0,0x13]
+#CHECK: locrle %r1, %r3 # encoding: [0xb9,0xf2,0xc0,0x13]
+#CHECK: locrnh %r1, %r3 # encoding: [0xb9,0xf2,0xd0,0x13]
+#CHECK: locrno %r1, %r3 # encoding: [0xb9,0xf2,0xe0,0x13]
+
+ locro %r1,%r3
+ locrh %r1,%r3
+ locrnle %r1,%r3
+ locrl %r1,%r3
+ locrnhe %r1,%r3
+ locrlh %r1,%r3
+ locrne %r1,%r3
+ locre %r1,%r3
+ locrnlh %r1,%r3
+ locrhe %r1,%r3
+ locrnl %r1,%r3
+ locrle %r1,%r3
+ locrnh %r1,%r3
+ locrno %r1,%r3
+
#CHECK: ngrk %r0, %r0, %r0 # encoding: [0xb9,0xe4,0x00,0x00]
#CHECK: ngrk %r0, %r0, %r15 # encoding: [0xb9,0xe4,0xf0,0x00]
#CHECK: ngrk %r0, %r15, %r0 # encoding: [0xb9,0xe4,0x00,0x0f]