From d2148caffc1f8aa975e03370e6b441169d424625 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 8 Nov 2016 18:30:50 +0000 Subject: [PATCH] [SystemZ] Refactor branch and conditional instruction patterns Rework patterns for branches, call & return instructions, compare-and-branch, compare-and-trap, and conditional move instructions. In particular, simplify creation of patterns for the extended opcodes of instructions that take a CC mask. Also, use semantical instruction classes for all the instructions instead of open-coding them in SystemZInstrInfo.td. Adds a couple of the basic branch instructions (that are unused for codegen) for the assembler/disassembler. llvm-svn: 286263 --- llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 4 +- llvm/lib/Target/SystemZ/SystemZInstrFormats.td | 681 +++++++++++++++++++++--- llvm/lib/Target/SystemZ/SystemZInstrInfo.td | 625 +++++++++------------- llvm/lib/Target/SystemZ/SystemZScheduleZ13.td | 95 ++-- llvm/lib/Target/SystemZ/SystemZScheduleZ196.td | 94 ++-- llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td | 94 ++-- llvm/test/MC/Disassembler/SystemZ/insns.txt | 96 ++++ llvm/test/MC/SystemZ/insn-bad.s | 22 + llvm/test/MC/SystemZ/insn-good.s | 128 +++++ 9 files changed, 1224 insertions(+), 615 deletions(-) diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp index 5157021..b39245b 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -418,10 +418,10 @@ void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) { case SystemZ::Serialize: if (MF->getSubtarget().hasFastSerialization()) - LoweredMI = MCInstBuilder(SystemZ::AsmBCR) + LoweredMI = MCInstBuilder(SystemZ::BCRAsm) .addImm(14).addReg(SystemZ::R0D); else - LoweredMI = MCInstBuilder(SystemZ::AsmBCR) + LoweredMI = MCInstBuilder(SystemZ::BCRAsm) .addImm(15).addReg(SystemZ::R0D); break; diff --git a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td index ad7a7cf..aede549 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td +++ b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td @@ -191,6 +191,34 @@ class InstRI op, dag outs, dag ins, string asmstr, list pattern> let Inst{15-0} = I2; } +class InstRIb op, dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ<4, outs, ins, asmstr, pattern> { + field bits<32> Inst; + field bits<32> SoftFail = 0; + + bits<4> R1; + bits<16> RI2; + + let Inst{31-24} = op{11-4}; + let Inst{23-20} = R1; + let Inst{19-16} = op{3-0}; + let Inst{15-0} = RI2; +} + +class InstRIc op, dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ<4, outs, ins, asmstr, pattern> { + field bits<32> Inst; + field bits<32> SoftFail = 0; + + bits<4> M1; + bits<16> RI2; + + let Inst{31-24} = op{11-4}; + let Inst{23-20} = M1; + let Inst{19-16} = op{3-0}; + let Inst{15-0} = RI2; +} + class InstRIEa op, dag outs, dag ins, string asmstr, list pattern> : InstSystemZ<6, outs, ins, asmstr, pattern> { field bits<48> Inst; @@ -283,6 +311,23 @@ class InstRIEf op, dag outs, dag ins, string asmstr, list pattern> let Inst{7-0} = op{7-0}; } +class InstRIEg op, dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + field bits<48> SoftFail = 0; + + bits<4> R1; + bits<4> M3; + bits<16> I2; + + let Inst{47-40} = op{15-8}; + let Inst{39-36} = R1; + let Inst{35-32} = M3; + let Inst{31-16} = I2; + let Inst{15-8} = 0; + let Inst{7-0} = op{7-0}; +} + class InstRIL op, dag outs, dag ins, string asmstr, list pattern> : InstSystemZ<6, outs, ins, asmstr, pattern> { field bits<48> Inst; @@ -297,6 +342,34 @@ class InstRIL op, dag outs, dag ins, string asmstr, list pattern> let Inst{31-0} = I2; } +class InstRILb op, dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + field bits<48> SoftFail = 0; + + bits<4> R1; + bits<32> RI2; + + let Inst{47-40} = op{11-4}; + let Inst{39-36} = R1; + let Inst{35-32} = op{3-0}; + let Inst{31-0} = RI2; +} + +class InstRILc op, dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + field bits<48> SoftFail = 0; + + bits<4> M1; + bits<32> RI2; + + let Inst{47-40} = op{11-4}; + let Inst{39-36} = M1; + let Inst{35-32} = op{3-0}; + let Inst{31-0} = RI2; +} + class InstRIS op, dag outs, dag ins, string asmstr, list pattern> : InstSystemZ<6, outs, ins, asmstr, pattern> { field bits<48> Inst; @@ -425,6 +498,21 @@ class InstRX op, dag outs, dag ins, string asmstr, list pattern> let HasIndex = 1; } +class InstRXb op, dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ<4, outs, ins, asmstr, pattern> { + field bits<32> Inst; + field bits<32> SoftFail = 0; + + bits<4> M1; + bits<20> XBD2; + + let Inst{31-24} = op; + let Inst{23-20} = M1; + let Inst{19-0} = XBD2; + + let HasIndex = 1; +} + class InstRXE op, dag outs, dag ins, string asmstr, list pattern> : InstSystemZ<6, outs, ins, asmstr, pattern> { field bits<48> Inst; @@ -480,6 +568,23 @@ class InstRXY op, dag outs, dag ins, string asmstr, list pattern> let HasIndex = 1; } +class InstRXYb op, dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + field bits<48> SoftFail = 0; + + bits<4> M1; + bits<28> XBD2; + + let Inst{47-40} = op{15-8}; + let Inst{39-36} = M1; + let Inst{35-8} = XBD2; + let Inst{7-0} = op{7-0}; + + let Has20BitOffset = 1; + let HasIndex = 1; +} + class InstRS op, dag outs, dag ins, string asmstr, list pattern> : InstSystemZ<4, outs, ins, asmstr, pattern> { field bits<32> Inst; @@ -495,6 +600,21 @@ class InstRS op, dag outs, dag ins, string asmstr, list pattern> let Inst{15-0} = BD2; } +class InstRSb op, dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ<4, outs, ins, asmstr, pattern> { + field bits<32> Inst; + field bits<32> SoftFail = 0; + + bits<4> R1; + bits<4> M3; + bits<16> BD2; + + let Inst{31-24} = op; + let Inst{23-20} = R1; + let Inst{19-16} = M3; + let Inst{15-0} = BD2; +} + class InstRSI op, dag outs, dag ins, string asmstr, list pattern> : InstSystemZ<4, outs, ins, asmstr, pattern> { field bits<32> Inst; @@ -528,6 +648,24 @@ class InstRSY op, dag outs, dag ins, string asmstr, list pattern> let Has20BitOffset = 1; } +class InstRSYb op, dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + field bits<48> SoftFail = 0; + + bits<4> R1; + bits<4> M3; + bits<24> BD2; + + let Inst{47-40} = op{15-8}; + let Inst{39-36} = R1; + let Inst{35-32} = M3; + let Inst{31-8} = BD2; + let Inst{7-0} = op{7-0}; + + let Has20BitOffset = 1; +} + class InstSI op, dag outs, dag ins, string asmstr, list pattern> : InstSystemZ<4, outs, ins, asmstr, pattern> { field bits<32> Inst; @@ -1206,6 +1344,104 @@ class DirectiveInsnSSF pattern> } //===----------------------------------------------------------------------===// +// Variants of instructions with condition mask +//===----------------------------------------------------------------------===// +// +// For instructions using a condition mask (e.g. conditional branches, +// compare-and-branch instructions, or conditional move instructions), +// we generally need to create multiple instruction patterns: +// +// - One used for code generation, which encodes the condition mask as an +// MI operand, but writes out an extended mnemonic for better readability. +// - One pattern for the base form of the instruction with an explicit +// condition mask (encoded as a plain integer MI operand). +// - Specific patterns for each extended mnemonic, where the condition mask +// is implied by the pattern name and not otherwise encoded at all. +// +// We need the latter primarily for the assembler and disassembler, since the +// assembler parser is not able to decode part of an instruction mnemonic +// into an operand. Thus we provide separate patterns for each mnemonic. +// +// Note that in some cases there are two different mnemonics for the same +// condition mask. In this case we cannot have both instructions available +// to the disassembler at the same time since the encodings are not distinct. +// Therefore the alternate forms are marked isAsmParserOnly. +// +// We don't make one of the two names an alias of the other because +// we need the custom parsing routines to select the correct register class. +// +// This section provides helpers for generating the specific forms. +// +//===----------------------------------------------------------------------===// + +// A class to describe a variant of an instruction with condition mask. +class CondVariant ccmaskin, string suffixin, bit alternatein> { + // The fixed condition mask to use. + bits<4> ccmask = ccmaskin; + + // The suffix to use for the extended assembler mnemonic. + string suffix = suffixin; + + // Whether this is an alternate that needs to be marked isAsmParserOnly. + bit alternate = alternatein; +} + +// Condition mask 15 means "always true", which is used to define +// unconditional branches as a variant of conditional branches. +def CondAlways : CondVariant<15, "", 0>; + +// Condition masks for general instructions that can set all 4 bits. +def CondVariantO : CondVariant<1, "o", 0>; +def CondVariantH : CondVariant<2, "h", 0>; +def CondVariantP : CondVariant<2, "p", 1>; +def CondVariantNLE : CondVariant<3, "nle", 0>; +def CondVariantL : CondVariant<4, "l", 0>; +def CondVariantM : CondVariant<4, "m", 1>; +def CondVariantNHE : CondVariant<5, "nhe", 0>; +def CondVariantLH : CondVariant<6, "lh", 0>; +def CondVariantNE : CondVariant<7, "ne", 0>; +def CondVariantNZ : CondVariant<7, "nz", 1>; +def CondVariantE : CondVariant<8, "e", 0>; +def CondVariantZ : CondVariant<8, "z", 1>; +def CondVariantNLH : CondVariant<9, "nlh", 0>; +def CondVariantHE : CondVariant<10, "he", 0>; +def CondVariantNL : CondVariant<11, "nl", 0>; +def CondVariantNM : CondVariant<11, "nm", 1>; +def CondVariantLE : CondVariant<12, "le", 0>; +def CondVariantNH : CondVariant<13, "nh", 0>; +def CondVariantNP : CondVariant<13, "np", 1>; +def CondVariantNO : CondVariant<14, "no", 0>; + +// A helper class to look up one of the above by name. +class CV + : CondVariant("CondVariant"#name).ccmask, + !cast("CondVariant"#name).suffix, + !cast("CondVariant"#name).alternate>; + +// Condition masks for integer instructions (e.g. compare-and-branch). +// This is like the list above, except that condition 3 is not possible +// and that the low bit of the mask is therefore always 0. This means +// that each condition has two names. Conditions "o" and "no" are not used. +def IntCondVariantH : CondVariant<2, "h", 0>; +def IntCondVariantNLE : CondVariant<2, "nle", 1>; +def IntCondVariantL : CondVariant<4, "l", 0>; +def IntCondVariantNHE : CondVariant<4, "nhe", 1>; +def IntCondVariantLH : CondVariant<6, "lh", 0>; +def IntCondVariantNE : CondVariant<6, "ne", 1>; +def IntCondVariantE : CondVariant<8, "e", 0>; +def IntCondVariantNLH : CondVariant<8, "nlh", 1>; +def IntCondVariantHE : CondVariant<10, "he", 0>; +def IntCondVariantNL : CondVariant<10, "nl", 1>; +def IntCondVariantLE : CondVariant<12, "le", 0>; +def IntCondVariantNH : CondVariant<12, "nh", 1>; + +// A helper class to look up one of the above by name. +class ICV + : CondVariant("IntCondVariant"#name).ccmask, + !cast("IntCondVariant"#name).suffix, + !cast("IntCondVariant"#name).alternate>; + +//===----------------------------------------------------------------------===// // Instruction definitions with semantics //===----------------------------------------------------------------------===// // @@ -1218,6 +1454,17 @@ class DirectiveInsnSSF pattern> // Inherent: // One register output operand and no input operands. // +// Branch: +// One branch target. The instruction branches to the target. +// +// Call: +// One output operand and one branch target. The instruction stores +// the return address to the output operand and branches to the target. +// +// CmpBranch: +// Two input operands and one optional branch target. The instruction +// 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 @@ -1314,11 +1561,257 @@ class InherentVRIa opcode, bits<16> value> let M3 = 0; } +// Allow an optional TLS marker symbol to generate TLS call relocations. +class CallRI opcode> + : InstRIb; + +// Allow an optional TLS marker symbol to generate TLS call relocations. +class CallRIL opcode> + : InstRILb; + +class CallRR opcode> + : InstRR; + +class CallRX opcode> + : InstRX; + +class CondBranchRI opcode, + SDPatternOperator operator = null_frag> + : InstRIc { + let CCMaskFirst = 1; +} + +class AsmCondBranchRI opcode> + : InstRIc; + +class FixedCondBranchRI opcode, + SDPatternOperator operator = null_frag> + : InstRIc { + let isAsmParserOnly = V.alternate; + let M1 = V.ccmask; +} + +class CondBranchRIL opcode> + : InstRILc { + let CCMaskFirst = 1; +} + +class AsmCondBranchRIL opcode> + : InstRILc; + +class FixedCondBranchRIL opcode> + : InstRILc { + let isAsmParserOnly = V.alternate; + let M1 = V.ccmask; +} + +class CondBranchRR opcode> + : InstRR { + let CCMaskFirst = 1; +} + +class AsmCondBranchRR opcode> + : InstRR; + +class FixedCondBranchRR opcode, + SDPatternOperator operator = null_frag> + : InstRR { + let isAsmParserOnly = V.alternate; + let R1 = V.ccmask; +} + +class CondBranchRX opcode> + : InstRXb { + let CCMaskFirst = 1; +} + +class AsmCondBranchRX opcode> + : InstRXb; + +class FixedCondBranchRX opcode> + : InstRXb { + let isAsmParserOnly = V.alternate; + let M1 = V.ccmask; +} + +class CmpBranchRIEa opcode, + RegisterOperand cls, Immediate imm> + : InstRIEa; + +class AsmCmpBranchRIEa opcode, + RegisterOperand cls, Immediate imm> + : InstRIEa; + +class FixedCmpBranchRIEa opcode, + RegisterOperand cls, Immediate imm> + : InstRIEa { + let isAsmParserOnly = V.alternate; + let M3 = V.ccmask; +} + +multiclass CmpBranchRIEaPair opcode, + RegisterOperand cls, Immediate imm> { + let isCodeGenOnly = 1 in + def "" : CmpBranchRIEa; + def Asm : AsmCmpBranchRIEa; +} + +class CmpBranchRIEb opcode, + RegisterOperand cls> + : InstRIEb; + +class AsmCmpBranchRIEb opcode, + RegisterOperand cls> + : InstRIEb; + +class FixedCmpBranchRIEb opcode, + RegisterOperand cls> + : InstRIEb { + let isAsmParserOnly = V.alternate; + let M3 = V.ccmask; +} + +multiclass CmpBranchRIEbPair opcode, + RegisterOperand cls> { + let isCodeGenOnly = 1 in + def "" : CmpBranchRIEb; + def Asm : AsmCmpBranchRIEb; +} + +class CmpBranchRIEc opcode, + RegisterOperand cls, Immediate imm> + : InstRIEc; + +class AsmCmpBranchRIEc opcode, + RegisterOperand cls, Immediate imm> + : InstRIEc; + +class FixedCmpBranchRIEc opcode, + RegisterOperand cls, Immediate imm> + : InstRIEc { + let isAsmParserOnly = V.alternate; + let M3 = V.ccmask; +} + +multiclass CmpBranchRIEcPair opcode, + RegisterOperand cls, Immediate imm> { + let isCodeGenOnly = 1 in + def "" : CmpBranchRIEc; + def Asm : AsmCmpBranchRIEc; +} + +class CmpBranchRRFc opcode, + RegisterOperand cls> + : InstRRFc; + +class AsmCmpBranchRRFc opcode, + RegisterOperand cls> + : InstRRFc; + +multiclass CmpBranchRRFcPair opcode, + RegisterOperand cls> { + let isCodeGenOnly = 1 in + def "" : CmpBranchRRFc; + def Asm : AsmCmpBranchRRFc; +} + +class FixedCmpBranchRRFc opcode, + RegisterOperand cls> + : InstRRFc { + let isAsmParserOnly = V.alternate; + let M3 = V.ccmask; +} + +class CmpBranchRRS opcode, + RegisterOperand cls> + : InstRRS; + +class AsmCmpBranchRRS opcode, + RegisterOperand cls> + : InstRRS; + +class FixedCmpBranchRRS opcode, + RegisterOperand cls> + : InstRRS { + let isAsmParserOnly = V.alternate; + let M3 = V.ccmask; +} + +multiclass CmpBranchRRSPair opcode, + RegisterOperand cls> { + let isCodeGenOnly = 1 in + def "" : CmpBranchRRS; + def Asm : AsmCmpBranchRRS; +} + +class CmpBranchRIS opcode, + RegisterOperand cls, Immediate imm> + : InstRIS; + +class AsmCmpBranchRIS opcode, + RegisterOperand cls, Immediate imm> + : InstRIS; + +class FixedCmpBranchRIS opcode, + RegisterOperand cls, Immediate imm> + : InstRIS { + let isAsmParserOnly = V.alternate; + let M3 = V.ccmask; +} + +multiclass CmpBranchRISPair opcode, + RegisterOperand cls, Immediate imm> { + let isCodeGenOnly = 1 in + def "" : CmpBranchRIS; + def Asm : AsmCmpBranchRIS; +} + class BranchUnaryRI opcode, RegisterOperand cls> - : InstRI { - let isBranch = 1; - let isTerminator = 1; + : InstRIb { let Constraints = "$R1 = $R1src"; let DisableEncoding = "$R1src"; } @@ -1326,8 +1819,6 @@ class BranchUnaryRI opcode, RegisterOperand cls> class BranchBinaryRSI opcode, RegisterOperand cls> : InstRSI { - let isBranch = 1; - let isTerminator = 1; let Constraints = "$R1 = $R1src"; let DisableEncoding = "$R1src"; } @@ -1365,9 +1856,9 @@ class LoadMultipleVRSa opcode> class StoreRILPC opcode, SDPatternOperator operator, RegisterOperand cls> - : InstRIL { + : InstRILb { let mayStore = 1; // We want PC-relative addresses to be tried ahead of BD and BDX addresses. // However, BDXs have two extra operands and are therefore 6 units more @@ -1505,9 +1996,8 @@ multiclass StoreSIPair siOpcode, bits<16> siyOpcode, class CondStoreRSY opcode, RegisterOperand cls, bits<5> bytes, AddressingMode mode = bdaddr20only> - : InstRSY, - Requires<[FeatureLoadStoreOnCond]> { + : InstRSYb { let mayStore = 1; let AccessBytes = bytes; let CCMaskLast = 1; @@ -1518,23 +2008,30 @@ class CondStoreRSY opcode, class AsmCondStoreRSY opcode, RegisterOperand cls, bits<5> bytes, AddressingMode mode = bdaddr20only> - : InstRSY, - Requires<[FeatureLoadStoreOnCond]> { + : InstRSYb { let mayStore = 1; let AccessBytes = bytes; } // Like CondStoreRSY, but with a fixed CC mask. -class FixedCondStoreRSY opcode, - RegisterOperand cls, bits<4> ccmask, bits<5> bytes, +class FixedCondStoreRSY opcode, + RegisterOperand cls, bits<5> bytes, AddressingMode mode = bdaddr20only> - : InstRSY, - Requires<[FeatureLoadStoreOnCond]> { + : InstRSYb { let mayStore = 1; let AccessBytes = bytes; - let R3 = ccmask; + let isAsmParserOnly = V.alternate; + let M3 = V.ccmask; +} + +multiclass CondStoreRSYPair opcode, + RegisterOperand cls, bits<5> bytes, + AddressingMode mode = bdaddr20only> { + let isCodeGenOnly = 1 in + def "" : CondStoreRSY; + def Asm : AsmCondStoreRSY; } class UnaryRR opcode, SDPatternOperator operator, @@ -1573,19 +2070,15 @@ class UnaryRRF4 opcode, RegisterOperand cls1, // is added as an implicit use. class CondUnaryRRF opcode, RegisterOperand cls1, RegisterOperand cls2> - : InstRRF, - Requires<[FeatureLoadStoreOnCond]> { + : InstRRFc { let CCMaskLast = 1; - let R4 = 0; } class CondUnaryRIE opcode, RegisterOperand cls, Immediate imm> - : InstRIEd, - Requires<[FeatureLoadStoreOnCond2]> { + : InstRIEg { let CCMaskLast = 1; } @@ -1593,45 +2086,55 @@ class CondUnaryRIE opcode, RegisterOperand cls, // mask is the third operand rather than being part of the mnemonic. class AsmCondUnaryRRF opcode, RegisterOperand cls1, RegisterOperand cls2> - : InstRRF, - Requires<[FeatureLoadStoreOnCond]> { + : InstRRFc { let Constraints = "$R1 = $R1src"; let DisableEncoding = "$R1src"; - let R4 = 0; } class AsmCondUnaryRIE opcode, RegisterOperand cls, Immediate imm> - : InstRIEd, - Requires<[FeatureLoadStoreOnCond2]> { + : InstRIEg { 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]> { +class FixedCondUnaryRRF opcode, + RegisterOperand cls1, RegisterOperand cls2> + : InstRRFc { let Constraints = "$R1 = $R1src"; let DisableEncoding = "$R1src"; - let R3 = ccmask; - let R4 = 0; + let isAsmParserOnly = V.alternate; + let M3 = V.ccmask; } -class FixedCondUnaryRIE opcode, RegisterOperand cls, - Immediate imm, bits<4> ccmask> - : InstRIEd, - Requires<[FeatureLoadStoreOnCond2]> { +class FixedCondUnaryRIE opcode, + RegisterOperand cls, Immediate imm> + : InstRIEg { let Constraints = "$R1 = $R1src"; let DisableEncoding = "$R1src"; - let R3 = ccmask; + let isAsmParserOnly = V.alternate; + let M3 = V.ccmask; +} + +multiclass CondUnaryRRFPair opcode, + RegisterOperand cls1, RegisterOperand cls2> { + let isCodeGenOnly = 1 in + def "" : CondUnaryRRF; + def Asm : AsmCondUnaryRRF; +} + +multiclass CondUnaryRIEPair opcode, + RegisterOperand cls, Immediate imm> { + let isCodeGenOnly = 1 in + def "" : CondUnaryRIE; + def Asm : AsmCondUnaryRIE; } class UnaryRI opcode, SDPatternOperator operator, @@ -1648,9 +2151,9 @@ class UnaryRIL opcode, SDPatternOperator operator, class UnaryRILPC opcode, SDPatternOperator operator, RegisterOperand cls> - : InstRIL { + : InstRILb { let mayLoad = 1; // We want PC-relative addresses to be tried ahead of BD and BDX addresses. // However, BDXs have two extra operands and are therefore 6 units more @@ -1661,13 +2164,12 @@ class UnaryRILPC opcode, SDPatternOperator operator, class CondUnaryRSY opcode, SDPatternOperator operator, RegisterOperand cls, bits<5> bytes, AddressingMode mode = bdaddr20only> - : InstRSY, - Requires<[FeatureLoadStoreOnCond]> { + : InstRSYb { let Constraints = "$R1 = $R1src"; let DisableEncoding = "$R1src"; let mayLoad = 1; @@ -1680,9 +2182,8 @@ class CondUnaryRSY opcode, class AsmCondUnaryRSY opcode, RegisterOperand cls, bits<5> bytes, AddressingMode mode = bdaddr20only> - : InstRSY, - Requires<[FeatureLoadStoreOnCond]> { + : InstRSYb { let mayLoad = 1; let AccessBytes = bytes; let Constraints = "$R1 = $R1src"; @@ -1690,19 +2191,29 @@ class AsmCondUnaryRSY opcode, } // Like CondUnaryRSY, but with a fixed CC mask. -class FixedCondUnaryRSY opcode, - RegisterOperand cls, bits<4> ccmask, bits<5> bytes, +class FixedCondUnaryRSY opcode, + RegisterOperand cls, bits<5> bytes, AddressingMode mode = bdaddr20only> - : InstRSY, - Requires<[FeatureLoadStoreOnCond]> { + : InstRSYb { let Constraints = "$R1 = $R1src"; let DisableEncoding = "$R1src"; - let R3 = ccmask; let mayLoad = 1; let AccessBytes = bytes; + let isAsmParserOnly = V.alternate; + let M3 = V.ccmask; } +multiclass CondUnaryRSYPair opcode, + SDPatternOperator operator, + RegisterOperand cls, bits<5> bytes, + AddressingMode mode = bdaddr20only> { + let isCodeGenOnly = 1 in + def "" : CondUnaryRSY; + def Asm : AsmCondUnaryRSY; +} + + class UnaryRX opcode, SDPatternOperator operator, RegisterOperand cls, bits<5> bytes, AddressingMode mode = bdxaddr12only> @@ -2321,9 +2832,9 @@ class CompareRIL opcode, SDPatternOperator operator, class CompareRILPC opcode, SDPatternOperator operator, RegisterOperand cls, SDPatternOperator load> - : InstRIL { + : InstRILb { let isCompare = 1; let mayLoad = 1; // We want PC-relative addresses to be tried ahead of BD and BDX addresses. @@ -2473,9 +2984,9 @@ class TernaryRRD opcode, class TernaryRS opcode, RegisterOperand cls, bits<5> bytes, AddressingMode mode = bdaddr12only> - : InstRS { + : InstRSb { let Constraints = "$R1 = $R1src"; let DisableEncoding = "$R1src"; @@ -2485,9 +2996,9 @@ class TernaryRS opcode, RegisterOperand cls, class TernaryRSY opcode, RegisterOperand cls, bits<5> bytes, AddressingMode mode = bdaddr20only> - : InstRSY { + : InstRSYb { let Constraints = "$R1 = $R1src"; let DisableEncoding = "$R1src"; @@ -2815,15 +3326,15 @@ class RotateSelectRIEf opcode, RegisterOperand cls1, } class PrefetchRXY opcode, SDPatternOperator operator> - : InstRXY; + : InstRXYb; class PrefetchRILPC opcode, SDPatternOperator operator> - : InstRIL { + : InstRILc { // We want PC-relative addresses to be tried ahead of BD and BDX addresses. // However, BDXs have two extra operands and are therefore 6 units more // complex. diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td index 7a966ba..0dba1b5 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td @@ -31,351 +31,199 @@ let hasSideEffects = 0 in { } //===----------------------------------------------------------------------===// -// Control flow instructions +// Branch instructions //===----------------------------------------------------------------------===// -// A return instruction (br %r14). -let isReturn = 1, isTerminator = 1, isBarrier = 1, hasCtrlDep = 1 in - def Return : Alias<2, (outs), (ins), [(z_retflag)]>; - -// A conditional return instruction (bcr , %r14). -let isReturn = 1, isTerminator = 1, hasCtrlDep = 1, CCMaskFirst = 1, Uses = [CC] in - def CondReturn : Alias<2, (outs), (ins cond4:$valid, cond4:$R1), []>; - -// Fused compare and conditional returns. -let isReturn = 1, isTerminator = 1, hasCtrlDep = 1 in { - def CRBReturn : Alias<6, (outs), (ins GR32:$R1, GR32:$R2, cond4:$M3), []>; - def CGRBReturn : Alias<6, (outs), (ins GR64:$R1, GR64:$R2, cond4:$M3), []>; - def CIBReturn : Alias<6, (outs), (ins GR32:$R1, imm32sx8:$I2, cond4:$M3), []>; - def CGIBReturn : Alias<6, (outs), (ins GR64:$R1, imm64sx8:$I2, cond4:$M3), []>; - def CLRBReturn : Alias<6, (outs), (ins GR32:$R1, GR32:$R2, cond4:$M3), []>; - def CLGRBReturn : Alias<6, (outs), (ins GR64:$R1, GR64:$R2, cond4:$M3), []>; - def CLIBReturn : Alias<6, (outs), (ins GR32:$R1, imm32zx8:$I2, cond4:$M3), []>; - def CLGIBReturn : Alias<6, (outs), (ins GR64:$R1, imm64zx8:$I2, cond4:$M3), []>; -} - -// Unconditional branches. R1 is the condition-code mask (all 1s). -let isBranch = 1, isTerminator = 1, isBarrier = 1, R1 = 15 in { - let isIndirectBranch = 1 in - def BR : InstRR<0x07, (outs), (ins ADDR64:$R2), - "br\t$R2", [(brind ADDR64:$R2)]>; - - // An assembler extended mnemonic for BRC. - def J : InstRI<0xA74, (outs), (ins brtarget16:$I2), "j\t$I2", - [(br bb:$I2)]>; - - // An assembler extended mnemonic for BRCL. (The extension is "G" - // rather than "L" because "JL" is "Jump if Less".) - def JG : InstRIL<0xC04, (outs), (ins brtarget32:$I2), "jg\t$I2", []>; -} +// Conditional branches. +let isBranch = 1, isTerminator = 1, Uses = [CC] in { + // It's easier for LLVM to handle these branches in their raw BRC/BRCL form + // with the condition-code mask being the first operand. It seems friendlier + // to use mnemonic forms like JE and JLH when writing out the assembly though. + let isCodeGenOnly = 1 in { + // An assembler extended mnemonic for BRC. + def BRC : CondBranchRI <"j#", 0xA74, z_br_ccmask>; + // An assembler extended mnemonic for BRCL. (The extension is "G" + // rather than "L" because "JL" is "Jump if Less".) + def BRCL : CondBranchRIL<"jg#", 0xC04>; + let isIndirectBranch = 1 in { + def BC : CondBranchRX<"b#", 0x47>; + def BCR : CondBranchRR<"b#r", 0x07>; + } + } -// FIXME: This trap instruction should be marked as isTerminator, but there is -// currently a general bug that allows non-terminators to be placed between -// terminators. Temporarily leave this unmarked until the bug is fixed. -let isBarrier = 1, hasCtrlDep = 1 in { - def Trap : Alias<4, (outs), (ins), [(trap)]>; -} + // Allow using the raw forms directly from the assembler (and occasional + // special code generation needs) as well. + def BRCAsm : AsmCondBranchRI <"brc", 0xA74>; + def BRCLAsm : AsmCondBranchRIL<"brcl", 0xC04>; + let isIndirectBranch = 1 in { + def BCAsm : AsmCondBranchRX<"bc", 0x47>; + def BCRAsm : AsmCondBranchRR<"bcr", 0x07>; + } -let isTerminator = 1, hasCtrlDep = 1, Uses = [CC] in { - def CondTrap : Alias<4, (outs), (ins cond4:$valid, cond4:$R1), []>; + // Define AsmParser extended mnemonics for each general condition-code mask + // (integer or floating-point) + foreach V = [ "E", "NE", "H", "NH", "L", "NL", "HE", "NHE", "LE", "NLE", + "Z", "NZ", "P", "NP", "M", "NM", "LH", "NLH", "O", "NO" ] in { + def JAsm#V : FixedCondBranchRI , "j#", 0xA74>; + def JGAsm#V : FixedCondBranchRIL, "jg#", 0xC04>; + let isIndirectBranch = 1 in { + def BAsm#V : FixedCondBranchRX , "b#", 0x47>; + def BRAsm#V : FixedCondBranchRR , "b#r", 0x07>; + } + } } -// Conditional branches. It's easier for LLVM to handle these branches -// in their raw BRC/BRCL form, with the 4-bit condition-code mask being -// the first operand. It seems friendlier to use mnemonic forms like -// JE and JLH when writing out the assembly though. -let isBranch = 1, isTerminator = 1, Uses = [CC] in { - let isCodeGenOnly = 1, CCMaskFirst = 1 in { - def BRC : InstRI<0xA74, (outs), (ins cond4:$valid, cond4:$R1, - brtarget16:$I2), "j$R1\t$I2", - [(z_br_ccmask cond4:$valid, cond4:$R1, bb:$I2)]>; - def BRCL : InstRIL<0xC04, (outs), (ins cond4:$valid, cond4:$R1, - brtarget32:$I2), "jg$R1\t$I2", []>; - let isIndirectBranch = 1 in - def BCR : InstRR<0x07, (outs), (ins cond4:$valid, cond4:$R1, GR64:$R2), - "b${R1}r\t$R2", []>; - } - def AsmBRC : InstRI<0xA74, (outs), (ins imm32zx4:$R1, brtarget16:$I2), - "brc\t$R1, $I2", []>; - def AsmBRCL : InstRIL<0xC04, (outs), (ins imm32zx4:$R1, brtarget32:$I2), - "brcl\t$R1, $I2", []>; +// Unconditional branches. These are in fact simply variants of the +// conditional branches with the condition mask set to "always". +let isBranch = 1, isTerminator = 1, isBarrier = 1 in { + def J : FixedCondBranchRI ; + def JG : FixedCondBranchRIL; let isIndirectBranch = 1 in { - def AsmBC : InstRX<0x47, (outs), (ins imm32zx4:$R1, bdxaddr12only:$XBD2), - "bc\t$R1, $XBD2", []>; - def AsmBCR : InstRR<0x07, (outs), (ins imm32zx4:$R1, GR64:$R2), - "bcr\t$R1, $R2", []>; + def B : FixedCondBranchRX; + def BR : FixedCondBranchRR; } } -def AsmNop : InstAlias<"nop\t$XBD", (AsmBC 0, bdxaddr12only:$XBD), 0>; -def AsmNopR : InstAlias<"nopr\t$R", (AsmBCR 0, GR64:$R), 0>; +// NOPs. These are again variants of the conditional branches, +// with the condition mask set to "never". +def NOP : InstAlias<"nop\t$XBD", (BCAsm 0, bdxaddr12only:$XBD), 0>; +def NOPR : InstAlias<"nopr\t$R", (BCRAsm 0, GR64:$R), 0>; -// Fused compare-and-branch instructions. As for normal branches, -// we handle these instructions internally in their raw CRJ-like form, -// but use assembly macros like CRJE when writing them out. +// Fused compare-and-branch instructions. // // These instructions do not use or clobber the condition codes. -// We nevertheless pretend that they clobber CC, so that we can lower -// them to separate comparisons and BRCLs if the branch ends up being -// out of range. -multiclass CompareBranches { - 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", []>; - def GRJ : InstRIEb<0xEC64, (outs), (ins GR64:$R1, GR64:$R2, ccmask:$M3, - brtarget16:$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", []>; - def LRJ : InstRIEb<0xEC77, (outs), (ins GR32:$R1, GR32:$R2, ccmask:$M3, - brtarget16:$RI4), - "clrj"##pos1##"\t$R1, $R2"##pos2##", $RI4", []>; - def LGRJ : InstRIEb<0xEC65, (outs), (ins GR64:$R1, GR64:$R2, ccmask:$M3, - brtarget16:$RI4), - "clgrj"##pos1##"\t$R1, $R2"##pos2##", $RI4", []>; - def LIJ : InstRIEc<0xEC7F, (outs), (ins GR32:$R1, imm32zx8:$I2, ccmask:$M3, - brtarget16:$RI4), - "clij"##pos1##"\t$R1, $I2"##pos2##", $RI4", []>; - def LGIJ : InstRIEc<0xEC7D, (outs), (ins GR64:$R1, imm64zx8:$I2, ccmask:$M3, - brtarget16:$RI4), - "clgij"##pos1##"\t$R1, $I2"##pos2##", $RI4", []>; - let isIndirectBranch = 1 in { - def RB : InstRRS<0xECF6, (outs), (ins GR32:$R1, GR32:$R2, ccmask:$M3, - bdaddr12only:$BD4), - "crb"##pos1##"\t$R1, $R2"##pos2##", $BD4", []>; - def GRB : InstRRS<0xECE4, (outs), (ins GR64:$R1, GR64:$R2, ccmask:$M3, - bdaddr12only:$BD4), - "cgrb"##pos1##"\t$R1, $R2"##pos2##", $BD4", []>; - def IB : InstRIS<0xECFE, (outs), (ins GR32:$R1, imm32sx8:$I2, ccmask:$M3, - bdaddr12only:$BD4), - "cib"##pos1##"\t$R1, $I2"##pos2##", $BD4", []>; - def GIB : InstRIS<0xECFC, (outs), (ins GR64:$R1, imm64sx8:$I2, ccmask:$M3, - bdaddr12only:$BD4), - "cgib"##pos1##"\t$R1, $I2"##pos2##", $BD4", []>; - def LRB : InstRRS<0xECF7, (outs), (ins GR32:$R1, GR32:$R2, ccmask:$M3, - bdaddr12only:$BD4), - "clrb"##pos1##"\t$R1, $R2"##pos2##", $BD4", []>; - def LGRB : InstRRS<0xECE5, (outs), (ins GR64:$R1, GR64:$R2, ccmask:$M3, - bdaddr12only:$BD4), - "clgrb"##pos1##"\t$R1, $R2"##pos2##", $BD4", []>; - def LIB : InstRIS<0xECFF, (outs), (ins GR32:$R1, imm32zx8:$I2, ccmask:$M3, - bdaddr12only:$BD4), - "clib"##pos1##"\t$R1, $I2"##pos2##", $BD4", []>; - def LGIB : InstRIS<0xECFD, (outs), (ins GR64:$R1, imm64zx8:$I2, ccmask:$M3, - bdaddr12only:$BD4), - "clgib"##pos1##"\t$R1, $I2"##pos2##", $BD4", []>; - } - } - - let isTerminator = 1, hasCtrlDep = 1 in { - def RT : InstRRFc<0xB972, (outs), (ins GR32:$R1, GR32:$R2, ccmask:$M3), - "crt"##pos1##"\t$R1, $R2"##pos2, []>; - def GRT : InstRRFc<0xB960, (outs), (ins GR64:$R1, GR64:$R2, ccmask:$M3), - "cgrt"##pos1##"\t$R1, $R2"##pos2, []>; - def LRT : InstRRFc<0xB973, (outs), (ins GR32:$R1, GR32:$R2, ccmask:$M3), - "clrt"##pos1##"\t$R1, $R2"##pos2, []>; - def LGRT : InstRRFc<0xB961, (outs), (ins GR64:$R1, GR64:$R2, ccmask:$M3), - "clgrt"##pos1##"\t$R1, $R2"##pos2, []>; - def IT : InstRIEa<0xEC72, (outs), (ins GR32:$R1, imm32sx16:$I2, ccmask:$M3), - "cit"##pos1##"\t$R1, $I2"##pos2, []>; - def GIT : InstRIEa<0xEC70, (outs), (ins GR64:$R1, imm32sx16:$I2, ccmask:$M3), - "cgit"##pos1##"\t$R1, $I2"##pos2, []>; - def LFIT : InstRIEa<0xEC73, (outs), (ins GR32:$R1, imm32zx16:$I2, ccmask:$M3), - "clfit"##pos1##"\t$R1, $I2"##pos2, []>; - def LGIT : InstRIEa<0xEC71, (outs), (ins GR64:$R1, imm32zx16:$I2, ccmask:$M3), - "clgit"##pos1##"\t$R1, $I2"##pos2, []>; +// We nevertheless pretend that the relative compare-and-branch +// instructions clobber CC, so that we can lower them to separate +// comparisons and BRCLs if the branch ends up being out of range. +let isBranch = 1, isTerminator = 1 in { + // As for normal branches, we handle these instructions internally in + // their raw CRJ-like form, but use assembly macros like CRJE when writing + // them out. Using the *Pair multiclasses, we also create the raw forms. + let Defs = [CC] in { + defm CRJ : CmpBranchRIEbPair<"crj", 0xEC76, GR32>; + defm CGRJ : CmpBranchRIEbPair<"cgrj", 0xEC64, GR64>; + defm CIJ : CmpBranchRIEcPair<"cij", 0xEC7E, GR32, imm32sx8>; + defm CGIJ : CmpBranchRIEcPair<"cgij", 0xEC7C, GR64, imm64sx8>; + defm CLRJ : CmpBranchRIEbPair<"clrj", 0xEC77, GR32>; + defm CLGRJ : CmpBranchRIEbPair<"clgrj", 0xEC65, GR64>; + defm CLIJ : CmpBranchRIEcPair<"clij", 0xEC7F, GR32, imm32zx8>; + defm CLGIJ : CmpBranchRIEcPair<"clgij", 0xEC7D, GR64, imm64zx8>; } -} -let isCodeGenOnly = 1 in - defm C : CompareBranches; -defm AsmC : CompareBranches; - -// Define AsmParser mnemonics for each general condition-code mask -// (integer or floating-point) -multiclass CondExtendedMnemonicA ccmask, string name> { - let isBranch = 1, isTerminator = 1, R1 = ccmask in { - def J : InstRI<0xA74, (outs), (ins brtarget16:$I2), - "j"##name##"\t$I2", []>; - def JG : InstRIL<0xC04, (outs), (ins brtarget32:$I2), - "jg"##name##"\t$I2", []>; - def BR : InstRR<0x07, (outs), (ins ADDR64:$R2), "b"##name##"r\t$R2", []>; + let isIndirectBranch = 1 in { + defm CRB : CmpBranchRRSPair<"crb", 0xECF6, GR32>; + defm CGRB : CmpBranchRRSPair<"cgrb", 0xECE4, GR64>; + defm CIB : CmpBranchRISPair<"cib", 0xECFE, GR32, imm32sx8>; + defm CGIB : CmpBranchRISPair<"cgib", 0xECFC, GR64, imm64sx8>; + defm CLRB : CmpBranchRRSPair<"clrb", 0xECF7, GR32>; + defm CLGRB : CmpBranchRRSPair<"clgrb", 0xECE5, GR64>; + defm CLIB : CmpBranchRISPair<"clib", 0xECFF, GR32, imm32zx8>; + defm CLGIB : CmpBranchRISPair<"clgib", 0xECFD, GR64, imm64zx8>; } - def LOCR : FixedCondUnaryRRF<"locr"##name, 0xB9F2, GR32, GR32, ccmask>; - def LOCGR : FixedCondUnaryRRF<"locgr"##name, 0xB9E2, GR64, GR64, ccmask>; - def LOCHI : FixedCondUnaryRIE<"lochi"##name, 0xEC42, GR64, imm32sx16, - ccmask>; - def LOCGHI: FixedCondUnaryRIE<"locghi"##name, 0xEC46, GR64, imm64sx16, - 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>; - def STOCG : FixedCondStoreRSY<"stocg"##name, 0xEBE3, GR64, ccmask, 8>; -} - -multiclass CondExtendedMnemonic ccmask, string name1, string name2> - : CondExtendedMnemonicA { - let isAsmParserOnly = 1 in - defm Alt : CondExtendedMnemonicA; -} - -defm AsmO : CondExtendedMnemonicA<1, "o">; -defm AsmH : CondExtendedMnemonic<2, "h", "p">; -defm AsmNLE : CondExtendedMnemonicA<3, "nle">; -defm AsmL : CondExtendedMnemonic<4, "l", "m">; -defm AsmNHE : CondExtendedMnemonicA<5, "nhe">; -defm AsmLH : CondExtendedMnemonicA<6, "lh">; -defm AsmNE : CondExtendedMnemonic<7, "ne", "nz">; -defm AsmE : CondExtendedMnemonic<8, "e", "z">; -defm AsmNLH : CondExtendedMnemonicA<9, "nlh">; -defm AsmHE : CondExtendedMnemonicA<10, "he">; -defm AsmNL : CondExtendedMnemonic<11, "nl", "nm">; -defm AsmLE : CondExtendedMnemonicA<12, "le">; -defm AsmNH : CondExtendedMnemonic<13, "nh", "np">; -defm AsmNO : CondExtendedMnemonicA<14, "no">; - -// Define AsmParser mnemonics for each integer condition-code mask. -// This is like the list above, except that condition 3 is not possible -// and that the low bit of the mask is therefore always 0. This means -// that each condition has two names. Conditions "o" and "no" are not used. -// -// We don't make one of the two names an alias of the other because -// we need the custom parsing routines to select the correct register class. -multiclass IntCondExtendedMnemonicA ccmask, string name> { - let isBranch = 1, isTerminator = 1, M3 = ccmask in { - def CRJ : InstRIEb<0xEC76, (outs), (ins GR32:$R1, GR32:$R2, - brtarget16:$RI4), - "crj"##name##"\t$R1, $R2, $RI4", []>; - def CGRJ : InstRIEb<0xEC64, (outs), (ins GR64:$R1, GR64:$R2, - brtarget16:$RI4), - "cgrj"##name##"\t$R1, $R2, $RI4", []>; - def CIJ : InstRIEc<0xEC7E, (outs), (ins GR32:$R1, imm32sx8:$I2, - brtarget16:$RI4), - "cij"##name##"\t$R1, $I2, $RI4", []>; - def CGIJ : InstRIEc<0xEC7C, (outs), (ins GR64:$R1, imm64sx8:$I2, - brtarget16:$RI4), - "cgij"##name##"\t$R1, $I2, $RI4", []>; - def CLRJ : InstRIEb<0xEC77, (outs), (ins GR32:$R1, GR32:$R2, - brtarget16:$RI4), - "clrj"##name##"\t$R1, $R2, $RI4", []>; - def CLGRJ : InstRIEb<0xEC65, (outs), (ins GR64:$R1, GR64:$R2, - brtarget16:$RI4), - "clgrj"##name##"\t$R1, $R2, $RI4", []>; - def CLIJ : InstRIEc<0xEC7F, (outs), (ins GR32:$R1, imm32zx8:$I2, - brtarget16:$RI4), - "clij"##name##"\t$R1, $I2, $RI4", []>; - def CLGIJ : InstRIEc<0xEC7D, (outs), (ins GR64:$R1, imm64zx8:$I2, - brtarget16:$RI4), - "clgij"##name##"\t$R1, $I2, $RI4", []>; + + // Define AsmParser mnemonics for each integer condition-code mask. + foreach V = [ "E", "H", "L", "HE", "LE", "LH", + "NE", "NH", "NL", "NHE", "NLE", "NLH" ] in { + let Defs = [CC] in { + def CRJAsm#V : FixedCmpBranchRIEb, "crj", 0xEC76, GR32>; + def CGRJAsm#V : FixedCmpBranchRIEb, "cgrj", 0xEC64, GR64>; + def CIJAsm#V : FixedCmpBranchRIEc, "cij", 0xEC7E, GR32, + imm32sx8>; + def CGIJAsm#V : FixedCmpBranchRIEc, "cgij", 0xEC7C, GR64, + imm64sx8>; + def CLRJAsm#V : FixedCmpBranchRIEb, "clrj", 0xEC77, GR32>; + def CLGRJAsm#V : FixedCmpBranchRIEb, "clgrj", 0xEC65, GR64>; + def CLIJAsm#V : FixedCmpBranchRIEc, "clij", 0xEC7F, GR32, + imm32zx8>; + def CLGIJAsm#V : FixedCmpBranchRIEc, "clgij", 0xEC7D, GR64, + imm64zx8>; + } let isIndirectBranch = 1 in { - def CRB : InstRRS<0xECF6, (outs), (ins GR32:$R1, GR32:$R2, - bdaddr12only:$BD4), - "crb"##name##"\t$R1, $R2, $BD4", []>; - def CGRB : InstRRS<0xECE4, (outs), (ins GR64:$R1, GR64:$R2, - bdaddr12only:$BD4), - "cgrb"##name##"\t$R1, $R2, $BD4", []>; - def CIB : InstRIS<0xECFE, (outs), (ins GR32:$R1, imm32sx8:$I2, - bdaddr12only:$BD4), - "cib"##name##"\t$R1, $I2, $BD4", []>; - def CGIB : InstRIS<0xECFC, (outs), (ins GR64:$R1, imm64sx8:$I2, - bdaddr12only:$BD4), - "cgib"##name##"\t$R1, $I2, $BD4", []>; - def CLRB : InstRRS<0xECF7, (outs), (ins GR32:$R1, GR32:$R2, - bdaddr12only:$BD4), - "clrb"##name##"\t$R1, $R2, $BD4", []>; - def CLGRB : InstRRS<0xECE5, (outs), (ins GR64:$R1, GR64:$R2, - bdaddr12only:$BD4), - "clgrb"##name##"\t$R1, $R2, $BD4", []>; - def CLIB : InstRIS<0xECFF, (outs), (ins GR32:$R1, imm32zx8:$I2, - bdaddr12only:$BD4), - "clib"##name##"\t$R1, $I2, $BD4", []>; - def CLGIB : InstRIS<0xECFD, (outs), (ins GR64:$R1, imm64zx8:$I2, - bdaddr12only:$BD4), - "clgib"##name##"\t$R1, $I2, $BD4", []>; + def CRBAsm#V : FixedCmpBranchRRS, "crb", 0xECF6, GR32>; + def CGRBAsm#V : FixedCmpBranchRRS, "cgrb", 0xECE4, GR64>; + def CIBAsm#V : FixedCmpBranchRIS, "cib", 0xECFE, GR32, + imm32sx8>; + def CGIBAsm#V : FixedCmpBranchRIS, "cgib", 0xECFC, GR64, + imm64sx8>; + def CLRBAsm#V : FixedCmpBranchRRS, "clrb", 0xECF7, GR32>; + def CLGRBAsm#V : FixedCmpBranchRRS, "clgrb", 0xECE5, GR64>; + def CLIBAsm#V : FixedCmpBranchRIS, "clib", 0xECFF, GR32, + imm32zx8>; + def CLGIBAsm#V : FixedCmpBranchRIS, "clgib", 0xECFD, GR64, + imm64zx8>; } } - - let hasCtrlDep = 1, isTerminator = 1, M3 = ccmask in { - def CRT : InstRRFc<0xB972, (outs), (ins GR32:$R1, GR32:$R2), - "crt"##name##"\t$R1, $R2", []>; - def CGRT : InstRRFc<0xB960, (outs), (ins GR64:$R1, GR64:$R2), - "cgrt"##name##"\t$R1, $R2", []>; - def CLRT : InstRRFc<0xB973, (outs), (ins GR32:$R1, GR32:$R2), - "clrt"##name##"\t$R1, $R2", []>; - def CLGRT : InstRRFc<0xB961, (outs), (ins GR64:$R1, GR64:$R2), - "clgrt"##name##"\t$R1, $R2", []>; - def CIT : InstRIEa<0xEC72, (outs), (ins GR32:$R1, imm32sx16:$I2), - "cit"##name##"\t$R1, $I2", []>; - def CGIT : InstRIEa<0xEC70, (outs), (ins GR64:$R1, imm32sx16:$I2), - "cgit"##name##"\t$R1, $I2", []>; - def CLFIT : InstRIEa<0xEC73, (outs), (ins GR32:$R1, imm32zx16:$I2), - "clfit"##name##"\t$R1, $I2", []>; - def CLGIT : InstRIEa<0xEC71, (outs), (ins GR64:$R1, imm32zx16:$I2), - "clgit"##name##"\t$R1, $I2", []>; - } } -multiclass IntCondExtendedMnemonic ccmask, string name1, string name2> - : IntCondExtendedMnemonicA { - let isAsmParserOnly = 1 in - defm Alt : IntCondExtendedMnemonicA; -} -defm AsmJH : IntCondExtendedMnemonic<2, "h", "nle">; -defm AsmJL : IntCondExtendedMnemonic<4, "l", "nhe">; -defm AsmJLH : IntCondExtendedMnemonic<6, "lh", "ne">; -defm AsmJE : IntCondExtendedMnemonic<8, "e", "nlh">; -defm AsmJHE : IntCondExtendedMnemonic<10, "he", "nl">; -defm AsmJLE : IntCondExtendedMnemonic<12, "le", "nh">; // 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 Defs = [CC] in { +let isBranch = 1, isTerminator = 1, Defs = [CC] in { def BRCT : BranchUnaryRI<"brct", 0xA76, GR32>; def BRCTG : BranchUnaryRI<"brctg", 0xA77, GR64>; } -def BRXH : BranchBinaryRSI<"brxh", 0x84, GR64>; -def BRXLE : BranchBinaryRSI<"brxle", 0x85, GR64>; +let isBranch = 1, isTerminator = 1, Defs = [CC] in { + def BRXH : BranchBinaryRSI<"brxh", 0x84, GR32>; + def BRXLE : BranchBinaryRSI<"brxle", 0x85, GR32>; +} //===----------------------------------------------------------------------===// -// Select instructions +// Trap instructions //===----------------------------------------------------------------------===// -def Select32Mux : SelectWrapper, Requires<[FeatureHighWord]>; -def Select32 : SelectWrapper; -def Select64 : SelectWrapper; +// Unconditional trap. +// FIXME: This trap instruction should be marked as isTerminator, but there is +// currently a general bug that allows non-terminators to be placed between +// terminators. Temporarily leave this unmarked until the bug is fixed. +let isBarrier = 1, hasCtrlDep = 1 in + def Trap : Alias<4, (outs), (ins), [(trap)]>; -// We don't define 32-bit Mux stores because the low-only STOC should -// always be used if possible. -defm CondStore8Mux : CondStores, - Requires<[FeatureHighWord]>; -defm CondStore16Mux : CondStores, - Requires<[FeatureHighWord]>; -defm CondStore8 : CondStores; -defm CondStore16 : CondStores; -defm CondStore32 : CondStores; +// Conditional trap. +let isTerminator = 1, hasCtrlDep = 1, Uses = [CC] in + def CondTrap : Alias<4, (outs), (ins cond4:$valid, cond4:$R1), []>; -defm : CondStores64; -defm : CondStores64; -defm : CondStores64; -defm CondStore64 : CondStores; +// Fused compare-and-trap instructions. +let isTerminator = 1, hasCtrlDep = 1 in { + // These patterns work the same way as for compare-and-branch. + defm CRT : CmpBranchRRFcPair<"crt", 0xB972, GR32>; + defm CGRT : CmpBranchRRFcPair<"cgrt", 0xB960, GR64>; + defm CLRT : CmpBranchRRFcPair<"clrt", 0xB973, GR32>; + defm CLGRT : CmpBranchRRFcPair<"clgrt", 0xB961, GR64>; + defm CIT : CmpBranchRIEaPair<"cit", 0xEC72, GR32, imm32sx16>; + defm CGIT : CmpBranchRIEaPair<"cgit", 0xEC70, GR64, imm64sx16>; + defm CLFIT : CmpBranchRIEaPair<"clfit", 0xEC73, GR32, imm32zx16>; + defm CLGIT : CmpBranchRIEaPair<"clgit", 0xEC71, GR64, imm64zx16>; + + foreach V = [ "E", "H", "L", "HE", "LE", "LH", + "NE", "NH", "NL", "NHE", "NLE", "NLH" ] in { + def CRTAsm#V : FixedCmpBranchRRFc, "crt", 0xB972, GR32>; + def CGRTAsm#V : FixedCmpBranchRRFc, "cgrt", 0xB960, GR64>; + def CLRTAsm#V : FixedCmpBranchRRFc, "clrt", 0xB973, GR32>; + def CLGRTAsm#V : FixedCmpBranchRRFc, "clgrt", 0xB961, GR64>; + def CITAsm#V : FixedCmpBranchRIEa, "cit", 0xEC72, GR32, + imm32sx16>; + def CGITAsm#V : FixedCmpBranchRIEa, "cgit", 0xEC70, GR64, + imm64sx16>; + def CLFITAsm#V : FixedCmpBranchRIEa, "clfit", 0xEC73, GR32, + imm32zx16>; + def CLGITAsm#V : FixedCmpBranchRIEa, "clgit", 0xEC71, GR64, + imm64zx16>; + } +} //===----------------------------------------------------------------------===// -// Call instructions +// Call and return instructions //===----------------------------------------------------------------------===// +// Define the general form of the call instructions for the asm parser. +// These instructions don't hard-code %r14 as the return address register. +let isCall = 1, Defs = [CC] in { + def BRAS : CallRI <"bras", 0xA75>; + def BRASL : CallRIL<"brasl", 0xC05>; + def BAS : CallRX <"bas", 0x4D>; + def BASR : CallRR <"basr", 0x0D>; +} + +// Regular calls. let isCall = 1, Defs = [R14D, CC] in { def CallBRASL : Alias<6, (outs), (ins pcrel32:$I2, variable_ops), [(z_call pcrel32:$I2)]>; @@ -383,6 +231,15 @@ let isCall = 1, Defs = [R14D, CC] in { [(z_call ADDR64:$R2)]>; } +// TLS calls. These will be lowered into a call to __tls_get_offset, +// with an extra relocation specifying the TLS symbol. +let isCall = 1, Defs = [R14D, CC] in { + def TLS_GDCALL : Alias<6, (outs), (ins tlssym:$I2, variable_ops), + [(z_tls_gdcall tglobaltlsaddr:$I2)]>; + def TLS_LDCALL : Alias<6, (outs), (ins tlssym:$I2, variable_ops), + [(z_tls_ldcall tglobaltlsaddr:$I2)]>; +} + // Sibling calls. Indirect sibling calls must be via R1, since R2 upwards // are argument registers and since branching to R0 is a no-op. let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in { @@ -392,10 +249,10 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in { def CallBR : Alias<2, (outs), (ins), [(z_sibcall R1D)]>; } +// Conditional sibling calls. let CCMaskFirst = 1, isCall = 1, isTerminator = 1, isReturn = 1 in { def CallBRCL : Alias<6, (outs), (ins cond4:$valid, cond4:$R1, pcrel32:$I2), []>; - let Uses = [R1D] in def CallBCR : Alias<2, (outs), (ins cond4:$valid, cond4:$R1), []>; } @@ -412,28 +269,59 @@ let isCall = 1, isTerminator = 1, isReturn = 1, Uses = [R1D] in { def CLGIBCall : Alias<6, (outs), (ins GR64:$R1, imm64zx8:$I2, cond4:$M3), []>; } -// TLS calls. These will be lowered into a call to __tls_get_offset, -// with an extra relocation specifying the TLS symbol. -let isCall = 1, Defs = [R14D, CC] in { - def TLS_GDCALL : Alias<6, (outs), (ins tlssym:$I2, variable_ops), - [(z_tls_gdcall tglobaltlsaddr:$I2)]>; - def TLS_LDCALL : Alias<6, (outs), (ins tlssym:$I2, variable_ops), - [(z_tls_ldcall tglobaltlsaddr:$I2)]>; -} +// A return instruction (br %r14). +let isReturn = 1, isTerminator = 1, isBarrier = 1, hasCtrlDep = 1 in + def Return : Alias<2, (outs), (ins), [(z_retflag)]>; -// Define the general form of the call instructions for the asm parser. -// These instructions don't hard-code %r14 as the return address register. -// Allow an optional TLS marker symbol to generate TLS call relocations. -let isCall = 1, Defs = [CC] in { - def BRAS : InstRI<0xA75, (outs), (ins GR64:$R1, brtarget16tls:$I2), - "bras\t$R1, $I2", []>; - def BRASL : InstRIL<0xC05, (outs), (ins GR64:$R1, brtarget32tls:$I2), - "brasl\t$R1, $I2", []>; - def BASR : InstRR<0x0D, (outs), (ins GR64:$R1, ADDR64:$R2), - "basr\t$R1, $R2", []>; +// A conditional return instruction (bcr , %r14). +let isReturn = 1, isTerminator = 1, hasCtrlDep = 1, CCMaskFirst = 1, Uses = [CC] in + def CondReturn : Alias<2, (outs), (ins cond4:$valid, cond4:$R1), []>; + +// Fused compare and conditional returns. +let isReturn = 1, isTerminator = 1, hasCtrlDep = 1 in { + def CRBReturn : Alias<6, (outs), (ins GR32:$R1, GR32:$R2, cond4:$M3), []>; + def CGRBReturn : Alias<6, (outs), (ins GR64:$R1, GR64:$R2, cond4:$M3), []>; + def CIBReturn : Alias<6, (outs), (ins GR32:$R1, imm32sx8:$I2, cond4:$M3), []>; + def CGIBReturn : Alias<6, (outs), (ins GR64:$R1, imm64sx8:$I2, cond4:$M3), []>; + def CLRBReturn : Alias<6, (outs), (ins GR32:$R1, GR32:$R2, cond4:$M3), []>; + def CLGRBReturn : Alias<6, (outs), (ins GR64:$R1, GR64:$R2, cond4:$M3), []>; + def CLIBReturn : Alias<6, (outs), (ins GR32:$R1, imm32zx8:$I2, cond4:$M3), []>; + def CLGIBReturn : Alias<6, (outs), (ins GR64:$R1, imm64zx8:$I2, cond4:$M3), []>; } //===----------------------------------------------------------------------===// +// Select instructions +//===----------------------------------------------------------------------===// + +def Select32Mux : SelectWrapper, Requires<[FeatureHighWord]>; +def Select32 : SelectWrapper; +def Select64 : SelectWrapper; + +// We don't define 32-bit Mux stores because the low-only STOC should +// always be used if possible. +defm CondStore8Mux : CondStores, + Requires<[FeatureHighWord]>; +defm CondStore16Mux : CondStores, + Requires<[FeatureHighWord]>; +defm CondStore8 : CondStores; +defm CondStore16 : CondStores; +defm CondStore32 : CondStores; + +defm : CondStores64; +defm : CondStores64; +defm : CondStores64; +defm CondStore64 : CondStores; + +//===----------------------------------------------------------------------===// // Move instructions //===----------------------------------------------------------------------===// @@ -450,24 +338,6 @@ let Defs = [CC], CCValues = 0xE, CompareZeroCCMask = 0xE in { def LTGR : UnaryRRE<"ltg", 0xB902, 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>; -} -let isCodeGenOnly = 1, Uses = [CC] in { - def LOCHI : CondUnaryRIE<"lochi", 0xEC42, GR32, imm32sx16>; - def LOCGHI : CondUnaryRIE<"locghi", 0xEC46, GR64, imm64sx16>; -} -let Uses = [CC] in { - def AsmLOCHI : AsmCondUnaryRIE<"lochi", 0xEC42, GR32, imm32sx16>; - def AsmLOCGHI : AsmCondUnaryRIE<"locghi", 0xEC46, GR64, imm64sx16>; -} - // Immediate moves. let hasSideEffects = 0, isAsCheapAsAMove = 1, isMoveImm = 1, isReMaterializable = 1 in { @@ -517,16 +387,6 @@ let canFoldAsLoad = 1 in { def LGRL : UnaryRILPC<"lgrl", 0xC48, aligned_load, GR64>; } -// Load on condition. -let isCodeGenOnly = 1, Uses = [CC] in { - def LOC : CondUnaryRSY<"loc", 0xEBF2, nonvolatile_load, GR32, 4>; - def LOCG : CondUnaryRSY<"locg", 0xEBE2, nonvolatile_load, GR64, 8>; -} -let Uses = [CC] in { - def AsmLOC : AsmCondUnaryRSY<"loc", 0xEBF2, GR32, 4>; - def AsmLOCG : AsmCondUnaryRSY<"locg", 0xEBE2, GR64, 8>; -} - // Register stores. let SimpleBDXStore = 1 in { // Expands to ST, STY or STFH, depending on the choice of register. @@ -547,16 +407,6 @@ let SimpleBDXStore = 1 in { def STRL : StoreRILPC<"strl", 0xC4F, aligned_store, GR32>; def STGRL : StoreRILPC<"stgrl", 0xC4B, aligned_store, GR64>; -// Store on condition. -let isCodeGenOnly = 1, Uses = [CC] in { - def STOC : CondStoreRSY<"stoc", 0xEBF3, GR32, 4>; - def STOCG : CondStoreRSY<"stocg", 0xEBE3, GR64, 8>; -} -let Uses = [CC] in { - def AsmSTOC : AsmCondStoreRSY<"stoc", 0xEBF3, GR32, 4>; - def AsmSTOCG : AsmCondStoreRSY<"stocg", 0xEBE3, GR64, 8>; -} - // 8-bit immediate stores to 8-bit fields. defm MVI : StoreSIPair<"mvi", 0x92, 0xEB52, truncstorei8, imm32zx8trunc>; @@ -574,6 +424,49 @@ let mayLoad = 1, mayStore = 1, Defs = [CC] in defm MVST : StringRRE<"mvst", 0xB255, z_stpcpy>; //===----------------------------------------------------------------------===// +// Conditional move instructions +//===----------------------------------------------------------------------===// + +let Predicates = [FeatureLoadStoreOnCond2], Uses = [CC] in { + // Load immediate on condition. Created by if-conversion. + defm LOCHI : CondUnaryRIEPair<"lochi", 0xEC42, GR32, imm32sx16>; + defm LOCGHI : CondUnaryRIEPair<"locghi", 0xEC46, GR64, imm64sx16>; + + // Define AsmParser extended mnemonics for each general condition-code mask. + foreach V = [ "E", "NE", "H", "NH", "L", "NL", "HE", "NHE", "LE", "NLE", + "Z", "NZ", "P", "NP", "M", "NM", "LH", "NLH", "O", "NO" ] in { + def LOCHIAsm#V : FixedCondUnaryRIE, "lochi", 0xEC42, GR32, + imm32sx16>; + def LOCGHIAsm#V : FixedCondUnaryRIE, "locghi", 0xEC46, GR64, + imm64sx16>; + } +} + +let Predicates = [FeatureLoadStoreOnCond], Uses = [CC] in { + // Move register on condition. Created by if-conversion. + defm LOCR : CondUnaryRRFPair<"locr", 0xB9F2, GR32, GR32>; + defm LOCGR : CondUnaryRRFPair<"locgr", 0xB9E2, GR64, GR64>; + + // Load on condition. Matched via DAG pattern. + defm LOC : CondUnaryRSYPair<"loc", 0xEBF2, nonvolatile_load, GR32, 4>; + defm LOCG : CondUnaryRSYPair<"locg", 0xEBE2, nonvolatile_load, GR64, 8>; + + // Store on condition. Expanded from CondStore* pseudos. + defm STOC : CondStoreRSYPair<"stoc", 0xEBF3, GR32, 4>; + defm STOCG : CondStoreRSYPair<"stocg", 0xEBE3, GR64, 8>; + + // Define AsmParser extended mnemonics for each general condition-code mask. + foreach V = [ "E", "NE", "H", "NH", "L", "NL", "HE", "NHE", "LE", "NLE", + "Z", "NZ", "P", "NP", "M", "NM", "LH", "NLH", "O", "NO" ] in { + def LOCRAsm#V : FixedCondUnaryRRF, "locr", 0xB9F2, GR32, GR32>; + def LOCGRAsm#V : FixedCondUnaryRRF, "locgr", 0xB9E2, GR64, GR64>; + def LOCAsm#V : FixedCondUnaryRSY, "loc", 0xEBF2, GR32, 4>; + def LOCGAsm#V : FixedCondUnaryRSY, "locg", 0xEBE2, GR64, 8>; + def STOCAsm#V : FixedCondStoreRSY, "stoc", 0xEBF3, GR32, 4>; + def STOCGAsm#V : FixedCondStoreRSY, "stocg", 0xEBE3, GR64, 8>; + } +} +//===----------------------------------------------------------------------===// // Sign extensions //===----------------------------------------------------------------------===// // diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td b/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td index 211fbde..f010f6d 100644 --- a/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td @@ -107,51 +107,47 @@ def : WriteRes; // Virtual Branching Unit def : InstRW<[FXa], (instregex "ADJDYNALLOC$")>; // Pseudo -> LA / LAY //===----------------------------------------------------------------------===// -// Control flow instructions +// Branch instructions //===----------------------------------------------------------------------===// -// Return -def : InstRW<[FXb, EndGroup], (instregex "Return$")>; -def : InstRW<[FXb], (instregex "CondReturn$")>; - -// Compare and branch -def : InstRW<[FXb], (instregex "(Asm.*)?C(I|R)J$")>; -def : InstRW<[FXb], (instregex "(Asm.*)?CG(I|R)J$")>; -def : InstRW<[FXb], (instregex "(Asm.*)?CL(I|R)J$")>; -def : InstRW<[FXb], (instregex "(Asm.*)?CLG(I|R)J$")>; -def : InstRW<[FXb], (instregex "(Asm.*)?CG(R|I)J$")>; -def : InstRW<[FXb], (instregex "CLR$")>; -def : InstRW<[FXb, FXb, Lat2, GroupAlone], (instregex "(Asm.*)?CIB(Call|Return)?$")>; -def : InstRW<[FXb, FXb, Lat2, GroupAlone], (instregex "(Asm.*)?CLIB(Call|Return)?$")>; -def : InstRW<[FXb, FXb, Lat2, GroupAlone], (instregex "(Asm.*)?CLGIB(Call|Return)?$")>; -def : InstRW<[FXb, FXb, Lat2, GroupAlone], (instregex "(Asm.*)?CGIB(Call|Return)?$")>; -def : InstRW<[FXb, FXb, Lat2, GroupAlone], (instregex "(Asm.*)?CGRB(Call|Return)?$")>; -def : InstRW<[FXb, FXb, Lat2, GroupAlone], (instregex "(Asm.*)?CLGRB(Call|Return)?$")>; -def : InstRW<[FXb, FXb, Lat2, GroupAlone], (instregex "CLR(Call|Return)?$")>; -def : InstRW<[FXb, FXb, Lat2, GroupAlone], (instregex "(Asm.*)?CLRB(Call|Return)?$")>; -def : InstRW<[FXb, FXb, Lat2, GroupAlone], (instregex "(Asm.*)?CRB(Call|Return)?$")>; - // Branch -def : InstRW<[FXb], (instregex "(Asm.*)?BR$")>; -def : InstRW<[FXb], (instregex "(Asm)?BC(R)?$")>; -def : InstRW<[VBU], (instregex "(Asm)?BRC(L)?$")>; +def : InstRW<[VBU], (instregex "(Call)?BRC(L)?(Asm.*)?$")>; +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<[VBU], (instregex "(Asm.*)?JG$")>; -def : InstRW<[VBU], (instregex "J$")>; -// (Need to avoid conflict with "(Asm.*)?CG(I|R)J$") -def : InstRW<[VBU], (instregex "Asm(EAlt|E|HAlt|HE|H|LAlt|LE|LH|L|NEAlt|NE)J$")>; -def : InstRW<[VBU], (instregex "Asm(NHAlt|NHE|NH|NLAlt|NLE|NLH|NL|NO|O)J$")>; def : InstRW<[FXa, FXa, FXb, FXb, Lat4, GroupAlone], (instregex "BRX(H|LE)$")>; +// Compare and branch +def : InstRW<[FXb], (instregex "C(L)?(G)?(I|R)J(Asm.*)?$")>; +def : InstRW<[FXb, FXb, Lat2, GroupAlone], + (instregex "C(L)?(G)?(I|R)B(Call|Return|Asm.*)?$")>; + +//===----------------------------------------------------------------------===// +// Trap instructions +//===----------------------------------------------------------------------===// + // Trap def : InstRW<[VBU], (instregex "(Cond)?Trap$")>; // Compare and trap -def : InstRW<[FXb], (instregex "(Asm.*)?C(G)?IT$")>; -def : InstRW<[FXb], (instregex "(Asm.*)?C(G)?RT$")>; -def : InstRW<[FXb], (instregex "(Asm.*)?CLG(I|R)T$")>; -def : InstRW<[FXb], (instregex "(Asm.*)?CLFIT$")>; -def : InstRW<[FXb], (instregex "(Asm.*)?CLRT$")>; +def : InstRW<[FXb], (instregex "C(G)?(I|R)T(Asm.*)?$")>; +def : InstRW<[FXb], (instregex "CL(G)?RT(Asm.*)?$")>; +def : InstRW<[FXb], (instregex "CL(F|G)IT(Asm.*)?$")>; + +//===----------------------------------------------------------------------===// +// Call and return instructions +//===----------------------------------------------------------------------===// + +// Call +def : InstRW<[VBU, FXa, FXa, Lat3, GroupAlone], (instregex "(Call)?BRAS$")>; +def : InstRW<[FXa, FXa, FXb, Lat3, GroupAlone], (instregex "(Call)?BRASL$")>; +def : InstRW<[FXa, FXa, FXb, Lat3, GroupAlone], (instregex "(Call)?BAS(R)?$")>; +def : InstRW<[FXa, FXa, FXb, Lat3, GroupAlone], (instregex "TLS_(G|L)DCALL$")>; + +// Return +def : InstRW<[FXb, EndGroup], (instregex "Return$")>; +def : InstRW<[FXb], (instregex "CondReturn$")>; //===----------------------------------------------------------------------===// // Select instructions @@ -169,18 +165,6 @@ def : InstRW<[FXa], (instregex "CondStore8(Inv)?$")>; def : InstRW<[FXa], (instregex "CondStore8Mux(Inv)?$")>; //===----------------------------------------------------------------------===// -// Call instructions -//===----------------------------------------------------------------------===// - -def : InstRW<[VBU, FXa, FXa, Lat3, GroupAlone], (instregex "BRAS$")>; -def : InstRW<[FXa, FXa, FXb, Lat3, GroupAlone], (instregex "(Call)?BASR$")>; -def : InstRW<[FXb], (instregex "CallB(C)?R$")>; -def : InstRW<[FXa, FXa, FXb, Lat3, GroupAlone], (instregex "(Call)?BRASL$")>; -def : InstRW<[FXa, FXa, FXb, Lat3, GroupAlone], (instregex "TLS_(G|L)DCALL$")>; -def : InstRW<[VBU], (instregex "CallBRCL$")>; -def : InstRW<[VBU], (instregex "CallJG$")>; - -//===----------------------------------------------------------------------===// // Move instructions //===----------------------------------------------------------------------===// @@ -214,23 +198,24 @@ def : InstRW<[FXa], (instregex "LR(Mux)?$")>; def : InstRW<[FXa, LSU, Lat5], (instregex "LT(G)?$")>; def : InstRW<[FXa], (instregex "LT(G)?R$")>; -// Load on condition -def : InstRW<[FXa, LSU, Lat6], (instregex "(Asm.*)?LOC(G)?$")>; -def : InstRW<[FXa, Lat2], (instregex "(Asm.*)?LOC(G)?R$")>; -def : InstRW<[FXa, Lat2], (instregex "(Asm.*)?LOC(G)?HI$")>; - // Stores def : InstRW<[FXb, LSU, Lat5], (instregex "STG(RL)?$")>; def : InstRW<[FXb, LSU, Lat5], (instregex "ST128$")>; def : InstRW<[FXb, LSU, Lat5], (instregex "ST(Y|FH|RL|Mux)?$")>; -// Store on condition -def : InstRW<[FXb, LSU, Lat5], (instregex "(Asm.*)?STOC(G)?$")>; - // String moves. def : InstRW<[LSU, Lat30, GroupAlone], (instregex "MVST$")>; //===----------------------------------------------------------------------===// +// Conditional move instructions +//===----------------------------------------------------------------------===// + +def : InstRW<[FXa, Lat2], (instregex "LOC(G)?R(Asm.*)?$")>; +def : InstRW<[FXa, Lat2], (instregex "LOC(G)?HI(Asm.*)?$")>; +def : InstRW<[FXa, LSU, Lat6], (instregex "LOC(G)?(Asm.*)?$")>; +def : InstRW<[FXb, LSU, Lat5], (instregex "STOC(G)?(Asm.*)?$")>; + +//===----------------------------------------------------------------------===// // Sign extensions //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td b/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td index c61a515..f4c0e6c 100644 --- a/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td @@ -82,50 +82,48 @@ def : WriteRes { let Latency = 9; } def : InstRW<[FXU], (instregex "ADJDYNALLOC$")>; // Pseudo -> LA / LAY //===----------------------------------------------------------------------===// -// Control flow instructions +// Branch instructions //===----------------------------------------------------------------------===// -// Return -def : InstRW<[LSU_lat1, EndGroup], (instregex "Return$")>; -def : InstRW<[LSU_lat1, EndGroup], (instregex "CondReturn$")>; - -// Compare and branch -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?C(I|R)J$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CG(I|R)J$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CL(I|R)J$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CLG(I|R)J$")>; -def : InstRW<[FXU], (instregex "CLR$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CIB(Call|Return)?$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CLIB(Call|Return)?$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CLGIB(Call|Return)?$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CGIB(Call|Return)?$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CGRB(Call|Return)?$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CLGRB(Call|Return)?$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "CLR(Call|Return)?$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CLRB(Call|Return)?$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CRB(Call|Return)?$")>; - // Branch -def : InstRW<[LSU, EndGroup], (instregex "(Asm.*)?BR$")>; -def : InstRW<[LSU, EndGroup], (instregex "(Asm)?BC(R)?$")>; -def : InstRW<[LSU, EndGroup], (instregex "(Asm)?BRC(L)?$")>; +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<[LSU, EndGroup], (instregex "(Asm.*)?JG$")>; -def : InstRW<[LSU, EndGroup], (instregex "J$")>; -// (Need to avoid conflict with "(Asm.*)?CG(I|R)J$") -def : InstRW<[LSU, EndGroup], (instregex "Asm(EAlt|E|HAlt|HE|H|LAlt|LE|LH|L|NEAlt|NE)J$")>; -def : InstRW<[LSU, EndGroup], (instregex "Asm(NHAlt|NHE|NH|NLAlt|NLE|NLH|NL|NO|O)J$")>; def : InstRW<[FXU, FXU, FXU, LSU, Lat7, GroupAlone], (instregex "BRX(H|LE)$")>; +// Compare and branch +def : InstRW<[FXU, LSU, Lat5, GroupAlone], + (instregex "C(L)?(G)?(I|R)J(Asm.*)?$")>; +def : InstRW<[FXU, LSU, Lat5, GroupAlone], + (instregex "C(L)?(G)?(I|R)B(Call|Return|Asm.*)?$")>; + +//===----------------------------------------------------------------------===// +// Trap instructions +//===----------------------------------------------------------------------===// + // Trap def : InstRW<[LSU, EndGroup], (instregex "(Cond)?Trap$")>; // Compare and trap -def : InstRW<[FXU], (instregex "(Asm.*)?C(G)?IT$")>; -def : InstRW<[FXU], (instregex "(Asm.*)?C(G)?RT$")>; -def : InstRW<[FXU], (instregex "(Asm.*)?CLG(I|R)T$")>; -def : InstRW<[FXU], (instregex "(Asm.*)?CLFIT$")>; -def : InstRW<[FXU], (instregex "(Asm.*)?CLRT$")>; +def : InstRW<[FXU], (instregex "C(G)?(I|R)T(Asm.*)?$")>; +def : InstRW<[FXU], (instregex "CL(G)?RT(Asm.*)?$")>; +def : InstRW<[FXU], (instregex "CL(F|G)IT(Asm.*)?$")>; + +//===----------------------------------------------------------------------===// +// Call and return instructions +//===----------------------------------------------------------------------===// + +// Call +def : InstRW<[LSU, FXU, FXU, Lat6, GroupAlone], (instregex "(Call)?BRAS$")>; +def : InstRW<[LSU, FXU, FXU, Lat6, GroupAlone], (instregex "(Call)?BRASL$")>; +def : InstRW<[FXU, FXU, LSU, Lat6, GroupAlone], (instregex "(Call)?BAS(R)?$")>; +def : InstRW<[LSU, FXU, FXU, Lat6, GroupAlone], (instregex "TLS_(G|L)DCALL$")>; + +// Return +def : InstRW<[LSU_lat1, EndGroup], (instregex "Return$")>; +def : InstRW<[LSU_lat1, EndGroup], (instregex "CondReturn$")>; //===----------------------------------------------------------------------===// // Select instructions @@ -143,18 +141,6 @@ def : InstRW<[FXU], (instregex "CondStore8(Inv)?$")>; def : InstRW<[FXU], (instregex "CondStore8Mux(Inv)?$")>; //===----------------------------------------------------------------------===// -// Call instructions -//===----------------------------------------------------------------------===// - -def : InstRW<[LSU, FXU, FXU, Lat6, GroupAlone], (instregex "BRAS$")>; -def : InstRW<[FXU, FXU, LSU, Lat6, GroupAlone], (instregex "(Call)?BASR$")>; -def : InstRW<[LSU, EndGroup], (instregex "CallB(C)?R$")>; -def : InstRW<[LSU, FXU, FXU, Lat6, GroupAlone], (instregex "(Call)?BRASL$")>; -def : InstRW<[LSU, FXU, FXU, Lat6, GroupAlone], (instregex "TLS_(G|L)DCALL$")>; -def : InstRW<[LSU, EndGroup], (instregex "CallBRCL$")>; -def : InstRW<[LSU, EndGroup], (instregex "CallJG$")>; - -//===----------------------------------------------------------------------===// // Move instructions //===----------------------------------------------------------------------===// @@ -188,22 +174,24 @@ def : InstRW<[FXU], (instregex "LR(Mux)?$")>; def : InstRW<[FXU, LSU, Lat5], (instregex "LT(G)?$")>; def : InstRW<[FXU], (instregex "LT(G)?R$")>; -// Load on condition -def : InstRW<[FXU, LSU, Lat6, EndGroup], (instregex "(Asm.*)?LOC(G)?$")>; -def : InstRW<[FXU, Lat2, EndGroup], (instregex "(Asm.*)?LOC(G)?R$")>; - // Stores def : InstRW<[FXU, LSU, Lat5], (instregex "STG(RL)?$")>; def : InstRW<[FXU, LSU, Lat5], (instregex "ST128$")>; def : InstRW<[FXU, LSU, Lat5], (instregex "ST(Y|FH|RL|Mux)?$")>; -// Store on condition -def : InstRW<[FXU, LSU, Lat5, EndGroup], (instregex "(Asm.*)?STOC(G)?$")>; - // String moves. def : InstRW<[LSU, Lat30, GroupAlone], (instregex "MVST$")>; //===----------------------------------------------------------------------===// +// Conditional move instructions +//===----------------------------------------------------------------------===// + +def : InstRW<[FXU, Lat2, EndGroup], (instregex "LOC(G)?R(Asm.*)?$")>; +def : InstRW<[FXU, Lat2, EndGroup], (instregex "LOC(G)?HI(Asm.*)?$")>; +def : InstRW<[FXU, LSU, Lat6, EndGroup], (instregex "LOC(G)?(Asm.*)?$")>; +def : InstRW<[FXU, LSU, Lat5, EndGroup], (instregex "STOC(G)?(Asm.*)?$")>; + +//===----------------------------------------------------------------------===// // Sign extensions //===----------------------------------------------------------------------===// def : InstRW<[FXU], (instregex "L(B|H|G)R$")>; diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td b/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td index 9e960df..4f406be 100644 --- a/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td @@ -84,51 +84,47 @@ def : WriteRes; // Virtual Branching Unit def : InstRW<[FXU], (instregex "ADJDYNALLOC$")>; // Pseudo -> LA / LAY //===----------------------------------------------------------------------===// -// Control flow instructions +// Branch instructions //===----------------------------------------------------------------------===// -// Return -def : InstRW<[LSU_lat1, EndGroup], (instregex "Return$")>; -def : InstRW<[LSU_lat1], (instregex "CondReturn$")>; - -// Compare and branch -def : InstRW<[FXU], (instregex "(Asm.*)?C(I|R)J$")>; -def : InstRW<[FXU], (instregex "(Asm.*)?CG(I|R)J$")>; -def : InstRW<[FXU], (instregex "(Asm.*)?CL(I|R)J$")>; -def : InstRW<[FXU], (instregex "(Asm.*)?CLG(I|R)J$")>; -def : InstRW<[FXU], (instregex "(Asm.*)?CG(R|I)J$")>; -def : InstRW<[FXU], (instregex "CLR$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CIB(Call|Return)?$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CLIB(Call|Return)?$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CLGIB(Call|Return)?$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CGIB(Call|Return)?$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CGRB(Call|Return)?$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CLGRB(Call|Return)?$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "CLR(Call|Return)?$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CLRB(Call|Return)?$")>; -def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "(Asm.*)?CRB(Call|Return)?$")>; - // Branch -def : InstRW<[LSU, Lat4], (instregex "(Asm.*)?BR$")>; -def : InstRW<[LSU, Lat4], (instregex "(Asm)?BC(R)?$")>; -def : InstRW<[VBU], (instregex "(Asm)?BRC(L)?$")>; +def : InstRW<[VBU], (instregex "(Call)?BRC(L)?(Asm.*)?$")>; +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<[VBU], (instregex "(Asm.*)?JG$")>; -def : InstRW<[VBU], (instregex "J$")>; -// (Need to avoid conflict with "(Asm.*)?CG(I|R)J$") -def : InstRW<[VBU], (instregex "Asm(EAlt|E|HAlt|HE|H|LAlt|LE|LH|L|NEAlt|NE)J$")>; -def : InstRW<[VBU], (instregex "Asm(NHAlt|NHE|NH|NLAlt|NLE|NLH|NL|NO|O)J$")>; def : InstRW<[FXU, FXU, FXU, LSU, Lat7, GroupAlone], (instregex "BRX(H|LE)$")>; +// Compare and branch +def : InstRW<[FXU], (instregex "C(L)?(G)?(I|R)J(Asm.*)?$")>; +def : InstRW<[FXU, LSU, Lat5, GroupAlone], + (instregex "C(L)?(G)?(I|R)B(Call|Return|Asm.*)?$")>; + +//===----------------------------------------------------------------------===// +// Trap instructions +//===----------------------------------------------------------------------===// + // Trap def : InstRW<[VBU], (instregex "(Cond)?Trap$")>; // Compare and trap -def : InstRW<[FXU], (instregex "(Asm.*)?C(G)?IT$")>; -def : InstRW<[FXU], (instregex "(Asm.*)?C(G)?RT$")>; -def : InstRW<[FXU], (instregex "(Asm.*)?CLG(I|R)T$")>; -def : InstRW<[FXU], (instregex "(Asm.*)?CLFIT$")>; -def : InstRW<[FXU], (instregex "(Asm.*)?CLRT$")>; +def : InstRW<[FXU], (instregex "C(G)?(I|R)T(Asm.*)?$")>; +def : InstRW<[FXU], (instregex "CL(G)?RT(Asm.*)?$")>; +def : InstRW<[FXU], (instregex "CL(F|G)IT(Asm.*)?$")>; + +//===----------------------------------------------------------------------===// +// Call and return instructions +//===----------------------------------------------------------------------===// + +// Call +def : InstRW<[VBU, FXU, FXU, Lat3, GroupAlone], (instregex "(Call)?BRAS$")>; +def : InstRW<[FXU, FXU, LSU, Lat6, GroupAlone], (instregex "(Call)?BRASL$")>; +def : InstRW<[FXU, FXU, LSU, Lat6, GroupAlone], (instregex "(Call)?BAS(R)?$")>; +def : InstRW<[FXU, FXU, LSU, Lat6, GroupAlone], (instregex "TLS_(G|L)DCALL$")>; + +// Return +def : InstRW<[LSU_lat1, EndGroup], (instregex "Return$")>; +def : InstRW<[LSU_lat1], (instregex "CondReturn$")>; //===----------------------------------------------------------------------===// // Select instructions @@ -146,18 +142,6 @@ def : InstRW<[FXU], (instregex "CondStore8(Inv)?$")>; def : InstRW<[FXU], (instregex "CondStore8Mux(Inv)?$")>; //===----------------------------------------------------------------------===// -// Call instructions -//===----------------------------------------------------------------------===// - -def : InstRW<[VBU, FXU, FXU, Lat3, GroupAlone], (instregex "BRAS$")>; -def : InstRW<[FXU, FXU, LSU, Lat6, GroupAlone], (instregex "(Call)?BASR$")>; -def : InstRW<[LSU, Lat4], (instregex "CallB(C)?R$")>; -def : InstRW<[FXU, FXU, LSU, Lat6, GroupAlone], (instregex "(Call)?BRASL$")>; -def : InstRW<[FXU, FXU, LSU, Lat6, GroupAlone], (instregex "TLS_(G|L)DCALL$")>; -def : InstRW<[VBU], (instregex "CallBRCL$")>; -def : InstRW<[VBU], (instregex "CallJG$")>; - -//===----------------------------------------------------------------------===// // Move instructions //===----------------------------------------------------------------------===// @@ -191,22 +175,24 @@ def : InstRW<[FXU], (instregex "LR(Mux)?$")>; def : InstRW<[FXU, LSU, Lat5], (instregex "LT(G)?$")>; def : InstRW<[FXU], (instregex "LT(G)?R$")>; -// Load on condition -def : InstRW<[FXU, LSU, Lat6], (instregex "(Asm.*)?LOC(G)?$")>; -def : InstRW<[FXU, Lat2], (instregex "(Asm.*)?LOC(G)?R$")>; - // Stores def : InstRW<[FXU, LSU, Lat5], (instregex "STG(RL)?$")>; def : InstRW<[FXU, LSU, Lat5], (instregex "ST128$")>; def : InstRW<[FXU, LSU, Lat5], (instregex "ST(Y|FH|RL|Mux)?$")>; -// Store on condition -def : InstRW<[FXU, LSU, Lat5], (instregex "(Asm.*)?STOC(G)?$")>; - // String moves. def : InstRW<[LSU, Lat30, GroupAlone], (instregex "MVST$")>; //===----------------------------------------------------------------------===// +// Conditional move instructions +//===----------------------------------------------------------------------===// + +def : InstRW<[FXU, Lat2], (instregex "LOC(G)?R(Asm.*)?$")>; +def : InstRW<[FXU, Lat2], (instregex "LOC(G)?HI(Asm.*)?$")>; +def : InstRW<[FXU, LSU, Lat6], (instregex "LOC(G)?(Asm.*)?$")>; +def : InstRW<[FXU, LSU, Lat5], (instregex "STOC(G)?(Asm.*)?$")>; + +//===----------------------------------------------------------------------===// // Sign extensions //===----------------------------------------------------------------------===// diff --git a/llvm/test/MC/Disassembler/SystemZ/insns.txt b/llvm/test/MC/Disassembler/SystemZ/insns.txt index 6c6ac7b..9a1cfe6 100644 --- a/llvm/test/MC/Disassembler/SystemZ/insns.txt +++ b/llvm/test/MC/Disassembler/SystemZ/insns.txt @@ -778,6 +778,24 @@ # CHECK: ay %r15, 0 0xe3 0xf0 0x00 0x00 0x00 0x5a +# CHECK: bas %r0, 0 +0x4d 0x00 0x00 0x00 + +# CHECK: bas %r1, 4095 +0x4d 0x10 0x0f 0xff + +# CHECK: bas %r2, 0(%r1) +0x4d 0x20 0x10 0x00 + +# CHECK: bas %r3, 0(%r15) +0x4d 0x30 0xf0 0x00 + +# CHECK: bas %r14, 4095(%r1,%r15) +0x4d 0xe1 0xff 0xff + +# CHECK: bas %r15, 4095(%r15,%r1) +0x4d 0xff 0x1f 0xff + # CHECK: basr %r0, %r1 0x0d 0x01 @@ -790,6 +808,84 @@ # CHECK: basr %r15, %r1 0x0d 0xf1 +# CHECK: b 0 +0x47 0xf0 0x00 0x00 + +# CHECK: b 4095 +0x47 0xf0 0x0f 0xff + +# CHECK: b 0(%r1) +0x47 0xf0 0x10 0x00 + +# CHECK: b 0(%r15) +0x47 0xf0 0xf0 0x00 + +# CHECK: b 4095(%r1,%r15) +0x47 0xf1 0xff 0xff + +# CHECK: b 4095(%r15,%r1) +0x47 0xff 0x1f 0xff + +# CHECK: bc 0, 0 +0x47 0x00 0x00 0x00 + +# CHECK: bc 0, 4095 +0x47 0x00 0x0f 0xff + +# CHECK: bc 0, 0(%r1) +0x47 0x00 0x10 0x00 + +# CHECK: bc 0, 0(%r15) +0x47 0x00 0xf0 0x00 + +# CHECK: bc 0, 4095(%r1,%r15) +0x47 0x01 0xff 0xff + +# CHECK: bc 0, 4095(%r15,%r1) +0x47 0x0f 0x1f 0xff + +# CHECK: bo 0(%r13) +0x47 0x10 0xd0 0x00 + +# CHECK: bh 0(%r12) +0x47 0x20 0xc0 0x00 + +# CHECK: bnle 0(%r11) +0x47 0x30 0xb0 0x00 + +# CHECK: bl 0(%r10) +0x47 0x40 0xa0 0x00 + +# CHECK: bnhe 0(%r9) +0x47 0x50 0x90 0x00 + +# CHECK: blh 0(%r8) +0x47 0x60 0x80 0x00 + +# CHECK: bne 0(%r7) +0x47 0x70 0x70 0x00 + +# CHECK: be 0(%r6) +0x47 0x80 0x60 0x00 + +# CHECK: bnlh 0(%r5) +0x47 0x90 0x50 0x00 + +# CHECK: bhe 0(%r4) +0x47 0xa0 0x40 0x00 + +# CHECK: bnl 0(%r3) +0x47 0xb0 0x30 0x00 + +# CHECK: ble 0(%r2) +0x47 0xc0 0x20 0x00 + +# CHECK: bnh 0(%r1) +0x47 0xd0 0x10 0x00 + +# CHECK: bno 0 +0x47 0xe0 0x00 0x00 + # CHECK: bcr 0, %r14 0x07 0x0e diff --git a/llvm/test/MC/SystemZ/insn-bad.s b/llvm/test/MC/SystemZ/insn-bad.s index 10c73d7..7e76f43 100644 --- a/llvm/test/MC/SystemZ/insn-bad.s +++ b/llvm/test/MC/SystemZ/insn-bad.s @@ -259,6 +259,28 @@ ay %r0, 524288 #CHECK: error: invalid operand +#CHECK: bas %r0, -1 +#CHECK: error: invalid operand +#CHECK: bas %r0, 4096 + + bas %r0, -1 + bas %r0, 4096 + +#CHECK: error: invalid operand +#CHECK: bc -1, 0(%r1) +#CHECK: error: invalid operand +#CHECK: bc 16, 0(%r1) +#CHECK: error: invalid operand +#CHECK: bc 0, -1 +#CHECK: error: invalid operand +#CHECK: bc 0, 4096 + + bc -1, 0(%r1) + bc 16, 0(%r1) + bc 0, -1 + bc 0, 4096 + +#CHECK: error: invalid operand #CHECK: bcr -1, %r1 #CHECK: error: invalid operand #CHECK: bcr 16, %r1 diff --git a/llvm/test/MC/SystemZ/insn-good.s b/llvm/test/MC/SystemZ/insn-good.s index d747571..a550f30 100644 --- a/llvm/test/MC/SystemZ/insn-good.s +++ b/llvm/test/MC/SystemZ/insn-good.s @@ -517,6 +517,20 @@ ay %r0, 524287(%r15,%r1) ay %r15, 0 +#CHECK: bas %r0, 0 # encoding: [0x4d,0x00,0x00,0x00] +#CHECK: bas %r1, 4095 # encoding: [0x4d,0x10,0x0f,0xff] +#CHECK: bas %r2, 0(%r1) # encoding: [0x4d,0x20,0x10,0x00] +#CHECK: bas %r3, 0(%r15) # encoding: [0x4d,0x30,0xf0,0x00] +#CHECK: bas %r14, 4095(%r1,%r15) # encoding: [0x4d,0xe1,0xff,0xff] +#CHECK: bas %r15, 4095(%r15,%r1) # encoding: [0x4d,0xff,0x1f,0xff] + + bas %r0, 0 + bas %r1, 4095 + bas %r2, 0(%r1) + bas %r3, 0(%r15) + bas %r14, 4095(%r1,%r15) + bas %r15, 4095(%r15,%r1) + #CHECK: basr %r0, %r1 # encoding: [0x0d,0x01] #CHECK: basr %r0, %r15 # encoding: [0x0d,0x0f] #CHECK: basr %r14, %r9 # encoding: [0x0d,0xe9] @@ -527,6 +541,120 @@ basr %r14,%r9 basr %r15,%r1 +#CHECK: b 0 # encoding: [0x47,0xf0,0x00,0x00] +#CHECK: b 4095 # encoding: [0x47,0xf0,0x0f,0xff] +#CHECK: b 0(%r1) # encoding: [0x47,0xf0,0x10,0x00] +#CHECK: b 0(%r15) # encoding: [0x47,0xf0,0xf0,0x00] +#CHECK: b 4095(%r1,%r15) # encoding: [0x47,0xf1,0xff,0xff] +#CHECK: b 4095(%r15,%r1) # encoding: [0x47,0xff,0x1f,0xff] + + b 0 + b 4095 + b 0(%r1) + b 0(%r15) + b 4095(%r1,%r15) + b 4095(%r15,%r1) + +#CHECK: bc 0, 0 # encoding: [0x47,0x00,0x00,0x00] +#CHECK: bc 0, 4095 # encoding: [0x47,0x00,0x0f,0xff] +#CHECK: bc 0, 0(%r1) # encoding: [0x47,0x00,0x10,0x00] +#CHECK: bc 0, 0(%r15) # encoding: [0x47,0x00,0xf0,0x00] +#CHECK: bc 0, 4095(%r1,%r15) # encoding: [0x47,0x01,0xff,0xff] +#CHECK: bc 0, 4095(%r15,%r1) # encoding: [0x47,0x0f,0x1f,0xff] +#CHECK: bc 15, 0 # encoding: [0x47,0xf0,0x00,0x00] + + bc 0, 0 + bc 0, 4095 + bc 0, 0(%r1) + bc 0, 0(%r15) + bc 0, 4095(%r1,%r15) + bc 0, 4095(%r15,%r1) + bc 15, 0 + +#CHECK: bc 1, 0(%r7) # encoding: [0x47,0x10,0x70,0x00] +#CHECK: bo 0(%r15) # encoding: [0x47,0x10,0xf0,0x00] + + bc 1, 0(%r7) + bo 0(%r15) + +#CHECK: bc 2, 0(%r7) # encoding: [0x47,0x20,0x70,0x00] +#CHECK: bh 0(%r15) # encoding: [0x47,0x20,0xf0,0x00] + + bc 2, 0(%r7) + bh 0(%r15) + +#CHECK: bc 3, 0(%r7) # encoding: [0x47,0x30,0x70,0x00] +#CHECK: bnle 0(%r15) # encoding: [0x47,0x30,0xf0,0x00] + + bc 3, 0(%r7) + bnle 0(%r15) + +#CHECK: bc 4, 0(%r7) # encoding: [0x47,0x40,0x70,0x00] +#CHECK: bl 0(%r15) # encoding: [0x47,0x40,0xf0,0x00] + + bc 4, 0(%r7) + bl 0(%r15) + +#CHECK: bc 5, 0(%r7) # encoding: [0x47,0x50,0x70,0x00] +#CHECK: bnhe 0(%r15) # encoding: [0x47,0x50,0xf0,0x00] + + bc 5, 0(%r7) + bnhe 0(%r15) + +#CHECK: bc 6, 0(%r7) # encoding: [0x47,0x60,0x70,0x00] +#CHECK: blh 0(%r15) # encoding: [0x47,0x60,0xf0,0x00] + + bc 6, 0(%r7) + blh 0(%r15) + +#CHECK: bc 7, 0(%r7) # encoding: [0x47,0x70,0x70,0x00] +#CHECK: bne 0(%r15) # encoding: [0x47,0x70,0xf0,0x00] + + bc 7, 0(%r7) + bne 0(%r15) + +#CHECK: bc 8, 0(%r7) # encoding: [0x47,0x80,0x70,0x00] +#CHECK: be 0(%r15) # encoding: [0x47,0x80,0xf0,0x00] + + bc 8, 0(%r7) + be 0(%r15) + +#CHECK: bc 9, 0(%r7) # encoding: [0x47,0x90,0x70,0x00] +#CHECK: bnlh 0(%r15) # encoding: [0x47,0x90,0xf0,0x00] + + bc 9, 0(%r7) + bnlh 0(%r15) + +#CHECK: bc 10, 0(%r7) # encoding: [0x47,0xa0,0x70,0x00] +#CHECK: bhe 0(%r15) # encoding: [0x47,0xa0,0xf0,0x00] + + bc 10, 0(%r7) + bhe 0(%r15) + +#CHECK: bc 11, 0(%r7) # encoding: [0x47,0xb0,0x70,0x00] +#CHECK: bnl 0(%r15) # encoding: [0x47,0xb0,0xf0,0x00] + + bc 11, 0(%r7) + bnl 0(%r15) + +#CHECK: bc 12, 0(%r7) # encoding: [0x47,0xc0,0x70,0x00] +#CHECK: ble 0(%r15) # encoding: [0x47,0xc0,0xf0,0x00] + + bc 12, 0(%r7) + ble 0(%r15) + +#CHECK: bc 13, 0(%r7) # encoding: [0x47,0xd0,0x70,0x00] +#CHECK: bnh 0(%r15) # encoding: [0x47,0xd0,0xf0,0x00] + + bc 13, 0(%r7) + bnh 0(%r15) + +#CHECK: bc 14, 0(%r7) # encoding: [0x47,0xe0,0x70,0x00] +#CHECK: bno 0(%r15) # encoding: [0x47,0xe0,0xf0,0x00] + + bc 14, 0(%r7) + bno 0(%r15) + #CHECK: bcr 0, %r0 # encoding: [0x07,0x00] #CHECK: bcr 0, %r15 # encoding: [0x07,0x0f] -- 2.7.4