diff options
author | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-05-29 11:58:52 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-05-29 11:58:52 +0000 |
commit | 2d664abbfca8b9fa3d99e8a2f74bd52faf007f12 (patch) | |
tree | ef3e64c5251a4118e32a0393799793277d7259f4 /lib | |
parent | b8303eb654c1ba1833cfd048ed1f01309b19afe2 (diff) | |
download | external_llvm-2d664abbfca8b9fa3d99e8a2f74bd52faf007f12.zip external_llvm-2d664abbfca8b9fa3d99e8a2f74bd52faf007f12.tar.gz external_llvm-2d664abbfca8b9fa3d99e8a2f74bd52faf007f12.tar.bz2 |
[SystemZ] Immediate compare-and-branch support
This patch adds support for the CIJ and CGIJ instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182846 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/SystemZ/README.txt | 4 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZISelLowering.cpp | 3 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrFormats.td | 18 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.cpp | 9 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.h | 4 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.td | 21 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZLongBranch.cpp | 11 |
7 files changed, 59 insertions, 11 deletions
diff --git a/lib/Target/SystemZ/README.txt b/lib/Target/SystemZ/README.txt index ac0e138..55e9fc0 100644 --- a/lib/Target/SystemZ/README.txt +++ b/lib/Target/SystemZ/README.txt @@ -56,10 +56,6 @@ and conditional returns. -- -We don't use the combined COMPARE AND BRANCH instructions. - --- - We don't use the condition code results of anything except comparisons. Implementing this may need something more finely grained than the z_cmp diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index 03a6da6..ae520e1 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -1624,7 +1624,8 @@ convertPrevCompareToBranch(MachineBasicBlock *MBB, while (Compare->isDebugValue()); const SystemZInstrInfo *TII = TM.getInstrInfo(); - unsigned FusedOpcode = TII->getCompareAndBranch(Compare->getOpcode()); + unsigned FusedOpcode = TII->getCompareAndBranch(Compare->getOpcode(), + Compare); if (!FusedOpcode) return false; diff --git a/lib/Target/SystemZ/SystemZInstrFormats.td b/lib/Target/SystemZ/SystemZInstrFormats.td index c52e2a2..ad050fd 100644 --- a/lib/Target/SystemZ/SystemZInstrFormats.td +++ b/lib/Target/SystemZ/SystemZInstrFormats.td @@ -129,6 +129,24 @@ class InstRIEb<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> let Inst{7-0} = op{7-0}; } +class InstRIEc<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + field bits<48> SoftFail = 0; + + bits<4> R1; + bits<8> I2; + bits<4> M3; + bits<16> RI4; + + let Inst{47-40} = op{15-8}; + let Inst{39-36} = R1; + let Inst{35-32} = M3; + let Inst{31-16} = RI4; + let Inst{15-8} = I2; + let Inst{7-0} = op{7-0}; +} + class InstRIEf<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> : InstSystemZ<6, outs, ins, asmstr, pattern> { field bits<48> Inst; diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp index dcce5a7..5339bf1 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -373,10 +373,12 @@ SystemZInstrInfo::getBranchInfo(const MachineInstr *MI) const { return SystemZII::Branch(SystemZII::BranchNormal, MI->getOperand(0).getImm(), &MI->getOperand(1)); + case SystemZ::CIJ: case SystemZ::CRJ: return SystemZII::Branch(SystemZII::BranchC, MI->getOperand(2).getImm(), &MI->getOperand(3)); + case SystemZ::CGIJ: case SystemZ::CGRJ: return SystemZII::Branch(SystemZII::BranchCG, MI->getOperand(2).getImm(), &MI->getOperand(3)); @@ -440,12 +442,17 @@ unsigned SystemZInstrInfo::getOpcodeForOffset(unsigned Opcode, return 0; } -unsigned SystemZInstrInfo::getCompareAndBranch(unsigned Opcode) const { +unsigned SystemZInstrInfo::getCompareAndBranch(unsigned Opcode, + const MachineInstr *MI) const { switch (Opcode) { case SystemZ::CR: return SystemZ::CRJ; case SystemZ::CGR: return SystemZ::CGRJ; + case SystemZ::CHI: + return MI && isInt<8>(MI->getOperand(1).getImm()) ? SystemZ::CIJ : 0; + case SystemZ::CGHI: + return MI && isInt<8>(MI->getOperand(1).getImm()) ? SystemZ::CGIJ : 0; default: return 0; } diff --git a/lib/Target/SystemZ/SystemZInstrInfo.h b/lib/Target/SystemZ/SystemZInstrInfo.h index e4a9840..d6980f7 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.h +++ b/lib/Target/SystemZ/SystemZInstrInfo.h @@ -143,7 +143,9 @@ public: // If Opcode is a COMPARE opcode for which an associated COMPARE AND // BRANCH exists, return the opcode for the latter, otherwise return 0. - unsigned getCompareAndBranch(unsigned Opcode) const; + // MI, if nonnull, is the compare instruction. + unsigned getCompareAndBranch(unsigned Opcode, + const MachineInstr *MI = 0) const; // Emit code before MBBI in MI to move immediate value Value into // physical register Reg. diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index bc3997b..062266b 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -87,10 +87,16 @@ multiclass CompareBranches<Operand ccmask, string pos1, string pos2> { let isBranch = 1, isTerminator = 1, Defs = [CC] in { def RJ : InstRIEb<0xEC76, (outs), (ins GR32:$R1, GR32:$R2, ccmask:$M3, brtarget16:$RI4), - "crj"#pos1#"\t$R1, $R2, "#pos2#"$RI4", []>; + "crj"##pos1##"\t$R1, $R2, "##pos2##"$RI4", []>; def GRJ : InstRIEb<0xEC64, (outs), (ins GR64:$R1, GR64:$R2, ccmask:$M3, brtarget16:$RI4), - "cgrj"#pos1#"\t$R1, $R2, "#pos2#"$RI4", []>; + "cgrj"##pos1##"\t$R1, $R2, "##pos2##"$RI4", []>; + def IJ : InstRIEc<0xEC7E, (outs), (ins GR32:$R1, imm32sx8:$I2, ccmask:$M3, + brtarget16:$RI4), + "cij"##pos1##"\t$R1, $I2, "##pos2##"$RI4", []>; + def GIJ : InstRIEc<0xEC7C, (outs), (ins GR64:$R1, imm64sx8:$I2, ccmask:$M3, + brtarget16:$RI4), + "cgij"##pos1##"\t$R1, $I2, "##pos2##"$RI4", []>; } } let isCodeGenOnly = 1 in @@ -101,9 +107,10 @@ defm AsmC : CompareBranches<uimm8zx4, "", "$M3, ">; // (integer or floating-point) multiclass CondExtendedMnemonic<bits<4> ccmask, string name> { let R1 = ccmask in { - def "" : InstRI<0xA74, (outs), (ins brtarget16:$I2), "j"#name#"\t$I2", []>; + def "" : InstRI<0xA74, (outs), (ins brtarget16:$I2), + "j"##name##"\t$I2", []>; def L : InstRIL<0xC04, (outs), (ins brtarget32:$I2), - "jg"#name#"\t$I2", []>; + "jg"##name##"\t$I2", []>; } } defm AsmJO : CondExtendedMnemonic<1, "o">; @@ -136,6 +143,12 @@ multiclass IntCondExtendedMnemonicA<bits<4> ccmask, string name> { def CGR : InstRIEb<0xEC64, (outs), (ins GR64:$R1, GR64:$R2, brtarget16:$RI4), "cgrj"##name##"\t$R1, $R2, $RI4", []>; + def CI : InstRIEc<0xEC7E, (outs), (ins GR32:$R1, imm32sx8:$I2, + brtarget16:$RI4), + "cij"##name##"\t$R1, $I2, $RI4", []>; + def CGI : InstRIEc<0xEC7C, (outs), (ins GR64:$R1, imm64sx8:$I2, + brtarget16:$RI4), + "cgij"##name##"\t$R1, $I2, $RI4", []>; } } multiclass IntCondExtendedMnemonic<bits<4> ccmask, string name1, string name2> diff --git a/lib/Target/SystemZ/SystemZLongBranch.cpp b/lib/Target/SystemZ/SystemZLongBranch.cpp index 2fc85f5..24afb07 100644 --- a/lib/Target/SystemZ/SystemZLongBranch.cpp +++ b/lib/Target/SystemZ/SystemZLongBranch.cpp @@ -229,6 +229,11 @@ TerminatorInfo SystemZLongBranch::describeTerminator(MachineInstr *MI) { // Relaxes to a CGR/BRCL sequence, which is 4 bytes longer. Terminator.ExtraRelaxSize = 4; break; + case SystemZ::CIJ: + case SystemZ::CGIJ: + // Relaxes to a C(G)HI/BRCL sequence, which is 4 bytes longer. + Terminator.ExtraRelaxSize = 4; + break; default: llvm_unreachable("Unrecognized branch instruction"); } @@ -361,6 +366,12 @@ void SystemZLongBranch::relaxBranch(TerminatorInfo &Terminator) { case SystemZ::CGRJ: splitCompareBranch(Branch, SystemZ::CGR); break; + case SystemZ::CIJ: + splitCompareBranch(Branch, SystemZ::CHI); + break; + case SystemZ::CGIJ: + splitCompareBranch(Branch, SystemZ::CGHI); + break; default: llvm_unreachable("Unrecognized branch"); } |