From bf99364f819465536a6b230b95735b239e3fc7a5 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 25 Jul 2013 09:11:15 +0000 Subject: [PATCH] [SystemZ] Add LOCR and LOCGR git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187113 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/SystemZ/SystemZInstrFormats.td | 30 +++++++ lib/Target/SystemZ/SystemZInstrInfo.cpp | 52 +++++++++++ lib/Target/SystemZ/SystemZInstrInfo.h | 17 ++++ lib/Target/SystemZ/SystemZInstrInfo.td | 12 +++ lib/Target/SystemZ/SystemZTargetMachine.cpp | 7 ++ test/CodeGen/SystemZ/cond-move-01.ll | 25 ++++++ test/MC/Disassembler/SystemZ/insns.txt | 96 +++++++++++++++++++++ test/MC/SystemZ/insn-bad-z196.s | 16 ++++ test/MC/SystemZ/insn-good-z196.s | 72 ++++++++++++++++ 9 files changed, 327 insertions(+) create mode 100644 test/CodeGen/SystemZ/cond-move-01.ll diff --git a/lib/Target/SystemZ/SystemZInstrFormats.td b/lib/Target/SystemZ/SystemZInstrFormats.td index 8199c176d79..b4e55313261 100644 --- a/lib/Target/SystemZ/SystemZInstrFormats.td +++ b/lib/Target/SystemZ/SystemZInstrFormats.td @@ -680,6 +680,36 @@ class UnaryRRF 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 opcode, RegisterOperand cls1, + RegisterOperand cls2> + : InstRRF, + 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 opcode, RegisterOperand cls1, + RegisterOperand cls2> + : InstRRF, + Requires<[FeatureLoadStoreOnCond]> { + let Constraints = "$R1 = $R1src"; + let DisableEncoding = "$R1src"; +} + +// Like CondUnaryRRF, but with a fixed CC mask. +class FixedCondUnaryRRF opcode, RegisterOperand cls1, + RegisterOperand cls2, bits<4> ccmask> + : InstRRF, + Requires<[FeatureLoadStoreOnCond]> { + let Constraints = "$R1 = $R1src"; + let DisableEncoding = "$R1src"; + let R3 = ccmask; +} + class UnaryRI opcode, SDPatternOperator operator, RegisterOperand cls, Immediate imm> : InstRIgetOpcode(); + 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 &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 2050e8ec7c6..4fc240e5fbd 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.h +++ b/lib/Target/SystemZ/SystemZInstrInfo.h @@ -104,6 +104,23 @@ public: MachineBasicBlock *FBB, const SmallVectorImpl &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 &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 46cd7644786..826aa271d0b 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -112,6 +112,8 @@ multiclass CondExtendedMnemonic 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 6e7540cec1f..437ea615582 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 00000000000..3ddc820dc1b --- /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 23f45a6067a..cf26b653b2a 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 5243eb57cd7..a5e21894a3d 100644 --- a/test/MC/SystemZ/insn-bad-z196.s +++ b/test/MC/SystemZ/insn-bad-z196.s @@ -58,6 +58,22 @@ 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 diff --git a/test/MC/SystemZ/insn-good-z196.s b/test/MC/SystemZ/insn-good-z196.s index 5b452b50810..f5213b910b9 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]