diff options
Diffstat (limited to 'contrib/llvm/lib/Target/SystemZ/SystemZInstrFormats.td')
-rw-r--r-- | contrib/llvm/lib/Target/SystemZ/SystemZInstrFormats.td | 987 |
1 files changed, 987 insertions, 0 deletions
diff --git a/contrib/llvm/lib/Target/SystemZ/SystemZInstrFormats.td b/contrib/llvm/lib/Target/SystemZ/SystemZInstrFormats.td new file mode 100644 index 0000000..b32b7eb --- /dev/null +++ b/contrib/llvm/lib/Target/SystemZ/SystemZInstrFormats.td @@ -0,0 +1,987 @@ +//==- SystemZInstrFormats.td - SystemZ Instruction Formats --*- tablegen -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Basic SystemZ instruction definition +//===----------------------------------------------------------------------===// + +class InstSystemZ<int size, dag outs, dag ins, string asmstr, + list<dag> pattern> : Instruction { + let Namespace = "SystemZ"; + + dag OutOperandList = outs; + dag InOperandList = ins; + let Size = size; + let Pattern = pattern; + let AsmString = asmstr; + + // Used to identify a group of related instructions, such as ST and STY. + string Function = ""; + + // "12" for an instruction that has a ...Y equivalent, "20" for that + // ...Y equivalent. + string PairType = "none"; + + // True if this instruction is a simple D(X,B) load of a register + // (with no sign or zero extension). + bit SimpleBDXLoad = 0; + + // True if this instruction is a simple D(X,B) store of a register + // (with no truncation). + bit SimpleBDXStore = 0; + + // True if this instruction has a 20-bit displacement field. + bit Has20BitOffset = 0; + + // True if addresses in this instruction have an index register. + bit HasIndex = 0; + + // True if this is a 128-bit pseudo instruction that combines two 64-bit + // operations. + bit Is128Bit = 0; + + let TSFlags{0} = SimpleBDXLoad; + let TSFlags{1} = SimpleBDXStore; + let TSFlags{2} = Has20BitOffset; + let TSFlags{3} = HasIndex; + let TSFlags{4} = Is128Bit; +} + +//===----------------------------------------------------------------------===// +// Mappings between instructions +//===----------------------------------------------------------------------===// + +// Return the version of an instruction that has an unsigned 12-bit +// displacement. +def getDisp12Opcode : InstrMapping { + let FilterClass = "InstSystemZ"; + let RowFields = ["Function"]; + let ColFields = ["PairType"]; + let KeyCol = ["20"]; + let ValueCols = [["12"]]; +} + +// Return the version of an instruction that has a signed 20-bit displacement. +def getDisp20Opcode : InstrMapping { + let FilterClass = "InstSystemZ"; + let RowFields = ["Function"]; + let ColFields = ["PairType"]; + let KeyCol = ["12"]; + let ValueCols = [["20"]]; +} + +//===----------------------------------------------------------------------===// +// Instruction formats +//===----------------------------------------------------------------------===// +// +// Formats are specified using operand field declarations of the form: +// +// bits<4> Rn : register input or output for operand n +// bits<m> In : immediate value of width m for operand n +// bits<4> Bn : base register for address operand n +// bits<m> Dn : displacement value of width m for address operand n +// bits<4> Xn : index register for address operand n +// bits<4> Mn : mode value for operand n +// +// The operand numbers ("n" in the list above) follow the architecture manual, +// but the fields are always declared in assembly order, so there are some +// cases where operand "2" comes after operand "3". For address operands, +// the base register field is declared first, followed by the displacement, +// followed by the index (if any). This matches the bdaddr* and bdxaddr* +// orders. +// +//===----------------------------------------------------------------------===// + +class InstRI<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSystemZ<4, outs, ins, asmstr, pattern> { + field bits<32> Inst; + + bits<4> R1; + bits<16> I2; + + let Inst{31-24} = op{11-4}; + let Inst{23-20} = R1; + let Inst{19-16} = op{3-0}; + let Inst{15-0} = I2; +} + +class InstRIEf<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + + bits<4> R1; + bits<4> R2; + bits<8> I3; + bits<8> I4; + bits<8> I5; + + let Inst{47-40} = op{15-8}; + let Inst{39-36} = R1; + let Inst{35-32} = R2; + let Inst{31-24} = I3; + let Inst{23-16} = I4; + let Inst{15-8} = I5; + let Inst{7-0} = op{7-0}; +} + +class InstRIL<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + + bits<4> R1; + bits<32> I2; + + let Inst{47-40} = op{11-4}; + let Inst{39-36} = R1; + let Inst{35-32} = op{3-0}; + let Inst{31-0} = I2; +} + +class InstRR<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSystemZ<2, outs, ins, asmstr, pattern> { + field bits<16> Inst; + + bits<4> R1; + bits<4> R2; + + let Inst{15-8} = op; + let Inst{7-4} = R1; + let Inst{3-0} = R2; +} + +class InstRRD<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSystemZ<4, outs, ins, asmstr, pattern> { + field bits<32> Inst; + + bits<4> R1; + bits<4> R3; + bits<4> R2; + + let Inst{31-16} = op; + let Inst{15-12} = R1; + let Inst{11-8} = 0; + let Inst{7-4} = R3; + let Inst{3-0} = R2; +} + +class InstRRE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSystemZ<4, outs, ins, asmstr, pattern> { + field bits<32> Inst; + + bits<4> R1; + bits<4> R2; + + let Inst{31-16} = op; + let Inst{15-8} = 0; + let Inst{7-4} = R1; + let Inst{3-0} = R2; +} + +class InstRRF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSystemZ<4, outs, ins, asmstr, pattern> { + field bits<32> Inst; + + bits<4> R1; + bits<4> R2; + bits<4> R3; + + let Inst{31-16} = op; + let Inst{15-12} = R3; + let Inst{11-8} = 0; + let Inst{7-4} = R1; + let Inst{3-0} = R2; +} + +class InstRX<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSystemZ<4, outs, ins, asmstr, pattern> { + field bits<32> Inst; + + bits<4> R1; + bits<4> B2; + bits<12> D2; + bits<4> X2; + + let Inst{31-24} = op; + let Inst{23-20} = R1; + let Inst{19-16} = X2; + let Inst{15-12} = B2; + let Inst{11-0} = D2; + + let HasIndex = 1; +} + +class InstRXE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + + bits<4> R1; + bits<4> B2; + bits<12> D2; + bits<4> X2; + + let Inst{47-40} = op{15-8}; + let Inst{39-36} = R1; + let Inst{35-32} = X2; + let Inst{31-28} = B2; + let Inst{27-16} = D2; + let Inst{15-8} = 0; + let Inst{7-0} = op{7-0}; + + let HasIndex = 1; +} + +class InstRXF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + + bits<4> R1; + bits<4> R3; + bits<4> B2; + bits<12> D2; + bits<4> X2; + + let Inst{47-40} = op{15-8}; + let Inst{39-36} = R3; + let Inst{35-32} = X2; + let Inst{31-28} = B2; + let Inst{27-16} = D2; + let Inst{15-12} = R1; + let Inst{11-8} = 0; + let Inst{7-0} = op{7-0}; + + let HasIndex = 1; +} + +class InstRXY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + + bits<4> R1; + bits<4> B2; + bits<20> D2; + bits<4> X2; + + let Inst{47-40} = op{15-8}; + let Inst{39-36} = R1; + let Inst{35-32} = X2; + let Inst{31-28} = B2; + let Inst{27-16} = D2{11-0}; + let Inst{15-8} = D2{19-12}; + let Inst{7-0} = op{7-0}; + + let Has20BitOffset = 1; + let HasIndex = 1; +} + +class InstRS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSystemZ<4, outs, ins, asmstr, pattern> { + field bits<32> Inst; + + bits<4> R1; + bits<4> R3; + bits<4> B2; + bits<12> D2; + + let Inst{31-24} = op; + let Inst{23-20} = R1; + let Inst{19-16} = R3; + let Inst{15-12} = B2; + let Inst{11-0} = D2; +} + +class InstRSY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + + bits<4> R1; + bits<4> R3; + bits<4> B2; + bits<20> D2; + + let Inst{47-40} = op{15-8}; + let Inst{39-36} = R1; + let Inst{35-32} = R3; + let Inst{31-28} = B2; + let Inst{27-16} = D2{11-0}; + let Inst{15-8} = D2{19-12}; + let Inst{7-0} = op{7-0}; + + let Has20BitOffset = 1; +} + +class InstSI<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSystemZ<4, outs, ins, asmstr, pattern> { + field bits<32> Inst; + + bits<4> B1; + bits<12> D1; + bits<8> I2; + + let Inst{31-24} = op; + let Inst{23-16} = I2; + let Inst{15-12} = B1; + let Inst{11-0} = D1; +} + +class InstSIL<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + + bits<4> B1; + bits<12> D1; + bits<16> I2; + + let Inst{47-32} = op; + let Inst{31-28} = B1; + let Inst{27-16} = D1; + let Inst{15-0} = I2; +} + +class InstSIY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + + bits<4> B1; + bits<20> D1; + bits<8> I2; + + let Inst{47-40} = op{15-8}; + let Inst{39-32} = I2; + let Inst{31-28} = B1; + let Inst{27-16} = D1{11-0}; + let Inst{15-8} = D1{19-12}; + let Inst{7-0} = op{7-0}; + + let Has20BitOffset = 1; +} + +//===----------------------------------------------------------------------===// +// Instruction definitions with semantics +//===----------------------------------------------------------------------===// +// +// These classes have the form <Category><Format>, where <Format> is one +// of the formats defined above and where <Category> describes the inputs +// and outputs. <Category> can be one of: +// +// Inherent: +// One register output operand and no input operands. +// +// Store: +// One register or immediate input operand and one address input operand. +// The instruction stores the first operand to the address. +// +// This category is used for both pure and truncating stores. +// +// LoadMultiple: +// One address input operand and two explicit output operands. +// The instruction loads a range of registers from the address, +// with the explicit operands giving the first and last register +// to load. Other loaded registers are added as implicit definitions. +// +// StoreMultiple: +// Two explicit input register operands and an address operand. +// The instruction stores a range of registers to the address, +// with the explicit operands giving the first and last register +// to store. Other stored registers are added as implicit uses. +// +// Unary: +// One register output operand and one input operand. The input +// operand may be a register, immediate or memory. +// +// Binary: +// One register output operand and two input operands. The first +// input operand is always a register and he second may be a register, +// immediate or memory. +// +// Shift: +// One register output operand and two input operands. The first +// input operand is a register and the second has the same form as +// an address (although it isn't actually used to address memory). +// +// Compare: +// Two input operands. The first operand is always a register, +// the second may be a register, immediate or memory. +// +// Ternary: +// One register output operand and three register input operands. +// +// CmpSwap: +// One output operand and three input operands. The first two +// operands are registers and the third is an address. The instruction +// both reads from and writes to the address. +// +// RotateSelect: +// One output operand and five input operands. The first two operands +// are registers and the other three are immediates. +// +// The format determines which input operands are tied to output operands, +// and also determines the shape of any address operand. +// +// Multiclasses of the form <Category><Format>Pair define two instructions, +// one with <Category><Format> and one with <Category><Format>Y. The name +// of the first instruction has no suffix, the name of the second has +// an extra "y". +// +//===----------------------------------------------------------------------===// + +class InherentRRE<string mnemonic, bits<16> opcode, RegisterOperand cls, + dag src> + : InstRRE<opcode, (outs cls:$dst), (ins), + mnemonic#"\t$dst", + [(set cls:$dst, src)]> { + let R2 = 0; +} + +class LoadMultipleRSY<string mnemonic, bits<16> opcode, RegisterOperand cls> + : InstRSY<opcode, (outs cls:$dst1, cls:$dst2), (ins bdaddr20only:$addr), + mnemonic#"\t$dst1, $dst2, $addr", []> { + let mayLoad = 1; +} + +class StoreRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator, + RegisterOperand cls> + : InstRIL<opcode, (outs), (ins cls:$src, pcrel32:$addr), + mnemonic#"\t$src, $addr", + [(operator cls:$src, pcrel32:$addr)]> { + 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 + // complex. + let AddedComplexity = 7; +} + +class StoreRX<string mnemonic, bits<8> opcode, SDPatternOperator operator, + RegisterOperand cls, AddressingMode mode = bdxaddr12only> + : InstRX<opcode, (outs), (ins cls:$src, mode:$addr), + mnemonic#"\t$src, $addr", + [(operator cls:$src, mode:$addr)]> { + let mayStore = 1; +} + +class StoreRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator, + RegisterOperand cls, AddressingMode mode = bdxaddr20only> + : InstRXY<opcode, (outs), (ins cls:$src, mode:$addr), + mnemonic#"\t$src, $addr", + [(operator cls:$src, mode:$addr)]> { + let mayStore = 1; +} + +multiclass StoreRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode, + SDPatternOperator operator, RegisterOperand cls> { + let Function = mnemonic ## #cls in { + let PairType = "12" in + def "" : StoreRX<mnemonic, rxOpcode, operator, cls, bdxaddr12pair>; + let PairType = "20" in + def Y : StoreRXY<mnemonic#"y", rxyOpcode, operator, cls, bdxaddr20pair>; + } +} + +class StoreMultipleRSY<string mnemonic, bits<16> opcode, RegisterOperand cls> + : InstRSY<opcode, (outs), (ins cls:$from, cls:$to, bdaddr20only:$addr), + mnemonic#"\t$from, $to, $addr", []> { + let mayStore = 1; +} + +class StoreSI<string mnemonic, bits<8> opcode, SDPatternOperator operator, + Immediate imm, AddressingMode mode = bdaddr12only> + : InstSI<opcode, (outs), (ins mode:$addr, imm:$src), + mnemonic#"\t$addr, $src", + [(operator imm:$src, mode:$addr)]> { + let mayStore = 1; +} + +class StoreSIY<string mnemonic, bits<16> opcode, SDPatternOperator operator, + Immediate imm, AddressingMode mode = bdaddr20only> + : InstSIY<opcode, (outs), (ins mode:$addr, imm:$src), + mnemonic#"\t$addr, $src", + [(operator imm:$src, mode:$addr)]> { + let mayStore = 1; +} + +class StoreSIL<string mnemonic, bits<16> opcode, SDPatternOperator operator, + Immediate imm> + : InstSIL<opcode, (outs), (ins bdaddr12only:$addr, imm:$src), + mnemonic#"\t$addr, $src", + [(operator imm:$src, bdaddr12only:$addr)]> { + let mayStore = 1; +} + +multiclass StoreSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode, + SDPatternOperator operator, Immediate imm> { + let Function = mnemonic in { + let PairType = "12" in + def "" : StoreSI<mnemonic, siOpcode, operator, imm, bdaddr12pair>; + let PairType = "20" in + def Y : StoreSIY<mnemonic#"y", siyOpcode, operator, imm, bdaddr20pair>; + } +} + +class UnaryRR<string mnemonic, bits<8> opcode, SDPatternOperator operator, + RegisterOperand cls1, RegisterOperand cls2> + : InstRR<opcode, (outs cls1:$dst), (ins cls2:$src), + mnemonic#"\t$dst, $src", + [(set cls1:$dst, (operator cls2:$src))]>; + +class UnaryRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator, + RegisterOperand cls1, RegisterOperand cls2> + : InstRRE<opcode, (outs cls1:$dst), (ins cls2:$src), + mnemonic#"\t$dst, $src", + [(set cls1:$dst, (operator cls2:$src))]>; + +class UnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1, + RegisterOperand cls2> + : InstRRF<opcode, (outs cls1:$dst), (ins cls2:$src, uimm8zx4:$mode), + mnemonic#"\t$dst, $mode, $src", []>; + +class UnaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator, + RegisterOperand cls, Immediate imm> + : InstRI<opcode, (outs cls:$dst), (ins imm:$src), + mnemonic#"\t$dst, $src", + [(set cls:$dst, (operator imm:$src))]>; + +class UnaryRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator, + RegisterOperand cls, Immediate imm> + : InstRIL<opcode, (outs cls:$dst), (ins imm:$src), + mnemonic#"\t$dst, $src", + [(set cls:$dst, (operator imm:$src))]>; + +class UnaryRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator, + RegisterOperand cls> + : InstRIL<opcode, (outs cls:$dst), (ins pcrel32:$addr), + mnemonic#"\t$dst, $addr", + [(set cls:$dst, (operator pcrel32:$addr))]> { + 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 + // complex. + let AddedComplexity = 7; +} + +class UnaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator, + RegisterOperand cls, AddressingMode mode = bdxaddr12only> + : InstRX<opcode, (outs cls:$dst), (ins mode:$addr), + mnemonic#"\t$dst, $addr", + [(set cls:$dst, (operator mode:$addr))]> { + let mayLoad = 1; +} + +class UnaryRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator, + RegisterOperand cls> + : InstRXE<opcode, (outs cls:$dst), (ins bdxaddr12only:$addr), + mnemonic#"\t$dst, $addr", + [(set cls:$dst, (operator bdxaddr12only:$addr))]> { + let mayLoad = 1; +} + +class UnaryRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator, + RegisterOperand cls, AddressingMode mode = bdxaddr20only> + : InstRXY<opcode, (outs cls:$dst), (ins mode:$addr), + mnemonic#"\t$dst, $addr", + [(set cls:$dst, (operator mode:$addr))]> { + let mayLoad = 1; +} + +multiclass UnaryRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode, + SDPatternOperator operator, RegisterOperand cls> { + let Function = mnemonic ## #cls in { + let PairType = "12" in + def "" : UnaryRX<mnemonic, rxOpcode, operator, cls, bdxaddr12pair>; + let PairType = "20" in + def Y : UnaryRXY<mnemonic#"y", rxyOpcode, operator, cls, bdxaddr20pair>; + } +} + +class BinaryRR<string mnemonic, bits<8> opcode, SDPatternOperator operator, + RegisterOperand cls1, RegisterOperand cls2> + : InstRR<opcode, (outs cls1:$dst), (ins cls1:$src1, cls2:$src2), + mnemonic#"\t$dst, $src2", + [(set cls1:$dst, (operator cls1:$src1, cls2:$src2))]> { + let Constraints = "$src1 = $dst"; + let DisableEncoding = "$src1"; +} + +class BinaryRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator, + RegisterOperand cls1, RegisterOperand cls2> + : InstRRE<opcode, (outs cls1:$dst), (ins cls1:$src1, cls2:$src2), + mnemonic#"\t$dst, $src2", + [(set cls1:$dst, (operator cls1:$src1, cls2:$src2))]> { + let Constraints = "$src1 = $dst"; + let DisableEncoding = "$src1"; +} + +// Here the assembly and dag operands are in natural order, +// but the first input operand maps to R3 and the second to R2. +// This is used for "CPSDR R1, R3, R2", which is equivalent to +// R1 = copysign (R3, R2). +// +// Direct uses of the instruction must pass operands in encoding order -- +// R1, R2, R3 -- so they must pass the source operands in reverse order. +class BinaryRevRRF<string mnemonic, bits<16> opcode, SDPatternOperator operator, + RegisterOperand cls1, RegisterOperand cls2> + : InstRRF<opcode, (outs cls1:$dst), (ins cls2:$src2, cls1:$src1), + mnemonic#"\t$dst, $src1, $src2", + [(set cls1:$dst, (operator cls1:$src1, cls2:$src2))]>; + +class BinaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator, + RegisterOperand cls, Immediate imm> + : InstRI<opcode, (outs cls:$dst), (ins cls:$src1, imm:$src2), + mnemonic#"\t$dst, $src2", + [(set cls:$dst, (operator cls:$src1, imm:$src2))]> { + let Constraints = "$src1 = $dst"; + let DisableEncoding = "$src1"; +} + +class BinaryRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator, + RegisterOperand cls, Immediate imm> + : InstRIL<opcode, (outs cls:$dst), (ins cls:$src1, imm:$src2), + mnemonic#"\t$dst, $src2", + [(set cls:$dst, (operator cls:$src1, imm:$src2))]> { + let Constraints = "$src1 = $dst"; + let DisableEncoding = "$src1"; +} + +class BinaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator, + RegisterOperand cls, SDPatternOperator load, + AddressingMode mode = bdxaddr12only> + : InstRX<opcode, (outs cls:$dst), (ins cls:$src1, mode:$src2), + mnemonic#"\t$dst, $src2", + [(set cls:$dst, (operator cls:$src1, (load mode:$src2)))]> { + let Constraints = "$src1 = $dst"; + let DisableEncoding = "$src1"; + let mayLoad = 1; +} + +class BinaryRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator, + RegisterOperand cls, SDPatternOperator load> + : InstRXE<opcode, (outs cls:$dst), (ins cls:$src1, bdxaddr12only:$src2), + mnemonic#"\t$dst, $src2", + [(set cls:$dst, (operator cls:$src1, + (load bdxaddr12only:$src2)))]> { + let Constraints = "$src1 = $dst"; + let DisableEncoding = "$src1"; + let mayLoad = 1; +} + +class BinaryRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator, + RegisterOperand cls, SDPatternOperator load, + AddressingMode mode = bdxaddr20only> + : InstRXY<opcode, (outs cls:$dst), (ins cls:$src1, mode:$src2), + mnemonic#"\t$dst, $src2", + [(set cls:$dst, (operator cls:$src1, (load mode:$src2)))]> { + let Constraints = "$src1 = $dst"; + let DisableEncoding = "$src1"; + let mayLoad = 1; +} + +multiclass BinaryRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode, + SDPatternOperator operator, RegisterOperand cls, + SDPatternOperator load> { + let Function = mnemonic ## #cls in { + let PairType = "12" in + def "" : BinaryRX<mnemonic, rxOpcode, operator, cls, load, bdxaddr12pair>; + let PairType = "20" in + def Y : BinaryRXY<mnemonic#"y", rxyOpcode, operator, cls, load, + bdxaddr20pair>; + } +} + +class BinarySI<string mnemonic, bits<8> opcode, SDPatternOperator operator, + Operand imm, AddressingMode mode = bdaddr12only> + : InstSI<opcode, (outs), (ins mode:$addr, imm:$src), + mnemonic#"\t$addr, $src", + [(store (operator (load mode:$addr), imm:$src), mode:$addr)]> { + let mayLoad = 1; + let mayStore = 1; +} + +class BinarySIY<string mnemonic, bits<16> opcode, SDPatternOperator operator, + Operand imm, AddressingMode mode = bdaddr20only> + : InstSIY<opcode, (outs), (ins mode:$addr, imm:$src), + mnemonic#"\t$addr, $src", + [(store (operator (load mode:$addr), imm:$src), mode:$addr)]> { + let mayLoad = 1; + let mayStore = 1; +} + +multiclass BinarySIPair<string mnemonic, bits<8> siOpcode, + bits<16> siyOpcode, SDPatternOperator operator, + Operand imm> { + let Function = mnemonic ## #cls in { + let PairType = "12" in + def "" : BinarySI<mnemonic, siOpcode, operator, imm, bdaddr12pair>; + let PairType = "20" in + def Y : BinarySIY<mnemonic#"y", siyOpcode, operator, imm, bdaddr20pair>; + } +} + +class ShiftRS<string mnemonic, bits<8> opcode, SDPatternOperator operator, + RegisterOperand cls, AddressingMode mode> + : InstRS<opcode, (outs cls:$dst), (ins cls:$src1, mode:$src2), + mnemonic#"\t$dst, $src2", + [(set cls:$dst, (operator cls:$src1, mode:$src2))]> { + let R3 = 0; + let Constraints = "$src1 = $dst"; + let DisableEncoding = "$src1"; +} + +class ShiftRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator, + RegisterOperand cls, AddressingMode mode> + : InstRSY<opcode, (outs cls:$dst), (ins cls:$src1, mode:$src2), + mnemonic#"\t$dst, $src1, $src2", + [(set cls:$dst, (operator cls:$src1, mode:$src2))]>; + +class CompareRR<string mnemonic, bits<8> opcode, SDPatternOperator operator, + RegisterOperand cls1, RegisterOperand cls2> + : InstRR<opcode, (outs), (ins cls1:$src1, cls2:$src2), + mnemonic#"\t$src1, $src2", + [(operator cls1:$src1, cls2:$src2)]>; + +class CompareRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator, + RegisterOperand cls1, RegisterOperand cls2> + : InstRRE<opcode, (outs), (ins cls1:$src1, cls2:$src2), + mnemonic#"\t$src1, $src2", + [(operator cls1:$src1, cls2:$src2)]>; + +class CompareRI<string mnemonic, bits<12> opcode, SDPatternOperator operator, + RegisterOperand cls, Immediate imm> + : InstRI<opcode, (outs), (ins cls:$src1, imm:$src2), + mnemonic#"\t$src1, $src2", + [(operator cls:$src1, imm:$src2)]>; + +class CompareRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator, + RegisterOperand cls, Immediate imm> + : InstRIL<opcode, (outs), (ins cls:$src1, imm:$src2), + mnemonic#"\t$src1, $src2", + [(operator cls:$src1, imm:$src2)]>; + +class CompareRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator, + RegisterOperand cls, SDPatternOperator load> + : InstRIL<opcode, (outs), (ins cls:$src1, pcrel32:$src2), + mnemonic#"\t$src1, $src2", + [(operator cls:$src1, (load pcrel32:$src2))]> { + 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 + // complex. + let AddedComplexity = 7; +} + +class CompareRX<string mnemonic, bits<8> opcode, SDPatternOperator operator, + RegisterOperand cls, SDPatternOperator load, + AddressingMode mode = bdxaddr12only> + : InstRX<opcode, (outs), (ins cls:$src1, mode:$src2), + mnemonic#"\t$src1, $src2", + [(operator cls:$src1, (load mode:$src2))]> { + let mayLoad = 1; +} + +class CompareRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator, + RegisterOperand cls, SDPatternOperator load> + : InstRXE<opcode, (outs), (ins cls:$src1, bdxaddr12only:$src2), + mnemonic#"\t$src1, $src2", + [(operator cls:$src1, (load bdxaddr12only:$src2))]> { + let mayLoad = 1; +} + +class CompareRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator, + RegisterOperand cls, SDPatternOperator load, + AddressingMode mode = bdxaddr20only> + : InstRXY<opcode, (outs), (ins cls:$src1, mode:$src2), + mnemonic#"\t$src1, $src2", + [(operator cls:$src1, (load mode:$src2))]> { + let mayLoad = 1; +} + +multiclass CompareRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode, + SDPatternOperator operator, RegisterOperand cls, + SDPatternOperator load> { + let Function = mnemonic ## #cls in { + let PairType = "12" in + def "" : CompareRX<mnemonic, rxOpcode, operator, cls, + load, bdxaddr12pair>; + let PairType = "20" in + def Y : CompareRXY<mnemonic#"y", rxyOpcode, operator, cls, + load, bdxaddr20pair>; + } +} + +class CompareSI<string mnemonic, bits<8> opcode, SDPatternOperator operator, + SDPatternOperator load, Immediate imm, + AddressingMode mode = bdaddr12only> + : InstSI<opcode, (outs), (ins mode:$addr, imm:$src), + mnemonic#"\t$addr, $src", + [(operator (load mode:$addr), imm:$src)]> { + let mayLoad = 1; +} + +class CompareSIL<string mnemonic, bits<16> opcode, SDPatternOperator operator, + SDPatternOperator load, Immediate imm> + : InstSIL<opcode, (outs), (ins bdaddr12only:$addr, imm:$src), + mnemonic#"\t$addr, $src", + [(operator (load bdaddr12only:$addr), imm:$src)]> { + let mayLoad = 1; +} + +class CompareSIY<string mnemonic, bits<16> opcode, SDPatternOperator operator, + SDPatternOperator load, Immediate imm, + AddressingMode mode = bdaddr20only> + : InstSIY<opcode, (outs), (ins mode:$addr, imm:$src), + mnemonic#"\t$addr, $src", + [(operator (load mode:$addr), imm:$src)]> { + let mayLoad = 1; +} + +multiclass CompareSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode, + SDPatternOperator operator, SDPatternOperator load, + Immediate imm> { + let Function = mnemonic in { + let PairType = "12" in + def "" : CompareSI<mnemonic, siOpcode, operator, load, imm, bdaddr12pair>; + let PairType = "20" in + def Y : CompareSIY<mnemonic#"y", siyOpcode, operator, load, imm, + bdaddr20pair>; + } +} + +class TernaryRRD<string mnemonic, bits<16> opcode, + SDPatternOperator operator, RegisterOperand cls> + : InstRRD<opcode, (outs cls:$dst), (ins cls:$src1, cls:$src2, cls:$src3), + mnemonic#"\t$dst, $src2, $src3", + [(set cls:$dst, (operator cls:$src1, cls:$src2, cls:$src3))]> { + let Constraints = "$src1 = $dst"; + let DisableEncoding = "$src1"; +} + +class TernaryRXF<string mnemonic, bits<16> opcode, SDPatternOperator operator, + RegisterOperand cls, SDPatternOperator load> + : InstRXF<opcode, (outs cls:$dst), + (ins cls:$src1, cls:$src2, bdxaddr12only:$src3), + mnemonic#"\t$dst, $src2, $src3", + [(set cls:$dst, (operator cls:$src1, cls:$src2, + (load bdxaddr12only:$src3)))]> { + let Constraints = "$src1 = $dst"; + let DisableEncoding = "$src1"; + let mayLoad = 1; +} + +class CmpSwapRS<string mnemonic, bits<8> opcode, SDPatternOperator operator, + RegisterOperand cls, AddressingMode mode = bdaddr12only> + : InstRS<opcode, (outs cls:$dst), (ins cls:$old, cls:$new, mode:$ptr), + mnemonic#"\t$dst, $new, $ptr", + [(set cls:$dst, (operator mode:$ptr, cls:$old, cls:$new))]> { + let Constraints = "$old = $dst"; + let DisableEncoding = "$old"; + let mayLoad = 1; + let mayStore = 1; +} + +class CmpSwapRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator, + RegisterOperand cls, AddressingMode mode = bdaddr20only> + : InstRSY<opcode, (outs cls:$dst), (ins cls:$old, cls:$new, mode:$ptr), + mnemonic#"\t$dst, $new, $ptr", + [(set cls:$dst, (operator mode:$ptr, cls:$old, cls:$new))]> { + let Constraints = "$old = $dst"; + let DisableEncoding = "$old"; + let mayLoad = 1; + let mayStore = 1; +} + +multiclass CmpSwapRSPair<string mnemonic, bits<8> rsOpcode, bits<16> rsyOpcode, + SDPatternOperator operator, RegisterOperand cls> { + let Function = mnemonic ## #cls in { + let PairType = "12" in + def "" : CmpSwapRS<mnemonic, rsOpcode, operator, cls, bdaddr12pair>; + let PairType = "20" in + def Y : CmpSwapRSY<mnemonic#"y", rsyOpcode, operator, cls, bdaddr20pair>; + } +} + +class RotateSelectRIEf<string mnemonic, bits<16> opcode, RegisterOperand cls1, + RegisterOperand cls2> + : InstRIEf<opcode, (outs cls1:$dst), + (ins cls1:$src1, cls2:$src2, + uimm8zx6:$imm1, uimm8zx6:$imm2, uimm8zx6:$imm3), + mnemonic#"\t$dst, $src2, $imm1, $imm2, $imm3", []> { + let Constraints = "$src1 = $dst"; + let DisableEncoding = "$src1"; +} + +//===----------------------------------------------------------------------===// +// Pseudo instructions +//===----------------------------------------------------------------------===// +// +// Convenience instructions that get lowered to real instructions +// by either SystemZTargetLowering::EmitInstrWithCustomInserter() +// or SystemZInstrInfo::expandPostRAPseudo(). +// +//===----------------------------------------------------------------------===// + +class Pseudo<dag outs, dag ins, list<dag> pattern> + : InstSystemZ<0, outs, ins, "", pattern> { + let isPseudo = 1; + let isCodeGenOnly = 1; +} + +// Implements "$dst = $cc & (8 >> CC) ? $src1 : $src2", where CC is +// the value of the PSW's 2-bit condition code field. +class SelectWrapper<RegisterOperand cls> + : Pseudo<(outs cls:$dst), (ins cls:$src1, cls:$src2, i8imm:$cc), + [(set cls:$dst, (z_select_ccmask cls:$src1, cls:$src2, imm:$cc))]> { + let usesCustomInserter = 1; + // Although the instructions used by these nodes do not in themselves + // change the PSW, the insertion requires new blocks, and the PSW cannot + // be live across them. + let Defs = [PSW]; + let Uses = [PSW]; +} + +// OPERATOR is ATOMIC_SWAP or an ATOMIC_LOAD_* operation. PAT and OPERAND +// describe the second (non-memory) operand. +class AtomicLoadBinary<SDPatternOperator operator, RegisterOperand cls, + dag pat, DAGOperand operand> + : Pseudo<(outs cls:$dst), (ins bdaddr20only:$ptr, operand:$src2), + [(set cls:$dst, (operator bdaddr20only:$ptr, pat))]> { + let Defs = [PSW]; + let Has20BitOffset = 1; + let mayLoad = 1; + let mayStore = 1; + let usesCustomInserter = 1; +} + +// Specializations of AtomicLoadWBinary. +class AtomicLoadBinaryReg32<SDPatternOperator operator> + : AtomicLoadBinary<operator, GR32, (i32 GR32:$src2), GR32>; +class AtomicLoadBinaryImm32<SDPatternOperator operator, Immediate imm> + : AtomicLoadBinary<operator, GR32, (i32 imm:$src2), imm>; +class AtomicLoadBinaryReg64<SDPatternOperator operator> + : AtomicLoadBinary<operator, GR64, (i64 GR64:$src2), GR64>; +class AtomicLoadBinaryImm64<SDPatternOperator operator, Immediate imm> + : AtomicLoadBinary<operator, GR64, (i64 imm:$src2), imm>; + +// OPERATOR is ATOMIC_SWAPW or an ATOMIC_LOADW_* operation. PAT and OPERAND +// describe the second (non-memory) operand. +class AtomicLoadWBinary<SDPatternOperator operator, dag pat, + DAGOperand operand> + : Pseudo<(outs GR32:$dst), + (ins bdaddr20only:$ptr, operand:$src2, ADDR32:$bitshift, + ADDR32:$negbitshift, uimm32:$bitsize), + [(set GR32:$dst, (operator bdaddr20only:$ptr, pat, ADDR32:$bitshift, + ADDR32:$negbitshift, uimm32:$bitsize))]> { + let Defs = [PSW]; + let Has20BitOffset = 1; + let mayLoad = 1; + let mayStore = 1; + let usesCustomInserter = 1; +} + +// Specializations of AtomicLoadWBinary. +class AtomicLoadWBinaryReg<SDPatternOperator operator> + : AtomicLoadWBinary<operator, (i32 GR32:$src2), GR32>; +class AtomicLoadWBinaryImm<SDPatternOperator operator, Immediate imm> + : AtomicLoadWBinary<operator, (i32 imm:$src2), imm>; |