diff options
author | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-07-25 09:11:15 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-07-25 09:11:15 +0000 |
commit | bf99364f819465536a6b230b95735b239e3fc7a5 (patch) | |
tree | 5839fbe196bb47163f76bda386eda7a3a012d940 | |
parent | cf20e45cc4cb77bcb16363531e600883cd27ff80 (diff) | |
download | llvm-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.td | 30 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.cpp | 52 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.h | 17 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.td | 12 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZTargetMachine.cpp | 7 | ||||
-rw-r--r-- | test/CodeGen/SystemZ/cond-move-01.ll | 25 | ||||
-rw-r--r-- | test/MC/Disassembler/SystemZ/insns.txt | 96 | ||||
-rw-r--r-- | test/MC/SystemZ/insn-bad-z196.s | 16 | ||||
-rw-r--r-- | test/MC/SystemZ/insn-good-z196.s | 72 |
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] |