diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZElimCompare.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrFormats.td | 91 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrInfo.td | 37 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZLongBranch.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZScheduleZ13.td | 9 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZScheduleZ196.td | 10 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td | 9 |
8 files changed, 153 insertions, 32 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp b/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp index 6b07c540400..b292b554779 100644 --- a/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp +++ b/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp @@ -171,7 +171,7 @@ static unsigned getCompareSourceReg(MachineInstr &Compare) { // Compare compares the result of MI against zero. If MI is an addition // of -1 and if CCUsers is a single branch on nonzero, eliminate the addition -// and convert the branch to a BRCT(G). Return true on success. +// and convert the branch to a BRCT(G) or BRCTH. Return true on success. bool SystemZElimCompare::convertToBRCT( MachineInstr &MI, MachineInstr &Compare, SmallVectorImpl<MachineInstr *> &CCUsers) { @@ -182,6 +182,8 @@ bool SystemZElimCompare::convertToBRCT( BRCT = SystemZ::BRCT; else if (Opcode == SystemZ::AGHI) BRCT = SystemZ::BRCTG; + else if (Opcode == SystemZ::AIH) + BRCT = SystemZ::BRCTH; else return false; if (MI.getOperand(2).getImm() != -1) @@ -205,16 +207,20 @@ bool SystemZElimCompare::convertToBRCT( if (getRegReferences(*MBBI, SrcReg)) return false; - // The transformation is OK. Rebuild Branch as a BRCT(G). + // The transformation is OK. Rebuild Branch as a BRCT(G) or BRCTH. MachineOperand Target(Branch->getOperand(2)); while (Branch->getNumOperands()) Branch->RemoveOperand(0); Branch->setDesc(TII->get(BRCT)); - MachineInstrBuilder(*Branch->getParent()->getParent(), Branch) - .addOperand(MI.getOperand(0)) - .addOperand(MI.getOperand(1)) - .addOperand(Target) - .addReg(SystemZ::CC, RegState::ImplicitDefine | RegState::Dead); + MachineInstrBuilder MIB(*Branch->getParent()->getParent(), Branch); + MIB.addOperand(MI.getOperand(0)) + .addOperand(MI.getOperand(1)) + .addOperand(Target); + // Add a CC def to BRCT(G), since we may have to split them again if the + // branch displacement overflows. BRCTH has a 32-bit displacement, so + // this is not necessary there. + if (BRCT != SystemZ::BRCTH) + MIB.addReg(SystemZ::CC, RegState::ImplicitDefine | RegState::Dead); MI.eraseFromParent(); return true; } diff --git a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td index 7a3aa40fc9d..a5c1c2680d5 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td +++ b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td @@ -291,6 +291,23 @@ class InstRIEd<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> let Inst{7-0} = op{7-0}; } +class InstRIEe<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<4> R3; + bits<16> RI2; + + let Inst{47-40} = op{15-8}; + let Inst{39-36} = R1; + let Inst{35-32} = R3; + let Inst{31-16} = RI2; + let Inst{15-8} = 0; + 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; @@ -1506,15 +1523,14 @@ class ICV<string name> // compares the two input operands and branches or traps on the result. // // BranchUnary: -// One register output operand, one register input operand and -// one branch displacement. The instructions stores a modified -// form of the source register in the destination register and -// branches on the result. +// One register output operand, one register input operand and one branch +// target. The instructions stores a modified form of the source register +// in the destination register and branches on the result. // // BranchBinary: // One register output operand, two register input operands and one branch -// displacement. The instructions stores a modified form of one of the -// source registers in the destination register and branches on the result. +// target. The instructions stores a modified form of one of the source +// registers in the destination register and branches on the result. // // LoadMultiple: // One address input operand and two explicit output operands. @@ -1911,6 +1927,41 @@ class BranchUnaryRI<string mnemonic, bits<12> opcode, RegisterOperand cls> let DisableEncoding = "$R1src"; } +class BranchUnaryRIL<string mnemonic, bits<12> opcode, RegisterOperand cls> + : InstRILb<opcode, (outs cls:$R1), (ins cls:$R1src, brtarget32:$RI2), + mnemonic##"\t$R1, $RI2", []> { + let Constraints = "$R1 = $R1src"; + let DisableEncoding = "$R1src"; +} + +class BranchUnaryRR<string mnemonic, bits<8> opcode, RegisterOperand cls> + : InstRR<opcode, (outs cls:$R1), (ins cls:$R1src, GR64:$R2), + mnemonic##"\t$R1, $R2", []> { + let Constraints = "$R1 = $R1src"; + let DisableEncoding = "$R1src"; +} + +class BranchUnaryRRE<string mnemonic, bits<16> opcode, RegisterOperand cls> + : InstRRE<opcode, (outs cls:$R1), (ins cls:$R1src, GR64:$R2), + mnemonic##"\t$R1, $R2", []> { + let Constraints = "$R1 = $R1src"; + let DisableEncoding = "$R1src"; +} + +class BranchUnaryRX<string mnemonic, bits<8> opcode, RegisterOperand cls> + : InstRXa<opcode, (outs cls:$R1), (ins cls:$R1src, bdxaddr12only:$XBD2), + mnemonic##"\t$R1, $XBD2", []> { + let Constraints = "$R1 = $R1src"; + let DisableEncoding = "$R1src"; +} + +class BranchUnaryRXY<string mnemonic, bits<16> opcode, RegisterOperand cls> + : InstRXYa<opcode, (outs cls:$R1), (ins cls:$R1src, bdxaddr20only:$XBD2), + mnemonic##"\t$R1, $XBD2", []> { + let Constraints = "$R1 = $R1src"; + let DisableEncoding = "$R1src"; +} + class BranchBinaryRSI<string mnemonic, bits<8> opcode, RegisterOperand cls> : InstRSI<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, brtarget16:$RI2), mnemonic##"\t$R1, $R3, $RI2", []> { @@ -1918,6 +1969,30 @@ class BranchBinaryRSI<string mnemonic, bits<8> opcode, RegisterOperand cls> let DisableEncoding = "$R1src"; } +class BranchBinaryRIEe<string mnemonic, bits<16> opcode, RegisterOperand cls> + : InstRIEe<opcode, (outs cls:$R1), + (ins cls:$R1src, cls:$R3, brtarget16:$RI2), + mnemonic##"\t$R1, $R3, $RI2", []> { + let Constraints = "$R1 = $R1src"; + let DisableEncoding = "$R1src"; +} + +class BranchBinaryRS<string mnemonic, bits<8> opcode, RegisterOperand cls> + : InstRSa<opcode, (outs cls:$R1), + (ins cls:$R1src, cls:$R3, bdaddr12only:$BD2), + mnemonic##"\t$R1, $R3, $BD2", []> { + let Constraints = "$R1 = $R1src"; + let DisableEncoding = "$R1src"; +} + +class BranchBinaryRSY<string mnemonic, bits<16> opcode, RegisterOperand cls> + : InstRSYa<opcode, + (outs cls:$R1), (ins cls:$R1src, cls:$R3, bdaddr20only:$BD2), + mnemonic##"\t$R1, $R3, $BD2", []> { + let Constraints = "$R1 = $R1src"; + let DisableEncoding = "$R1src"; +} + class LoadMultipleRS<string mnemonic, bits<8> opcode, RegisterOperand cls, AddressingMode mode = bdaddr12only> : InstRSa<opcode, (outs cls:$R1, cls:$R3), (ins mode:$BD2), @@ -3639,7 +3714,9 @@ multiclass BinaryRIAndKPseudo<string key, SDPatternOperator operator, // Like CompareRI, but expanded after RA depending on the choice of register. class CompareRIPseudo<SDPatternOperator operator, RegisterOperand cls, Immediate imm> - : Pseudo<(outs), (ins cls:$R1, imm:$I2), [(operator cls:$R1, imm:$I2)]>; + : Pseudo<(outs), (ins cls:$R1, imm:$I2), [(operator cls:$R1, imm:$I2)]> { + let isCompare = 1; +} // Like CompareRXY, but expanded after RA depending on the choice of register. class CompareRXYPseudo<SDPatternOperator operator, RegisterOperand cls, diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp index 8f1b5575902..7b835b04fd3 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -1321,6 +1321,10 @@ bool SystemZInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { expandRIPseudo(MI, SystemZ::AFI, SystemZ::AIH, false); return true; + case SystemZ::CHIMux: + expandRIPseudo(MI, SystemZ::CHI, SystemZ::CIH, false); + return true; + case SystemZ::CFIMux: expandRIPseudo(MI, SystemZ::CFI, SystemZ::CIH, false); return true; @@ -1386,6 +1390,7 @@ SystemZInstrInfo::getBranchInfo(const MachineInstr &MI) const { MI.getOperand(1).getImm(), &MI.getOperand(2)); case SystemZ::BRCT: + case SystemZ::BRCTH: return SystemZII::Branch(SystemZII::BranchCT, SystemZ::CCMASK_ICMP, SystemZ::CCMASK_CMP_NE, &MI.getOperand(2)); diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td index 28c8557c78d..87a70da6856 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td @@ -155,15 +155,33 @@ let isBranch = 1, isTerminator = 1 in { } // Decrement a register and branch if it is nonzero. These don't clobber CC, -// but we might need to split long branches into sequences that do. -let isBranch = 1, isTerminator = 1, Defs = [CC] in { - def BRCT : BranchUnaryRI<"brct", 0xA76, GR32>; - def BRCTG : BranchUnaryRI<"brctg", 0xA77, GR64>; +// but we might need to split long relative branches into sequences that do. +let isBranch = 1, isTerminator = 1 in { + let Defs = [CC] in { + def BRCT : BranchUnaryRI<"brct", 0xA76, GR32>; + def BRCTG : BranchUnaryRI<"brctg", 0xA77, GR64>; + } + // This doesn't need to clobber CC since we never need to split it. + def BRCTH : BranchUnaryRIL<"brcth", 0xCC6, GRH32>, + Requires<[FeatureHighWord]>; + + def BCT : BranchUnaryRX<"bct", 0x46,GR32>; + def BCTR : BranchUnaryRR<"bctr", 0x06, GR32>; + def BCTG : BranchUnaryRXY<"bctg", 0xE346, GR64>; + def BCTGR : BranchUnaryRRE<"bctgr", 0xB946, GR64>; } -let isBranch = 1, isTerminator = 1, Defs = [CC] in { - def BRXH : BranchBinaryRSI<"brxh", 0x84, GR32>; - def BRXLE : BranchBinaryRSI<"brxle", 0x85, GR32>; +let isBranch = 1, isTerminator = 1 in { + let Defs = [CC] in { + def BRXH : BranchBinaryRSI<"brxh", 0x84, GR32>; + def BRXLE : BranchBinaryRSI<"brxle", 0x85, GR32>; + def BRXHG : BranchBinaryRIEe<"brxhg", 0xEC44, GR64>; + def BRXLG : BranchBinaryRIEe<"brxlg", 0xEC45, GR64>; + } + def BXH : BranchBinaryRS<"bxh", 0x86, GR32>; + def BXLE : BranchBinaryRS<"bxle", 0x87, GR32>; + def BXHG : BranchBinaryRSY<"bxhg", 0xEB44, GR64>; + def BXLEG : BranchBinaryRSY<"bxleg", 0xEB45, GR64>; } //===----------------------------------------------------------------------===// @@ -1235,7 +1253,10 @@ let Defs = [CC], CCValues = 0xE in { def CGFR : CompareRRE<"cgfr", 0xB930, null_frag, GR64, GR32>; def CGR : CompareRRE<"cgr", 0xB920, z_scmp, GR64, GR64>; - // Comparison with a signed 16-bit immediate. + // Comparison with a signed 16-bit immediate. CHIMux expands to CHI or CIH, + // depending on the choice of register. + def CHIMux : CompareRIPseudo<z_scmp, GRX32, imm32sx16>, + Requires<[FeatureHighWord]>; def CHI : CompareRI<"chi", 0xA7E, z_scmp, GR32, imm32sx16>; def CGHI : CompareRI<"cghi", 0xA7F, z_scmp, GR64, imm64sx16>; diff --git a/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp b/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp index 0be0396034c..14ff6afbd4a 100644 --- a/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp +++ b/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp @@ -226,6 +226,10 @@ TerminatorInfo SystemZLongBranch::describeTerminator(MachineInstr &MI) { // Relaxes to A(G)HI and BRCL, which is 6 bytes longer. Terminator.ExtraRelaxSize = 6; break; + case SystemZ::BRCTH: + // Never needs to be relaxed. + Terminator.ExtraRelaxSize = 0; + break; case SystemZ::CRJ: case SystemZ::CLRJ: // Relaxes to a C(L)R/BRCL sequence, which is 2 bytes longer. diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td b/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td index 0030ed1f950..c9007e59bcb 100644 --- a/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td @@ -116,7 +116,10 @@ def : InstRW<[VBU], (instregex "(Call)?J(G)?(Asm.*)?$")>; def : InstRW<[FXb], (instregex "(Call)?BC(R)?(Asm.*)?$")>; def : InstRW<[FXb], (instregex "(Call)?B(R)?(Asm.*)?$")>; def : InstRW<[FXa, EndGroup], (instregex "BRCT(G)?$")>; -def : InstRW<[FXa, FXa, FXb, FXb, Lat4, GroupAlone], (instregex "BRX(H|LE)$")>; +def : InstRW<[FXb, FXa, Lat2, GroupAlone], (instregex "BRCTH$")>; +def : InstRW<[FXb, FXa, Lat2, GroupAlone], (instregex "BCT(G)?(R)?$")>; +def : InstRW<[FXa, FXa, FXb, FXb, Lat4, GroupAlone], + (instregex "B(R)?X(H|L).*$")>; // Compare and branch def : InstRW<[FXb], (instregex "C(L)?(G)?(I|R)J(Asm.*)?$")>; @@ -466,11 +469,11 @@ def : InstRW<[FXa, FXa, Lat3, BeginGroup], (instregex "R(N|O|X)SBG$")>; //===----------------------------------------------------------------------===// def : InstRW<[FXb, LSU, Lat5], (instregex "C(G|Y|Mux|RL)?$")>; -def : InstRW<[FXb], (instregex "CFI(Mux)?$")>; +def : InstRW<[FXb], (instregex "C(F|H)I(Mux)?$")>; def : InstRW<[FXb], (instregex "CG(F|H)I$")>; def : InstRW<[FXb, LSU, Lat5], (instregex "CG(HSI|RL)$")>; def : InstRW<[FXb], (instregex "C(G)?R$")>; -def : InstRW<[FXb], (instregex "C(HI|IH)$")>; +def : InstRW<[FXb], (instregex "CIH$")>; def : InstRW<[FXb, LSU, Lat5], (instregex "CH(F|SI)$")>; def : InstRW<[FXb, LSU, Lat5], (instregex "CL(Y|Mux|FHSI)?$")>; def : InstRW<[FXb], (instregex "CLFI(Mux)?$")>; diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td b/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td index 4d4a912b5d1..f8e0ccbcea0 100644 --- a/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td @@ -90,8 +90,10 @@ def : InstRW<[LSU, EndGroup], (instregex "(Call)?BRC(L)?(Asm.*)?$")>; def : InstRW<[LSU, EndGroup], (instregex "(Call)?J(G)?(Asm.*)?$")>; def : InstRW<[LSU, EndGroup], (instregex "(Call)?BC(R)?(Asm.*)?$")>; def : InstRW<[LSU, EndGroup], (instregex "(Call)?B(R)?(Asm.*)?$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "BRCT(G)?$")>; -def : InstRW<[FXU, FXU, FXU, LSU, Lat7, GroupAlone], (instregex "BRX(H|LE)$")>; +def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "BRCT(G|H)?$")>; +def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "BCT(G)?(R)?$")>; +def : InstRW<[FXU, FXU, FXU, LSU, Lat7, GroupAlone], + (instregex "B(R)?X(H|L).*$")>; // Compare and branch def : InstRW<[FXU, LSU, Lat5, GroupAlone], @@ -433,11 +435,11 @@ def : InstRW<[FXU, FXU, Lat3, GroupAlone], (instregex "R(N|O|X)SBG$")>; //===----------------------------------------------------------------------===// def : InstRW<[FXU, LSU, Lat5], (instregex "C(G|Y|Mux|RL)?$")>; -def : InstRW<[FXU], (instregex "CFI(Mux)?$")>; +def : InstRW<[FXU], (instregex "C(F|H)I(Mux)?$")>; def : InstRW<[FXU], (instregex "CG(F|H)I$")>; def : InstRW<[FXU, LSU, Lat5], (instregex "CG(HSI|RL)$")>; def : InstRW<[FXU], (instregex "C(G)?R$")>; -def : InstRW<[FXU], (instregex "C(HI|IH)$")>; +def : InstRW<[FXU], (instregex "CIH$")>; def : InstRW<[FXU, LSU, Lat5], (instregex "CH(F|SI)$")>; def : InstRW<[FXU, LSU, Lat5], (instregex "CL(Y|Mux|FHSI)?$")>; def : InstRW<[FXU], (instregex "CLFI(Mux)?$")>; diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td b/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td index 69c70bbe28f..73008749773 100644 --- a/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td @@ -93,7 +93,10 @@ def : InstRW<[VBU], (instregex "(Call)?J(G)?(Asm.*)?$")>; def : InstRW<[LSU, Lat4], (instregex "(Call)?BC(R)?(Asm.*)?$")>; def : InstRW<[LSU, Lat4], (instregex "(Call)?B(R)?(Asm.*)?$")>; def : InstRW<[FXU, EndGroup], (instregex "BRCT(G)?$")>; -def : InstRW<[FXU, FXU, FXU, LSU, Lat7, GroupAlone], (instregex "BRX(H|LE)$")>; +def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "BRCTH$")>; +def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "BCT(G)?(R)?$")>; +def : InstRW<[FXU, FXU, FXU, LSU, Lat7, GroupAlone], + (instregex "B(R)?X(H|L).*$")>; // Compare and branch def : InstRW<[FXU], (instregex "C(L)?(G)?(I|R)J(Asm.*)?$")>; @@ -436,11 +439,11 @@ def : InstRW<[FXU, FXU, Lat3, GroupAlone], (instregex "R(N|O|X)SBG$")>; //===----------------------------------------------------------------------===// def : InstRW<[FXU, LSU, Lat5], (instregex "C(G|Y|Mux|RL)?$")>; -def : InstRW<[FXU], (instregex "CFI(Mux)?$")>; +def : InstRW<[FXU], (instregex "C(F|H)I(Mux)?$")>; def : InstRW<[FXU], (instregex "CG(F|H)I$")>; def : InstRW<[FXU, LSU, Lat5], (instregex "CG(HSI|RL)$")>; def : InstRW<[FXU], (instregex "C(G)?R$")>; -def : InstRW<[FXU], (instregex "C(HI|IH)$")>; +def : InstRW<[FXU], (instregex "CIH$")>; def : InstRW<[FXU, LSU, Lat5], (instregex "CH(F|SI)$")>; def : InstRW<[FXU, LSU, Lat5], (instregex "CL(Y|Mux|FHSI)?$")>; def : InstRW<[FXU], (instregex "CLFI(Mux)?$")>; |