[SystemZ] Add LOCR and LOCGR
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>
Thu, 25 Jul 2013 09:11:15 +0000 (09:11 +0000)
committerRichard Sandiford <rsandifo@linux.vnet.ibm.com>
Thu, 25 Jul 2013 09:11:15 +0000 (09:11 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187113 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/SystemZ/SystemZInstrFormats.td
lib/Target/SystemZ/SystemZInstrInfo.cpp
lib/Target/SystemZ/SystemZInstrInfo.h
lib/Target/SystemZ/SystemZInstrInfo.td
lib/Target/SystemZ/SystemZTargetMachine.cpp
test/CodeGen/SystemZ/cond-move-01.ll [new file with mode: 0644]
test/MC/Disassembler/SystemZ/insns.txt
test/MC/SystemZ/insn-bad-z196.s
test/MC/SystemZ/insn-good-z196.s

index 8199c176d79f807add99bcad65453ad14fa78a29..b4e5531326128102f176069b84757b181fb0f801 100644 (file)
@@ -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),
index 3a502a0117b488e841e8044fffa15f2455204046..53a94a0c94682cfa07f20f30c5261f065d957750 100644 (file)
@@ -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,
index 2050e8ec7c65ed8637d83a28947cf722ef9f5cd1..4fc240e5fbdaf41a901859ddf612ca0fb7606f57 100644 (file)
@@ -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,
index 46cd764478635829bbb53da6125b7bfd5f22eec8..826aa271d0bcb4e59d39c8069d2165601b34a9ad 100644 (file)
@@ -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 {
index 6e7540cec1f781b61f2108e41973b3d098aa119c..437ea615582d26575169401179c8259d4787ec1f 100644 (file)
@@ -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 (file)
index 0000000..3ddc820
--- /dev/null
@@ -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
+}
index 23f45a6067ab826c32509d4de74bbf5e65de83bc..cf26b653b2a249d752ad928363d62c3862d9e8b3 100644 (file)
 # 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
 
index 5243eb57cd7013183abfad39afa07d1208d90bfe..a5e21894a3d758775d81e74586a630c62354dacd 100644 (file)
        locg    %r0,524288,1
        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
index 5b452b5081029745b03f95d3561e8c7b2afd766e..f5213b910b9317d1a02be5286b11454eeb4534c6 100644 (file)
        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]