1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[SystemZ] Add support for IBM z14 processor (1/3)

This patch series adds support for the IBM z14 processor.  This part includes:
- Basic support for the new processor and its features.
- Support for new instructions (except vector 32-bit float and 128-bit float).
- CodeGen for new instructions, including new LLVM intrinsics.
- Scheduler description for the new processor.
- Detection of z14 as host processor.

Support for the new 32-bit vector float and 128-bit vector float
instructions is provided by separate patches.

llvm-svn: 308194
This commit is contained in:
Ulrich Weigand 2017-07-17 17:41:11 +00:00
parent ce97a198e5
commit 5f15092063
38 changed files with 7249 additions and 15 deletions

View File

@ -373,6 +373,33 @@ let TargetPrefix = "s390" in {
def int_s390_vfidb : Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
// Instructions from the Vector Enhancements Facility 1
def int_s390_vbperm : SystemZBinaryConv<"vbperm", llvm_v2i64_ty,
llvm_v16i8_ty>;
def int_s390_vmslg : GCCBuiltin<"__builtin_s390_vmslg">,
Intrinsic<[llvm_v16i8_ty],
[llvm_v2i64_ty, llvm_v2i64_ty, llvm_v16i8_ty,
llvm_i32_ty], [IntrNoMem]>;
def int_s390_vfmaxdb : Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_s390_vfmindb : Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_i32_ty],
[IntrNoMem]>;
// Instructions from the Vector Packed Decimal Facility
def int_s390_vlrl : GCCBuiltin<"__builtin_s390_vlrl">,
Intrinsic<[llvm_v16i8_ty], [llvm_i32_ty, llvm_ptr_ty],
[IntrReadMem, IntrArgMemOnly]>;
def int_s390_vstrl : GCCBuiltin<"__builtin_s390_vstrl">,
Intrinsic<[], [llvm_v16i8_ty, llvm_i32_ty, llvm_ptr_ty],
// In fact write-only but there's no property
// for that.
[IntrArgMemOnly]>;
}
//===----------------------------------------------------------------------===//

View File

@ -250,6 +250,8 @@ StringRef sys::detail::getHostCPUNameForS390x(
Pos += sizeof("machine = ") - 1;
unsigned int Id;
if (!Lines[I].drop_front(Pos).getAsInteger(10, Id)) {
if (Id >= 3906 && HaveVectorSupport)
return "z14";
if (Id >= 2964 && HaveVectorSupport)
return "z13";
if (Id >= 2827)

View File

@ -187,6 +187,57 @@ def Arch11NewFeatures : SystemZFeatureList<[
FeatureVector
]>;
//===----------------------------------------------------------------------===//
//
// New features added in the Twelvth Edition of the z/Architecture
//
//===----------------------------------------------------------------------===//
def FeatureMiscellaneousExtensions2 : SystemZFeature<
"miscellaneous-extensions-2", "MiscellaneousExtensions2",
"Assume that the miscellaneous-extensions facility 2 is installed"
>;
def FeatureGuardedStorage : SystemZFeature<
"guarded-storage", "GuardedStorage",
"Assume that the guarded-storage facility is installed"
>;
def FeatureMessageSecurityAssist7 : SystemZFeature<
"message-security-assist-extension7", "MessageSecurityAssist7",
"Assume that the message-security-assist extension facility 7 is installed"
>;
def FeatureMessageSecurityAssist8 : SystemZFeature<
"message-security-assist-extension8", "MessageSecurityAssist8",
"Assume that the message-security-assist extension facility 8 is installed"
>;
def FeatureVectorEnhancements1 : SystemZFeature<
"vector-enhancements-1", "VectorEnhancements1",
"Assume that the vector enhancements facility 1 is installed"
>;
def FeatureVectorPackedDecimal : SystemZFeature<
"vector-packed-decimal", "VectorPackedDecimal",
"Assume that the vector packed decimal facility is installed"
>;
def FeatureInsertReferenceBitsMultiple : SystemZFeature<
"insert-reference-bits-multiple", "InsertReferenceBitsMultiple",
"Assume that the insert-reference-bits-multiple facility is installed"
>;
def Arch12NewFeatures : SystemZFeatureList<[
FeatureMiscellaneousExtensions2,
FeatureGuardedStorage,
FeatureMessageSecurityAssist7,
FeatureMessageSecurityAssist8,
FeatureVectorEnhancements1,
FeatureVectorPackedDecimal,
FeatureInsertReferenceBitsMultiple
]>;
//===----------------------------------------------------------------------===//
//
// Cumulative supported and unsupported feature sets
@ -201,9 +252,13 @@ def Arch10SupportedFeatures
: SystemZFeatureAdd<Arch9SupportedFeatures.List, Arch10NewFeatures.List>;
def Arch11SupportedFeatures
: SystemZFeatureAdd<Arch10SupportedFeatures.List, Arch11NewFeatures.List>;
def Arch12SupportedFeatures
: SystemZFeatureAdd<Arch11SupportedFeatures.List, Arch12NewFeatures.List>;
def Arch11UnsupportedFeatures
def Arch12UnsupportedFeatures
: SystemZFeatureList<[]>;
def Arch11UnsupportedFeatures
: SystemZFeatureAdd<Arch12UnsupportedFeatures.List, Arch12NewFeatures.List>;
def Arch10UnsupportedFeatures
: SystemZFeatureAdd<Arch11UnsupportedFeatures.List, Arch11NewFeatures.List>;
def Arch9UnsupportedFeatures

View File

@ -316,7 +316,10 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::AND, VT, Legal);
setOperationAction(ISD::OR, VT, Legal);
setOperationAction(ISD::XOR, VT, Legal);
setOperationAction(ISD::CTPOP, VT, Custom);
if (Subtarget.hasVectorEnhancements1())
setOperationAction(ISD::CTPOP, VT, Legal);
else
setOperationAction(ISD::CTPOP, VT, Custom);
setOperationAction(ISD::CTTZ, VT, Legal);
setOperationAction(ISD::CTLZ, VT, Legal);
@ -414,6 +417,19 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::FROUND, MVT::v2f64, Legal);
}
// The vector enhancements facility 1 has instructions for these.
if (Subtarget.hasVectorEnhancements1()) {
setOperationAction(ISD::FMAXNUM, MVT::f64, Legal);
setOperationAction(ISD::FMAXNAN, MVT::f64, Legal);
setOperationAction(ISD::FMINNUM, MVT::f64, Legal);
setOperationAction(ISD::FMINNAN, MVT::f64, Legal);
setOperationAction(ISD::FMAXNUM, MVT::v2f64, Legal);
setOperationAction(ISD::FMAXNAN, MVT::v2f64, Legal);
setOperationAction(ISD::FMINNUM, MVT::v2f64, Legal);
setOperationAction(ISD::FMINNAN, MVT::v2f64, Legal);
}
// We have fused multiply-addition for f32 and f64 but not f128.
setOperationAction(ISD::FMA, MVT::f32, Legal);
setOperationAction(ISD::FMA, MVT::f64, Legal);
@ -2960,6 +2976,12 @@ SDValue SystemZTargetLowering::lowerSMUL_LOHI(SDValue Op,
// We define this so that it can be used for constant division.
lowerMUL_LOHI32(DAG, DL, ISD::SIGN_EXTEND, Op.getOperand(0),
Op.getOperand(1), Ops[1], Ops[0]);
else if (Subtarget.hasMiscellaneousExtensions2())
// SystemZISD::SMUL_LOHI returns the low result in the odd register and
// the high result in the even register. ISD::SMUL_LOHI is defined to
// return the low half first, so the results are in reverse order.
lowerGR128Binary(DAG, DL, VT, SystemZISD::SMUL_LOHI,
Op.getOperand(0), Op.getOperand(1), Ops[1], Ops[0]);
else {
// Do a full 128-bit multiplication based on SystemZISD::UMUL_LOHI:
//
@ -4658,6 +4680,7 @@ const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const {
OPCODE(SELECT_CCMASK);
OPCODE(ADJDYNALLOC);
OPCODE(POPCNT);
OPCODE(SMUL_LOHI);
OPCODE(UMUL_LOHI);
OPCODE(SDIVREM);
OPCODE(UDIVREM);

View File

@ -88,6 +88,7 @@ enum NodeType : unsigned {
// Wrappers around the ISD opcodes of the same name. The output is GR128.
// Input operands may be GR64 or GR32, depending on the instruction.
SMUL_LOHI,
UMUL_LOHI,
SDIVREM,
UDIVREM,

View File

@ -1091,6 +1091,94 @@ class InstVRIe<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
let Inst{7-0} = op{7-0};
}
class InstVRIf<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSystemZ<6, outs, ins, asmstr, pattern> {
field bits<48> Inst;
field bits<48> SoftFail = 0;
bits<5> V1;
bits<5> V2;
bits<5> V3;
bits<8> I4;
bits<4> M5;
let Inst{47-40} = op{15-8};
let Inst{39-36} = V1{3-0};
let Inst{35-32} = V2{3-0};
let Inst{31-28} = V3{3-0};
let Inst{27-24} = 0;
let Inst{23-20} = M5;
let Inst{19-12} = I4;
let Inst{11} = V1{4};
let Inst{10} = V2{4};
let Inst{9} = V3{4};
let Inst{8} = 0;
let Inst{7-0} = op{7-0};
}
class InstVRIg<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSystemZ<6, outs, ins, asmstr, pattern> {
field bits<48> Inst;
field bits<48> SoftFail = 0;
bits<5> V1;
bits<5> V2;
bits<8> I3;
bits<8> I4;
bits<4> M5;
let Inst{47-40} = op{15-8};
let Inst{39-36} = V1{3-0};
let Inst{35-32} = V2{3-0};
let Inst{31-24} = I4;
let Inst{23-20} = M5;
let Inst{19-12} = I3;
let Inst{11} = V1{4};
let Inst{10} = V2{4};
let Inst{9-8} = 0;
let Inst{7-0} = op{7-0};
}
class InstVRIh<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSystemZ<6, outs, ins, asmstr, pattern> {
field bits<48> Inst;
field bits<48> SoftFail = 0;
bits<5> V1;
bits<16> I2;
bits<4> I3;
let Inst{47-40} = op{15-8};
let Inst{39-36} = V1{3-0};
let Inst{35-32} = 0;
let Inst{31-16} = I2;
let Inst{15-12} = I3;
let Inst{11} = V1{4};
let Inst{10-8} = 0;
let Inst{7-0} = op{7-0};
}
class InstVRIi<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSystemZ<6, outs, ins, asmstr, pattern> {
field bits<48> Inst;
field bits<48> SoftFail = 0;
bits<5> V1;
bits<4> R2;
bits<8> I3;
bits<4> M4;
let Inst{47-40} = op{15-8};
let Inst{39-36} = V1{3-0};
let Inst{35-32} = R2;
let Inst{31-24} = 0;
let Inst{23-20} = M4;
let Inst{19-12} = I3;
let Inst{11} = V1{4};
let Inst{10-8} = 0;
let Inst{7-0} = op{7-0};
}
// Depending on the instruction mnemonic, certain bits may be or-ed into
// the M4 value provided as explicit operand. These are passed as m4or.
class InstVRRa<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern,
@ -1259,6 +1347,67 @@ class InstVRRf<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
let Inst{7-0} = op{7-0};
}
class InstVRRg<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSystemZ<6, outs, ins, asmstr, pattern> {
field bits<48> Inst;
field bits<48> SoftFail = 0;
bits<5> V1;
let Inst{47-40} = op{15-8};
let Inst{39-36} = 0;
let Inst{35-32} = V1{3-0};
let Inst{31-12} = 0;
let Inst{11} = 0;
let Inst{10} = V1{4};
let Inst{9-8} = 0;
let Inst{7-0} = op{7-0};
}
class InstVRRh<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSystemZ<6, outs, ins, asmstr, pattern> {
field bits<48> Inst;
field bits<48> SoftFail = 0;
bits<5> V1;
bits<5> V2;
bits<4> M3;
let Inst{47-40} = op{15-8};
let Inst{39-36} = 0;
let Inst{35-32} = V1{3-0};
let Inst{31-28} = V2{3-0};
let Inst{27-24} = 0;
let Inst{23-20} = M3;
let Inst{19-12} = 0;
let Inst{11} = 0;
let Inst{10} = V1{4};
let Inst{9} = V2{4};
let Inst{8} = 0;
let Inst{7-0} = op{7-0};
}
class InstVRRi<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSystemZ<6, outs, ins, asmstr, pattern> {
field bits<48> Inst;
field bits<48> SoftFail = 0;
bits<4> R1;
bits<5> V2;
bits<4> M3;
let Inst{47-40} = op{15-8};
let Inst{39-36} = R1;
let Inst{35-32} = V2{3-0};
let Inst{31-24} = 0;
let Inst{23-20} = M3;
let Inst{19-12} = 0;
let Inst{11} = 0;
let Inst{10} = V2{4};
let Inst{9-8} = 0;
let Inst{7-0} = op{7-0};
}
class InstVRSa<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSystemZ<6, outs, ins, asmstr, pattern> {
field bits<48> Inst;
@ -1321,6 +1470,25 @@ class InstVRSc<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
let Inst{7-0} = op{7-0};
}
class InstVRSd<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSystemZ<6, outs, ins, asmstr, pattern> {
field bits<48> Inst;
field bits<48> SoftFail = 0;
bits<5> V1;
bits<16> BD2;
bits<4> R3;
let Inst{47-40} = op{15-8};
let Inst{39-36} = 0;
let Inst{35-32} = R3;
let Inst{31-16} = BD2;
let Inst{15-12} = V1{3-0};
let Inst{11-9} = 0;
let Inst{8} = V1{4};
let Inst{7-0} = op{7-0};
}
class InstVRV<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSystemZ<6, outs, ins, asmstr, pattern> {
field bits<48> Inst;
@ -1358,6 +1526,24 @@ class InstVRX<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
let Inst{7-0} = op{7-0};
}
class InstVSI<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSystemZ<6, outs, ins, asmstr, pattern> {
field bits<48> Inst;
field bits<48> SoftFail = 0;
bits<5> V1;
bits<16> BD2;
bits<8> I3;
let Inst{47-40} = op{15-8};
let Inst{39-32} = I3;
let Inst{31-16} = BD2;
let Inst{15-12} = V1{3-0};
let Inst{11-9} = 0;
let Inst{8} = V1{4};
let Inst{7-0} = op{7-0};
}
//===----------------------------------------------------------------------===//
// Instruction classes for .insn directives
//===----------------------------------------------------------------------===//
@ -1910,6 +2096,25 @@ class FixedCondBranchRX<CondVariant V, string mnemonic, bits<8> opcode>
let M1 = V.ccmask;
}
class CondBranchRXY<string mnemonic, bits<16> opcode>
: InstRXYb<opcode, (outs), (ins cond4:$valid, cond4:$M1, bdxaddr20only:$XBD2),
!subst("#", "${M1}", mnemonic)#"\t$XBD2", []> {
let CCMaskFirst = 1;
}
class AsmCondBranchRXY<string mnemonic, bits<16> opcode>
: InstRXYb<opcode, (outs), (ins imm32zx4:$M1, bdxaddr20only:$XBD2),
mnemonic#"\t$M1, $XBD2", []>;
class FixedCondBranchRXY<CondVariant V, string mnemonic, bits<16> opcode,
SDPatternOperator operator = null_frag>
: InstRXYb<opcode, (outs), (ins bdxaddr20only:$XBD2),
!subst("#", V.suffix, mnemonic)#"\t$XBD2",
[(operator (load bdxaddr20only:$XBD2))]> {
let isAsmParserOnly = V.alternate;
let M1 = V.ccmask;
}
class CmpBranchRIEa<string mnemonic, bits<16> opcode,
RegisterOperand cls, Immediate imm>
: InstRIEa<opcode, (outs), (ins cls:$R1, imm:$I2, cond4:$M3),
@ -2272,6 +2477,24 @@ class StoreLengthVRSb<string mnemonic, bits<16> opcode,
let AccessBytes = bytes;
}
class StoreLengthVRSd<string mnemonic, bits<16> opcode,
SDPatternOperator operator, bits<5> bytes>
: InstVRSd<opcode, (outs), (ins VR128:$V1, GR32:$R3, bdaddr12only:$BD2),
mnemonic#"\t$V1, $R3, $BD2",
[(operator VR128:$V1, GR32:$R3, bdaddr12only:$BD2)]> {
let mayStore = 1;
let AccessBytes = bytes;
}
class StoreLengthVSI<string mnemonic, bits<16> opcode,
SDPatternOperator operator, bits<5> bytes>
: InstVSI<opcode, (outs), (ins VR128:$V1, bdaddr12only:$BD2, imm32zx8:$I3),
mnemonic#"\t$V1, $BD2, $I3",
[(operator VR128:$V1, imm32zx8:$I3, bdaddr12only:$BD2)]> {
let mayStore = 1;
let AccessBytes = bytes;
}
class StoreMultipleRS<string mnemonic, bits<8> opcode, RegisterOperand cls,
AddressingMode mode = bdaddr12only>
: InstRSa<opcode, (outs), (ins cls:$R1, cls:$R3, mode:$BD2),
@ -2700,6 +2923,11 @@ class SideEffectBinaryRX<string mnemonic, bits<8> opcode,
: InstRXa<opcode, (outs), (ins cls:$R1, bdxaddr12only:$XBD2),
mnemonic##"\t$R1, $XBD2", []>;
class SideEffectBinaryRXY<string mnemonic, bits<16> opcode,
RegisterOperand cls>
: InstRXYa<opcode, (outs), (ins cls:$R1, bdxaddr20only:$XBD2),
mnemonic##"\t$R1, $XBD2", []>;
class SideEffectBinaryRILPC<string mnemonic, bits<12> opcode,
RegisterOperand cls>
: InstRILb<opcode, (outs), (ins cls:$R1, pcrel32:$RI2),
@ -3188,6 +3416,11 @@ class BinaryVRIeFloatGeneric<string mnemonic, bits<16> opcode>
(ins VR128:$V2, imm32zx12:$I3, imm32zx4:$M4, imm32zx4:$M5),
mnemonic#"\t$V1, $V2, $I3, $M4, $M5", []>;
class BinaryVRIh<string mnemonic, bits<16> opcode>
: InstVRIh<opcode, (outs VR128:$V1),
(ins imm32zx16:$I2, imm32zx4:$I3),
mnemonic#"\t$V1, $I2, $I3", []>;
class BinaryVRRa<string mnemonic, bits<16> opcode, SDPatternOperator operator,
TypedReg tr1, TypedReg tr2, bits<4> type = 0, bits<4> m4 = 0>
: InstVRRa<opcode, (outs tr1.op:$V1), (ins tr2.op:$V2, imm32zx4:$M5),
@ -3316,6 +3549,10 @@ class BinaryVRRf<string mnemonic, bits<16> opcode, SDPatternOperator operator,
mnemonic#"\t$V1, $R2, $R3",
[(set tr.op:$V1, (tr.vt (operator GR64:$R2, GR64:$R3)))]>;
class BinaryVRRi<string mnemonic, bits<16> opcode, RegisterOperand cls>
: InstVRRi<opcode, (outs cls:$R1), (ins VR128:$V2, imm32zx4:$M3),
mnemonic#"\t$R1, $V2, $M3", []>;
class BinaryVRSa<string mnemonic, bits<16> opcode, SDPatternOperator operator,
TypedReg tr1, TypedReg tr2, bits<4> type>
: InstVRSa<opcode, (outs tr1.op:$V1), (ins tr2.op:$V3, shift12only:$BD2),
@ -3353,6 +3590,15 @@ class BinaryVRScGeneric<string mnemonic, bits<16> opcode>
(ins VR128:$V3, shift12only:$BD2, imm32zx4: $M4),
mnemonic#"\t$R1, $V3, $BD2, $M4", []>;
class BinaryVRSd<string mnemonic, bits<16> opcode, SDPatternOperator operator,
bits<5> bytes>
: InstVRSd<opcode, (outs VR128:$V1), (ins GR32:$R3, bdaddr12only:$BD2),
mnemonic#"\t$V1, $R3, $BD2",
[(set VR128:$V1, (operator GR32:$R3, bdaddr12only:$BD2))]> {
let mayLoad = 1;
let AccessBytes = bytes;
}
class BinaryVRX<string mnemonic, bits<16> opcode, SDPatternOperator operator,
TypedReg tr, bits<5> bytes>
: InstVRX<opcode, (outs VR128:$V1), (ins bdxaddr12only:$XBD2, imm32zx4:$M3),
@ -3398,6 +3644,15 @@ class StoreBinaryRSL<string mnemonic, bits<16> opcode, RegisterOperand cls>
let mayStore = 1;
}
class BinaryVSI<string mnemonic, bits<16> opcode, SDPatternOperator operator,
bits<5> bytes>
: InstVSI<opcode, (outs VR128:$V1), (ins bdaddr12only:$BD2, imm32zx8:$I3),
mnemonic#"\t$V1, $BD2, $I3",
[(set VR128:$V1, (operator imm32zx8:$I3, bdaddr12only:$BD2))]> {
let mayLoad = 1;
let AccessBytes = bytes;
}
class StoreBinaryVRV<string mnemonic, bits<16> opcode, bits<5> bytes,
Immediate index>
: InstVRV<opcode, (outs), (ins VR128:$V1, bdvaddr12only:$VBD2, index:$M3),
@ -3625,6 +3880,12 @@ class CompareVRRaFloatGeneric<string mnemonic, bits<16> opcode>
let M5 = 0;
}
class CompareVRRh<string mnemonic, bits<16> opcode>
: InstVRRh<opcode, (outs), (ins VR128:$V1, VR128:$V2, imm32zx4:$M3),
mnemonic#"\t$V1, $V2, $M3", []> {
let isCompare = 1;
}
class TestRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
RegisterOperand cls>
: InstRXE<opcode, (outs), (ins cls:$R1, bdxaddr12only:$XBD2),
@ -3639,6 +3900,10 @@ class TestRSL<string mnemonic, bits<16> opcode>
let mayLoad = 1;
}
class TestVRRg<string mnemonic, bits<16> opcode>
: InstVRRg<opcode, (outs), (ins VR128:$V1),
mnemonic#"\t$V1", []>;
class SideEffectTernarySSc<string mnemonic, bits<8> opcode>
: InstSSc<opcode, (outs), (ins bdladdr12onlylen4:$BDL1,
shift12only:$BD2, imm32zx4:$I3),
@ -3842,6 +4107,11 @@ class TernaryVRId<string mnemonic, bits<16> opcode, SDPatternOperator operator,
let M5 = type;
}
class TernaryVRIi<string mnemonic, bits<16> opcode, RegisterOperand cls>
: InstVRIi<opcode, (outs VR128:$V1),
(ins cls:$R2, imm32zx8:$I3, imm32zx4:$M4),
mnemonic#"\t$V1, $R2, $I3, $M4", []>;
class TernaryVRRa<string mnemonic, bits<16> opcode, SDPatternOperator operator,
TypedReg tr1, TypedReg tr2, bits<4> type, bits<4> m4or>
: InstVRRa<opcode, (outs tr1.op:$V1),
@ -3914,6 +4184,25 @@ class TernaryVRRc<string mnemonic, bits<16> opcode, SDPatternOperator operator,
let M6 = 0;
}
class TernaryVRRcFloat<string mnemonic, bits<16> opcode,
SDPatternOperator operator, TypedReg tr1, TypedReg tr2,
bits<4> type = 0, bits<4> m5 = 0>
: InstVRRc<opcode, (outs tr1.op:$V1),
(ins tr2.op:$V2, tr2.op:$V3, imm32zx4:$M6),
mnemonic#"\t$V1, $V2, $V3, $M6",
[(set tr1.op:$V1, (tr1.vt (operator (tr2.vt tr2.op:$V2),
(tr2.vt tr2.op:$V3),
imm32zx4:$M6)))]> {
let M4 = type;
let M5 = m5;
}
class TernaryVRRcFloatGeneric<string mnemonic, bits<16> opcode>
: InstVRRc<opcode, (outs VR128:$V1),
(ins VR128:$V2, VR128:$V3, imm32zx4:$M4, imm32zx4:$M5,
imm32zx4:$M6),
mnemonic#"\t$V1, $V2, $V3, $M4, $M5, $M6", []>;
class TernaryVRRd<string mnemonic, bits<16> opcode, SDPatternOperator operator,
TypedReg tr1, TypedReg tr2, bits<4> type = 0>
: InstVRRd<opcode, (outs tr1.op:$V1),
@ -4019,20 +4308,38 @@ class QuaternaryVRIdGeneric<string mnemonic, bits<16> opcode>
let DisableEncoding = "$V1src";
}
class QuaternaryVRIf<string mnemonic, bits<16> opcode>
: InstVRIf<opcode, (outs VR128:$V1),
(ins VR128:$V2, VR128:$V3,
imm32zx8:$I4, imm32zx4:$M5),
mnemonic#"\t$V1, $V2, $V3, $I4, $M5", []>;
class QuaternaryVRIg<string mnemonic, bits<16> opcode>
: InstVRIg<opcode, (outs VR128:$V1),
(ins VR128:$V2, imm32zx8:$I3,
imm32zx8:$I4, imm32zx4:$M5),
mnemonic#"\t$V1, $V2, $I3, $I4, $M5", []>;
class QuaternaryVRRd<string mnemonic, bits<16> opcode,
SDPatternOperator operator, TypedReg tr1, TypedReg tr2,
bits<4> type, SDPatternOperator m6mask, bits<4> m6or>
TypedReg tr3, TypedReg tr4, bits<4> type,
SDPatternOperator m6mask = imm32zx4, bits<4> m6or = 0>
: InstVRRd<opcode, (outs tr1.op:$V1),
(ins tr2.op:$V2, tr2.op:$V3, tr2.op:$V4, m6mask:$M6),
(ins tr2.op:$V2, tr3.op:$V3, tr4.op:$V4, m6mask:$M6),
mnemonic#"\t$V1, $V2, $V3, $V4, $M6",
[(set tr1.op:$V1, (tr1.vt (operator (tr2.vt tr2.op:$V2),
(tr2.vt tr2.op:$V3),
(tr2.vt tr2.op:$V4),
(tr3.vt tr3.op:$V3),
(tr4.vt tr4.op:$V4),
m6mask:$M6)))],
m6or> {
let M5 = type;
}
class QuaternaryVRRdGeneric<string mnemonic, bits<16> opcode>
: InstVRRd<opcode, (outs VR128:$V1),
(ins VR128:$V2, VR128:$V3, VR128:$V4, imm32zx4:$M5, imm32zx4:$M6),
mnemonic#"\t$V1, $V2, $V3, $V4, $M5, $M6", []>;
// Declare a pair of instructions, one which sets CC and one which doesn't.
// The CC-setting form ends with "S" and sets the low bit of M6.
// Also create aliases to make use of M6 operand optional in assembler.
@ -4041,13 +4348,15 @@ multiclass QuaternaryOptVRRdSPair<string mnemonic, bits<16> opcode,
SDPatternOperator operator_cc,
TypedReg tr1, TypedReg tr2, bits<4> type,
bits<4> modifier = 0> {
def "" : QuaternaryVRRd<mnemonic, opcode, operator, tr1, tr2, type,
def "" : QuaternaryVRRd<mnemonic, opcode, operator,
tr1, tr2, tr2, tr2, type,
imm32zx4even, !and (modifier, 14)>;
def : InstAlias<mnemonic#"\t$V1, $V2, $V3, $V4",
(!cast<Instruction>(NAME) tr1.op:$V1, tr2.op:$V2,
tr2.op:$V3, tr2.op:$V4, 0)>;
let Defs = [CC] in
def S : QuaternaryVRRd<mnemonic##"s", opcode, operator_cc, tr1, tr2, type,
def S : QuaternaryVRRd<mnemonic##"s", opcode, operator_cc,
tr1, tr2, tr2, tr2, type,
imm32zx4even, !add (!and (modifier, 14), 1)>;
def : InstAlias<mnemonic#"s\t$V1, $V2, $V3, $V4",
(!cast<Instruction>(NAME#"S") tr1.op:$V1, tr2.op:$V2,
@ -4055,10 +4364,7 @@ multiclass QuaternaryOptVRRdSPair<string mnemonic, bits<16> opcode,
}
multiclass QuaternaryOptVRRdSPairGeneric<string mnemonic, bits<16> opcode> {
def "" : InstVRRd<opcode, (outs VR128:$V1),
(ins VR128:$V2, VR128:$V3, VR128:$V4,
imm32zx4:$M5, imm32zx4:$M6),
mnemonic#"\t$V1, $V2, $V3, $V4, $M5, $M6", []>;
def "" : QuaternaryVRRdGeneric<mnemonic, opcode>;
def : InstAlias<mnemonic#"\t$V1, $V2, $V3, $V4, $M5",
(!cast<Instruction>(NAME) VR128:$V1, VR128:$V2, VR128:$V3,
VR128:$V4, imm32zx4:$M5, 0)>;

View File

@ -1434,6 +1434,7 @@ SystemZII::Branch
SystemZInstrInfo::getBranchInfo(const MachineInstr &MI) const {
switch (MI.getOpcode()) {
case SystemZ::BR:
case SystemZ::BI:
case SystemZ::J:
case SystemZ::JG:
return SystemZII::Branch(SystemZII::BranchNormal, SystemZ::CCMASK_ANY,

View File

@ -48,6 +48,8 @@ let isBranch = 1, isTerminator = 1, Uses = [CC] in {
let isIndirectBranch = 1 in {
def BC : CondBranchRX<"b#", 0x47>;
def BCR : CondBranchRR<"b#r", 0x07>;
def BIC : CondBranchRXY<"bi#", 0xe347>,
Requires<[FeatureMiscellaneousExtensions2]>;
}
}
@ -58,6 +60,8 @@ let isBranch = 1, isTerminator = 1, Uses = [CC] in {
let isIndirectBranch = 1 in {
def BCAsm : AsmCondBranchRX<"bc", 0x47>;
def BCRAsm : AsmCondBranchRR<"bcr", 0x07>;
def BICAsm : AsmCondBranchRXY<"bic", 0xe347>,
Requires<[FeatureMiscellaneousExtensions2]>;
}
// Define AsmParser extended mnemonics for each general condition-code mask
@ -69,6 +73,8 @@ let isBranch = 1, isTerminator = 1, Uses = [CC] in {
let isIndirectBranch = 1 in {
def BAsm#V : FixedCondBranchRX <CV<V>, "b#", 0x47>;
def BRAsm#V : FixedCondBranchRR <CV<V>, "b#r", 0x07>;
def BIAsm#V : FixedCondBranchRXY<CV<V>, "bi#", 0xe347>,
Requires<[FeatureMiscellaneousExtensions2]>;
}
}
}
@ -81,6 +87,8 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
let isIndirectBranch = 1 in {
def B : FixedCondBranchRX<CondAlways, "b", 0x47>;
def BR : FixedCondBranchRR<CondAlways, "br", 0x07, brind>;
def BI : FixedCondBranchRXY<CondAlways, "bi", 0xe347, brind>,
Requires<[FeatureMiscellaneousExtensions2]>;
}
}
@ -921,6 +929,8 @@ let Defs = [CC], CCValues = 0xF, CompareZeroCCMask = 0x8 in {
// Addition of memory.
defm AH : BinaryRXPair<"ah", 0x4A, 0xE37A, add, GR32, asextloadi16, 2>;
defm A : BinaryRXPair<"a", 0x5A, 0xE35A, add, GR32, load, 4>;
def AGH : BinaryRXY<"agh", 0xE338, add, GR64, asextloadi16, 2>,
Requires<[FeatureMiscellaneousExtensions2]>;
def AGF : BinaryRXY<"agf", 0xE318, add, GR64, asextloadi32, 4>;
def AG : BinaryRXY<"ag", 0xE308, add, GR64, load, 8>;
@ -1006,6 +1016,8 @@ let Defs = [CC], CCValues = 0xF, CompareZeroCCMask = 0x8 in {
// Subtraction of memory.
defm SH : BinaryRXPair<"sh", 0x4B, 0xE37B, sub, GR32, asextloadi16, 2>;
defm S : BinaryRXPair<"s", 0x5B, 0xE35B, sub, GR32, load, 4>;
def SGH : BinaryRXY<"sgh", 0xE339, sub, GR64, asextloadi16, 2>,
Requires<[FeatureMiscellaneousExtensions2]>;
def SGF : BinaryRXY<"sgf", 0xE319, sub, GR64, asextloadi32, 4>;
def SG : BinaryRXY<"sg", 0xE309, sub, GR64, load, 8>;
}
@ -1207,6 +1219,15 @@ defm : RMWIByte<xor, bdaddr20pair, XIY>;
// Multiplication
//===----------------------------------------------------------------------===//
// Multiplication of a register, setting the condition code. We prefer these
// over MS(G)R if available, even though we cannot use the condition code,
// since they are three-operand instructions.
let Predicates = [FeatureMiscellaneousExtensions2],
Defs = [CC], isCommutable = 1 in {
def MSRKC : BinaryRRFa<"msrkc", 0xB9FD, mul, GR32, GR32, GR32>;
def MSGRKC : BinaryRRFa<"msgrkc", 0xB9ED, mul, GR64, GR64, GR64>;
}
// Multiplication of a register.
let isCommutable = 1 in {
def MSR : BinaryRRE<"msr", 0xB252, mul, GR32, GR32>;
@ -1226,21 +1247,37 @@ def MSGFI : BinaryRIL<"msgfi", 0xC20, mul, GR64, imm64sx32>;
// Multiplication of memory.
defm MH : BinaryRXPair<"mh", 0x4C, 0xE37C, mul, GR32, asextloadi16, 2>;
defm MS : BinaryRXPair<"ms", 0x71, 0xE351, mul, GR32, load, 4>;
def MGH : BinaryRXY<"mgh", 0xE33C, mul, GR64, asextloadi16, 2>,
Requires<[FeatureMiscellaneousExtensions2]>;
def MSGF : BinaryRXY<"msgf", 0xE31C, mul, GR64, asextloadi32, 4>;
def MSG : BinaryRXY<"msg", 0xE30C, mul, GR64, load, 8>;
// Multiplication of memory, setting the condition code.
let Predicates = [FeatureMiscellaneousExtensions2], Defs = [CC] in {
def MSC : BinaryRXY<"msc", 0xE353, null_frag, GR32, load, 4>;
def MSGC : BinaryRXY<"msgc", 0xE383, null_frag, GR64, load, 8>;
}
// Multiplication of a register, producing two results.
def MR : BinaryRR <"mr", 0x1C, null_frag, GR128, GR32>;
def MR : BinaryRR <"mr", 0x1C, null_frag, GR128, GR32>;
def MGRK : BinaryRRFa<"mgrk", 0xB9EC, null_frag, GR128, GR64, GR64>,
Requires<[FeatureMiscellaneousExtensions2]>;
def MLR : BinaryRRE<"mlr", 0xB996, null_frag, GR128, GR32>;
def MLGR : BinaryRRE<"mlgr", 0xB986, null_frag, GR128, GR64>;
def : Pat<(z_smul_lohi GR64:$src1, GR64:$src2),
(MGRK GR64:$src1, GR64:$src2)>;
def : Pat<(z_umul_lohi GR64:$src1, GR64:$src2),
(MLGR (AEXT128 GR64:$src1), GR64:$src2)>;
// Multiplication of memory, producing two results.
def M : BinaryRX <"m", 0x5C, null_frag, GR128, load, 4>;
def MFY : BinaryRXY<"mfy", 0xE35C, null_frag, GR128, load, 4>;
def MG : BinaryRXY<"mg", 0xE384, null_frag, GR128, load, 8>,
Requires<[FeatureMiscellaneousExtensions2]>;
def ML : BinaryRXY<"ml", 0xE396, null_frag, GR128, load, 4>;
def MLG : BinaryRXY<"mlg", 0xE386, null_frag, GR128, load, 8>;
def : Pat<(z_smul_lohi GR64:$src1, (i64 (load bdxaddr20only:$src2))),
(MG (AEXT128 GR64:$src1), bdxaddr20only:$src2)>;
def : Pat<(z_umul_lohi GR64:$src1, (i64 (load bdxaddr20only:$src2))),
(MLG (AEXT128 GR64:$src1), bdxaddr20only:$src2)>;
@ -1765,8 +1802,29 @@ let mayLoad = 1, mayStore = 1, Uses = [R0L, R1D], Defs = [CC] in {
GR128, GR128, GR128>;
def PCC : SideEffectInherentRRE<"pcc", 0xB92C>;
}
let Predicates = [FeatureMessageSecurityAssist5] in
def PPNO : SideEffectBinaryMemMemRRE<"ppno", 0xB93C, GR128, GR128>;
def PPNO : SideEffectBinaryMemMemRRE<"ppno", 0xB93C, GR128, GR128>;
let Predicates = [FeatureMessageSecurityAssist7], isAsmParserOnly = 1 in
def PRNO : SideEffectBinaryMemMemRRE<"prno", 0xB93C, GR128, GR128>;
let Predicates = [FeatureMessageSecurityAssist8] in
def KMA : SideEffectTernaryMemMemMemRRFb<"kma", 0xB929,
GR128, GR128, GR128>;
}
//===----------------------------------------------------------------------===//
// Guarded storage
//===----------------------------------------------------------------------===//
let Predicates = [FeatureGuardedStorage] in {
def LGG : UnaryRXY<"lgg", 0xE34C, null_frag, GR64, 8>;
def LLGFSG : UnaryRXY<"llgfsg", 0xE348, null_frag, GR64, 4>;
let mayLoad = 1 in
def LGSC : SideEffectBinaryRXY<"lgsc", 0xE34D, GR64>;
let mayStore = 1 in
def STGSC : SideEffectBinaryRXY<"stgsc", 0xE349, GR64>;
}
//===----------------------------------------------------------------------===//

View File

@ -126,6 +126,10 @@ let hasSideEffects = 1, Defs = [CC] in
let Predicates = [FeatureResetReferenceBitsMultiple], hasSideEffects = 1 in
def RRBM : UnaryRRE<"rrbm", 0xB9AE, null_frag, GR64, GR64>;
// Insert reference bits multiple.
let Predicates = [FeatureInsertReferenceBitsMultiple], hasSideEffects = 1 in
def IRBM : UnaryRRE<"irbm", 0xB9AC, null_frag, GR64, GR64>;
// Perform frame management function.
let hasSideEffects = 1 in
def PFMF : SideEffectBinaryMemRRE<"pfmf", 0xB9AF, GR32, GR64>;

View File

@ -154,6 +154,11 @@ let Predicates = [FeatureVector] in {
(VLLEZF bdxaddr12only:$addr)>;
def : Pat<(v2f64 (z_vllezf64 bdxaddr12only:$addr)),
(VLLEZG bdxaddr12only:$addr)>;
let Predicates = [FeatureVectorEnhancements1] in {
def VLLEZLF : UnaryVRX<"vllezlf", 0xE704, z_vllezli32, v128f, 4, 6>;
def : Pat<(v4f32 (z_vllezlf32 bdxaddr12only:$addr)),
(VLLEZLF bdxaddr12only:$addr)>;
}
// Load element.
def VLEB : TernaryVRX<"vleb", 0xE700, z_vlei8, v128b, v128b, 1, imm32zx4>;
@ -170,6 +175,13 @@ let Predicates = [FeatureVector] in {
def VGEG : TernaryVRV<"vgeg", 0xE712, 8, imm32zx1>;
}
let Predicates = [FeatureVectorPackedDecimal] in {
// Load rightmost with length. The number of loaded bytes is only known
// at run time.
def VLRL : BinaryVSI<"vlrl", 0xE635, int_s390_vlrl, 0>;
def VLRLR : BinaryVRSd<"vlrlr", 0xE637, int_s390_vlrl, 0>;
}
// Use replicating loads if we're inserting a single element into an
// undefined vector. This avoids a false dependency on the previous
// register contents.
@ -227,6 +239,13 @@ let Predicates = [FeatureVector] in {
def VSCEG : StoreBinaryVRV<"vsceg", 0xE71A, 8, imm32zx1>;
}
let Predicates = [FeatureVectorPackedDecimal] in {
// Store rightmost with length. The number of stored bytes is only known
// at run time.
def VSTRL : StoreLengthVSI<"vstrl", 0xE63D, int_s390_vstrl, 0>;
def VSTRLR : StoreLengthVRSd<"vstrlr", 0xE63F, int_s390_vstrl, 0>;
}
//===----------------------------------------------------------------------===//
// Selects and permutes
//===----------------------------------------------------------------------===//
@ -256,6 +275,10 @@ let Predicates = [FeatureVector] in {
// Permute doubleword immediate.
def VPDI : TernaryVRRc<"vpdi", 0xE784, z_permute_dwords, v128g, v128g>;
// Bit Permute.
let Predicates = [FeatureVectorEnhancements1] in
def VBPERM : BinaryVRRc<"vbperm", 0xE785, int_s390_vbperm, v128g, v128b>;
// Replicate.
def VREP: BinaryVRIcGeneric<"vrep", 0xE74D>;
def VREPB : BinaryVRIc<"vrepb", 0xE74D, z_splat, v128b, v128b, 0>;
@ -424,6 +447,10 @@ let Predicates = [FeatureVector] in {
def VCTZF : UnaryVRRa<"vctzf", 0xE752, cttz, v128f, v128f, 2>;
def VCTZG : UnaryVRRa<"vctzg", 0xE752, cttz, v128g, v128g, 3>;
// Not exclusive or.
let Predicates = [FeatureVectorEnhancements1] in
def VNX : BinaryVRRc<"vnx", 0xE76C, null_frag, v128any, v128any>;
// Exclusive or.
def VX : BinaryVRRc<"vx", 0xE76D, null_frag, v128any, v128any>;
@ -567,6 +594,17 @@ let Predicates = [FeatureVector] in {
def VMLOH : BinaryVRRc<"vmloh", 0xE7A5, int_s390_vmloh, v128f, v128h, 1>;
def VMLOF : BinaryVRRc<"vmlof", 0xE7A5, int_s390_vmlof, v128g, v128f, 2>;
// Multiply sum logical.
let Predicates = [FeatureVectorEnhancements1] in {
def VMSL : QuaternaryVRRdGeneric<"vmsl", 0xE7B8>;
def VMSLG : QuaternaryVRRd<"vmslg", 0xE7B8, int_s390_vmslg,
v128q, v128g, v128g, v128q, 3>;
}
// Nand.
let Predicates = [FeatureVectorEnhancements1] in
def VNN : BinaryVRRc<"vnn", 0xE76E, null_frag, v128any, v128any>;
// Nor.
def VNO : BinaryVRRc<"vno", 0xE76B, null_frag, v128any, v128any>;
def : InstAlias<"vnot\t$V1, $V2", (VNO VR128:$V1, VR128:$V2, VR128:$V2), 0>;
@ -574,9 +612,19 @@ let Predicates = [FeatureVector] in {
// Or.
def VO : BinaryVRRc<"vo", 0xE76A, null_frag, v128any, v128any>;
// Or with complement.
let Predicates = [FeatureVectorEnhancements1] in
def VOC : BinaryVRRc<"voc", 0xE76F, null_frag, v128any, v128any>;
// Population count.
def VPOPCT : UnaryVRRaGeneric<"vpopct", 0xE750>;
def : Pat<(v16i8 (z_popcnt VR128:$x)), (VPOPCT VR128:$x, 0)>;
let Predicates = [FeatureVectorEnhancements1] in {
def VPOPCTB : UnaryVRRa<"vpopctb", 0xE750, ctpop, v128b, v128b, 0>;
def VPOPCTH : UnaryVRRa<"vpopcth", 0xE750, ctpop, v128h, v128h, 1>;
def VPOPCTF : UnaryVRRa<"vpopctf", 0xE750, ctpop, v128f, v128f, 2>;
def VPOPCTG : UnaryVRRa<"vpopctg", 0xE750, ctpop, v128g, v128g, 3>;
}
// Element rotate left logical (with vector shift amount).
def VERLLV : BinaryVRRcGeneric<"verllv", 0xE773>;
@ -724,6 +772,14 @@ multiclass BitwiseVectorOps<ValueType type> {
(VNO VR128:$x, VR128:$y)>;
def : Pat<(type (z_vnot VR128:$x)), (VNO VR128:$x, VR128:$x)>;
}
let Predicates = [FeatureVectorEnhancements1] in {
def : Pat<(type (z_vnot (xor VR128:$x, VR128:$y))),
(VNX VR128:$x, VR128:$y)>;
def : Pat<(type (z_vnot (and VR128:$x, VR128:$y))),
(VNN VR128:$x, VR128:$y)>;
def : Pat<(type (or VR128:$x, (z_vnot VR128:$y))),
(VOC VR128:$x, VR128:$y)>;
}
}
defm : BitwiseVectorOps<v16i8>;
@ -930,6 +986,36 @@ let Predicates = [FeatureVector] in {
def : Pat<(v4f32 (z_vround (v2f64 VR128:$src))), (VLEDB VR128:$src, 0, 0)>;
def : FPConversion<WLEDB, fpround, v32eb, v64db, 0, 0>;
// Maximum.
multiclass VectorMax<Instruction insn, TypedReg tr> {
def : FPMinMax<insn, fmaxnum, tr, 4>;
def : FPMinMax<insn, fmaxnan, tr, 1>;
}
let Predicates = [FeatureVectorEnhancements1] in {
def VFMAX : TernaryVRRcFloatGeneric<"vfmax", 0xE7EF>;
def VFMAXDB : TernaryVRRcFloat<"vfmaxdb", 0xE7EF, int_s390_vfmaxdb,
v128db, v128db, 3, 0>;
def WFMAXDB : TernaryVRRcFloat<"wfmaxdb", 0xE7EF, null_frag,
v64db, v64db, 3, 8>;
defm : VectorMax<VFMAXDB, v128db>;
defm : VectorMax<WFMAXDB, v64db>;
}
// Minimum.
multiclass VectorMin<Instruction insn, TypedReg tr> {
def : FPMinMax<insn, fminnum, tr, 4>;
def : FPMinMax<insn, fminnan, tr, 1>;
}
let Predicates = [FeatureVectorEnhancements1] in {
def VFMIN : TernaryVRRcFloatGeneric<"vfmin", 0xE7EE>;
def VFMINDB : TernaryVRRcFloat<"vfmindb", 0xE7EE, int_s390_vfmindb,
v128db, v128db, 3, 0>;
def WFMINDB : TernaryVRRcFloat<"wfmindb", 0xE7EE, null_frag,
v64db, v64db, 3, 8>;
defm : VectorMin<VFMINDB, v128db>;
defm : VectorMin<WFMINDB, v64db>;
}
// Multiply.
def VFM : BinaryVRRcFloatGeneric<"vfm", 0xE7E7>;
def VFMDB : BinaryVRRc<"vfmdb", 0xE7E7, fmul, v128db, v128db, 3, 0>;
@ -945,6 +1031,20 @@ let Predicates = [FeatureVector] in {
def VFMSDB : TernaryVRRe<"vfmsdb", 0xE78E, fms, v128db, v128db, 0, 3>;
def WFMSDB : TernaryVRRe<"wfmsdb", 0xE78E, fms, v64db, v64db, 8, 3>;
// Negative multiply and add.
let Predicates = [FeatureVectorEnhancements1] in {
def VFNMA : TernaryVRReFloatGeneric<"vfnma", 0xE79F>;
def VFNMADB : TernaryVRRe<"vfnmadb", 0xE79F, fnma, v128db, v128db, 0, 3>;
def WFNMADB : TernaryVRRe<"wfnmadb", 0xE79F, fnma, v64db, v64db, 8, 3>;
}
// Negative multiply and subtract.
let Predicates = [FeatureVectorEnhancements1] in {
def VFNMS : TernaryVRReFloatGeneric<"vfnms", 0xE79E>;
def VFNMSDB : TernaryVRRe<"vfnmsdb", 0xE79E, fnms, v128db, v128db, 0, 3>;
def WFNMSDB : TernaryVRRe<"wfnmsdb", 0xE79E, fnms, v64db, v64db, 8, 3>;
}
// Perform sign operation.
def VFPSO : BinaryVRRaFloatGeneric<"vfpso", 0xE7CC>;
def VFPSODB : BinaryVRRa<"vfpsodb", 0xE7CC, null_frag, v128db, v128db, 3, 0>;
@ -1004,6 +1104,14 @@ let Predicates = [FeatureVector] in {
defm WFCEDB : BinaryVRRcSPair<"wfcedb", 0xE7E8, null_frag, null_frag,
v64g, v64db, 3, 8>;
// Compare and signal equal.
let Predicates = [FeatureVectorEnhancements1] in {
defm VFKEDB : BinaryVRRcSPair<"vfkedb", 0xE7E8, null_frag, null_frag,
v128g, v128db, 3, 4>;
defm WFKEDB : BinaryVRRcSPair<"wfkedb", 0xE7E8, null_frag, null_frag,
v64g, v64db, 3, 12>;
}
// Compare high.
def VFCH : BinaryVRRcSPairFloatGeneric<"vfch", 0xE7EB>;
defm VFCHDB : BinaryVRRcSPair<"vfchdb", 0xE7EB, z_vfcmph, z_vfcmphs,
@ -1011,12 +1119,28 @@ let Predicates = [FeatureVector] in {
defm WFCHDB : BinaryVRRcSPair<"wfchdb", 0xE7EB, null_frag, null_frag,
v64g, v64db, 3, 8>;
// Compare and signal high.
let Predicates = [FeatureVectorEnhancements1] in {
defm VFKHDB : BinaryVRRcSPair<"vfkhdb", 0xE7EB, null_frag, null_frag,
v128g, v128db, 3, 4>;
defm WFKHDB : BinaryVRRcSPair<"wfkhdb", 0xE7EB, null_frag, null_frag,
v64g, v64db, 3, 12>;
}
// Compare high or equal.
def VFCHE : BinaryVRRcSPairFloatGeneric<"vfche", 0xE7EA>;
defm VFCHEDB : BinaryVRRcSPair<"vfchedb", 0xE7EA, z_vfcmphe, z_vfcmphes,
v128g, v128db, 3, 0>;
defm WFCHEDB : BinaryVRRcSPair<"wfchedb", 0xE7EA, null_frag, null_frag,
v64g, v64db, 3, 8>;
// Compare and signal high or equal.
let Predicates = [FeatureVectorEnhancements1] in {
defm VFKHEDB : BinaryVRRcSPair<"vfkhedb", 0xE7EA, null_frag, null_frag,
v128g, v128db, 3, 4>;
defm WFKHEDB : BinaryVRRcSPair<"wfkhedb", 0xE7EA, null_frag, null_frag,
v64g, v64db, 3, 12>;
}
}
//===----------------------------------------------------------------------===//
@ -1202,3 +1326,37 @@ let Predicates = [FeatureVector] in {
defm VSTRCZF : QuaternaryOptVRRdSPair<"vstrczf", 0xE78A, int_s390_vstrczf,
z_vstrcz_cc, v128f, v128f, 2, 2>;
}
//===----------------------------------------------------------------------===//
// Packed-decimal instructions
//===----------------------------------------------------------------------===//
let Predicates = [FeatureVectorPackedDecimal] in {
def VLIP : BinaryVRIh<"vlip", 0xE649>;
def VPKZ : BinaryVSI<"vpkz", 0xE634, null_frag, 0>;
def VUPKZ : StoreLengthVSI<"vupkz", 0xE63C, null_frag, 0>;
let Defs = [CC] in {
def VCVB : BinaryVRRi<"vcvb", 0xE650, GR32>;
def VCVBG : BinaryVRRi<"vcvbg", 0xE652, GR64>;
def VCVD : TernaryVRIi<"vcvd", 0xE658, GR32>;
def VCVDG : TernaryVRIi<"vcvdg", 0xE65A, GR64>;
def VAP : QuaternaryVRIf<"vap", 0xE671>;
def VSP : QuaternaryVRIf<"vsp", 0xE673>;
def VMP : QuaternaryVRIf<"vmp", 0xE678>;
def VMSP : QuaternaryVRIf<"vmsp", 0xE679>;
def VDP : QuaternaryVRIf<"vdp", 0xE67A>;
def VRP : QuaternaryVRIf<"vrp", 0xE67B>;
def VSDP : QuaternaryVRIf<"vsdp", 0xE67E>;
def VSRP : QuaternaryVRIg<"vsrp", 0xE659>;
def VPSOP : QuaternaryVRIg<"vpsop", 0xE65B>;
def VTP : TestVRRg<"vtp", 0xE65F>;
def VCP : CompareVRRh<"vcp", 0xE677>;
}
}

View File

@ -181,6 +181,7 @@ def z_select_ccmask : SDNode<"SystemZISD::SELECT_CCMASK", SDT_ZSelectCCMask,
[SDNPInGlue]>;
def z_adjdynalloc : SDNode<"SystemZISD::ADJDYNALLOC", SDT_ZAdjDynAlloc>;
def z_popcnt : SDNode<"SystemZISD::POPCNT", SDTIntUnaryOp>;
def z_smul_lohi : SDNode<"SystemZISD::SMUL_LOHI", SDT_ZGR128Binary>;
def z_umul_lohi : SDNode<"SystemZISD::UMUL_LOHI", SDT_ZGR128Binary>;
def z_sdivrem : SDNode<"SystemZISD::SDIVREM", SDT_ZGR128Binary>;
def z_udivrem : SDNode<"SystemZISD::UDIVREM", SDT_ZGR128Binary>;
@ -549,6 +550,12 @@ def z_fma : PatFrag<(ops node:$src1, node:$src2, node:$src3),
def z_fms : PatFrag<(ops node:$src1, node:$src2, node:$src3),
(fma node:$src2, node:$src3, (fneg node:$src1))>;
// Negative fused multiply-add and multiply-subtract.
def fnma : PatFrag<(ops node:$src1, node:$src2, node:$src3),
(fneg (fma node:$src1, node:$src2, node:$src3))>;
def fnms : PatFrag<(ops node:$src1, node:$src2, node:$src3),
(fneg (fms node:$src1, node:$src2, node:$src3))>;
// Floating-point negative absolute.
def fnabs : PatFrag<(ops node:$ptr), (fneg (fabs node:$ptr))>;
@ -624,6 +631,19 @@ def z_vllezf64 : PatFrag<(ops node:$addr),
(scalar_to_vector (f64 (load node:$addr))),
(z_vzero))>;
// Similarly for the high element of a zeroed vector.
def z_vllezli32 : z_vllez<i32, load, 0>;
def z_vllezlf32 : PatFrag<(ops node:$addr),
(bitconvert
(z_merge_high
(v2i64
(bitconvert
(z_merge_high
(v4f32 (scalar_to_vector
(f32 (load node:$addr)))),
(v4f32 (z_vzero))))),
(v2i64 (z_vzero))))>;
// Store one element of a vector.
class z_vste<ValueType scalartype, SDPatternOperator store>
: PatFrag<(ops node:$vec, node:$addr, node:$index),

View File

@ -167,3 +167,10 @@ class FPConversion<Instruction insn, SDPatternOperator operator, TypedReg tr1,
TypedReg tr2, bits<3> suppress, bits<4> mode>
: Pat<(tr1.vt (operator (tr2.vt tr2.op:$vec))),
(insn tr2.op:$vec, suppress, mode)>;
// Use INSN to perform mininum/maximum operation OPERATOR on type TR.
// FUNCTION is the type of minimum/maximum function to perform.
class FPMinMax<Instruction insn, SDPatternOperator operator, TypedReg tr,
bits<4> function>
: Pat<(tr.vt (operator (tr.vt tr.op:$vec1), (tr.vt tr.op:$vec2))),
(insn tr.op:$vec1, tr.op:$vec2, function)>;

View File

@ -33,3 +33,6 @@ def : ProcessorModel<"zEC12", ZEC12Model, Arch10SupportedFeatures.List>;
def : ProcessorModel<"arch11", Z13Model, Arch11SupportedFeatures.List>;
def : ProcessorModel<"z13", Z13Model, Arch11SupportedFeatures.List>;
def : ProcessorModel<"arch12", Z14Model, Arch12SupportedFeatures.List>;
def : ProcessorModel<"z14", Z14Model, Arch12SupportedFeatures.List>;

View File

@ -59,7 +59,7 @@ def FPU2 : SchedWrite;
def DFU : SchedWrite;
def DFU2 : SchedWrite;
// Vector sub units (z13)
// Vector sub units (z13 and later)
def VecBF : SchedWrite;
def VecBF2 : SchedWrite;
def VecDF : SchedWrite;
@ -75,6 +75,7 @@ def VecXsPm : SchedWrite;
def VBU : SchedWrite;
include "SystemZScheduleZ14.td"
include "SystemZScheduleZ13.td"
include "SystemZScheduleZEC12.td"
include "SystemZScheduleZ196.td"

File diff suppressed because it is too large Load Diff

View File

@ -47,6 +47,10 @@ SystemZSubtarget::SystemZSubtarget(const Triple &TT, const std::string &CPU,
HasVector(false), HasLoadStoreOnCond2(false),
HasLoadAndZeroRightmostByte(false), HasMessageSecurityAssist5(false),
HasDFPPackedConversion(false),
HasMiscellaneousExtensions2(false), HasGuardedStorage(false),
HasMessageSecurityAssist7(false), HasMessageSecurityAssist8(false),
HasVectorEnhancements1(false), HasVectorPackedDecimal(false),
HasInsertReferenceBitsMultiple(false),
TargetTriple(TT), InstrInfo(initializeSubtargetDependencies(CPU, FS)),
TLInfo(TM, *this), TSInfo(), FrameLowering() {}

View File

@ -56,6 +56,13 @@ protected:
bool HasLoadAndZeroRightmostByte;
bool HasMessageSecurityAssist5;
bool HasDFPPackedConversion;
bool HasMiscellaneousExtensions2;
bool HasGuardedStorage;
bool HasMessageSecurityAssist7;
bool HasMessageSecurityAssist8;
bool HasVectorEnhancements1;
bool HasVectorPackedDecimal;
bool HasInsertReferenceBitsMultiple;
private:
Triple TargetTriple;
@ -168,6 +175,33 @@ public:
// Return true if the target has the vector facility.
bool hasVector() const { return HasVector; }
// Return true if the target has the miscellaneous-extensions facility 2.
bool hasMiscellaneousExtensions2() const {
return HasMiscellaneousExtensions2;
}
// Return true if the target has the guarded-storage facility.
bool hasGuardedStorage() const { return HasGuardedStorage; }
// Return true if the target has the message-security-assist
// extension facility 7.
bool hasMessageSecurityAssist7() const { return HasMessageSecurityAssist7; }
// Return true if the target has the message-security-assist
// extension facility 8.
bool hasMessageSecurityAssist8() const { return HasMessageSecurityAssist8; }
// Return true if the target has the vector-enhancements facility 1.
bool hasVectorEnhancements1() const { return HasVectorEnhancements1; }
// Return true if the target has the vector-packed-decimal facility.
bool hasVectorPackedDecimal() const { return HasVectorPackedDecimal; }
// Return true if the target has the insert-reference-bits-multiple facility.
bool hasInsertReferenceBitsMultiple() const {
return HasInsertReferenceBitsMultiple;
}
// Return true if GV can be accessed using LARL for reloc model RM
// and code model CM.
bool isPC32DBLSymbol(const GlobalValue *GV, CodeModel::Model CM) const;

View File

@ -0,0 +1,56 @@
; Test indirect jumps on z14.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
define i32 @f1(i32 %x, i32 %y, i32 %op) {
; CHECK-LABEL: f1:
; CHECK: ahi %r4, -1
; CHECK: clibh %r4, 5, 0(%r14)
; CHECK: llgfr [[OP64:%r[0-5]]], %r4
; CHECK: sllg [[INDEX:%r[1-5]]], [[OP64]], 3
; CHECK: larl [[BASE:%r[1-5]]]
; CHECK: bi 0([[BASE]],[[INDEX]])
entry:
switch i32 %op, label %exit [
i32 1, label %b.add
i32 2, label %b.sub
i32 3, label %b.and
i32 4, label %b.or
i32 5, label %b.xor
i32 6, label %b.mul
]
b.add:
%add = add i32 %x, %y
br label %exit
b.sub:
%sub = sub i32 %x, %y
br label %exit
b.and:
%and = and i32 %x, %y
br label %exit
b.or:
%or = or i32 %x, %y
br label %exit
b.xor:
%xor = xor i32 %x, %y
br label %exit
b.mul:
%mul = mul i32 %x, %y
br label %exit
exit:
%res = phi i32 [ %x, %entry ],
[ %add, %b.add ],
[ %sub, %b.sub ],
[ %and, %b.and ],
[ %or, %b.or ],
[ %xor, %b.xor ],
[ %mul, %b.mul ]
ret i32 %res
}

View File

@ -0,0 +1,23 @@
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
declare double @llvm.fma.f64(double %f1, double %f2, double %f3)
define double @f1(double %f1, double %f2, double %acc) {
; CHECK-LABEL: f1:
; CHECK: wfnmadb %f0, %f0, %f2, %f4
; CHECK: br %r14
%res = call double @llvm.fma.f64 (double %f1, double %f2, double %acc)
%negres = fsub double -0.0, %res
ret double %negres
}
define double @f2(double %f1, double %f2, double %acc) {
; CHECK-LABEL: f2:
; CHECK: wfnmsdb %f0, %f0, %f2, %f4
; CHECK: br %r14
%negacc = fsub double -0.0, %acc
%res = call double @llvm.fma.f64 (double %f1, double %f2, double %negacc)
%negres = fsub double -0.0, %res
ret double %negres
}

View File

@ -0,0 +1,95 @@
; Test additions between an i64 and a sign-extended i16 on z14.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
declare i64 @foo()
; Check AGH with no displacement.
define i64 @f1(i64 %a, i16 *%src) {
; CHECK-LABEL: f1:
; CHECK: agh %r2, 0(%r3)
; CHECK: br %r14
%b = load i16, i16 *%src
%bext = sext i16 %b to i64
%add = add i64 %a, %bext
ret i64 %add
}
; Check the high end of the aligned AGH range.
define i64 @f2(i64 %a, i16 *%src) {
; CHECK-LABEL: f2:
; CHECK: agh %r2, 524286(%r3)
; CHECK: br %r14
%ptr = getelementptr i16, i16 *%src, i64 262143
%b = load i16, i16 *%ptr
%bext = sext i16 %b to i64
%add = add i64 %a, %bext
ret i64 %add
}
; Check the next word up, which needs separate address logic.
; Other sequences besides this one would be OK.
define i64 @f3(i64 %a, i16 *%src) {
; CHECK-LABEL: f3:
; CHECK: agfi %r3, 524288
; CHECK: agh %r2, 0(%r3)
; CHECK: br %r14
%ptr = getelementptr i16, i16 *%src, i64 262144
%b = load i16, i16 *%ptr
%bext = sext i16 %b to i64
%add = add i64 %a, %bext
ret i64 %add
}
; Check the high end of the negative aligned AGH range.
define i64 @f4(i64 %a, i16 *%src) {
; CHECK-LABEL: f4:
; CHECK: agh %r2, -2(%r3)
; CHECK: br %r14
%ptr = getelementptr i16, i16 *%src, i64 -1
%b = load i16, i16 *%ptr
%bext = sext i16 %b to i64
%add = add i64 %a, %bext
ret i64 %add
}
; Check the low end of the AGH range.
define i64 @f5(i64 %a, i16 *%src) {
; CHECK-LABEL: f5:
; CHECK: agh %r2, -524288(%r3)
; CHECK: br %r14
%ptr = getelementptr i16, i16 *%src, i64 -262144
%b = load i16, i16 *%ptr
%bext = sext i16 %b to i64
%add = add i64 %a, %bext
ret i64 %add
}
; Check the next word down, which needs separate address logic.
; Other sequences besides this one would be OK.
define i64 @f6(i64 %a, i16 *%src) {
; CHECK-LABEL: f6:
; CHECK: agfi %r3, -524290
; CHECK: agh %r2, 0(%r3)
; CHECK: br %r14
%ptr = getelementptr i16, i16 *%src, i64 -262145
%b = load i16, i16 *%ptr
%bext = sext i16 %b to i64
%add = add i64 %a, %bext
ret i64 %add
}
; Check that AGH allows an index.
define i64 @f7(i64 %a, i64 %src, i64 %index) {
; CHECK-LABEL: f7:
; CHECK: agh %r2, 524284({{%r4,%r3|%r3,%r4}})
; CHECK: br %r14
%add1 = add i64 %src, %index
%add2 = add i64 %add1, 524284
%ptr = inttoptr i64 %add2 to i16 *
%b = load i16, i16 *%ptr
%bext = sext i16 %b to i64
%add = add i64 %a, %bext
ret i64 %add
}

View File

@ -0,0 +1,95 @@
; Test multiplications between an i64 and a sign-extended i16 on z14.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
declare i64 @foo()
; Check MGH with no displacement.
define i64 @f1(i64 %a, i16 *%src) {
; CHECK-LABEL: f1:
; CHECK: mgh %r2, 0(%r3)
; CHECK: br %r14
%b = load i16, i16 *%src
%bext = sext i16 %b to i64
%mul = mul i64 %a, %bext
ret i64 %mul
}
; Check the high end of the aligned MGH range.
define i64 @f2(i64 %a, i16 *%src) {
; CHECK-LABEL: f2:
; CHECK: mgh %r2, 524286(%r3)
; CHECK: br %r14
%ptr = getelementptr i16, i16 *%src, i64 262143
%b = load i16, i16 *%ptr
%bext = sext i16 %b to i64
%mul = mul i64 %a, %bext
ret i64 %mul
}
; Check the next word up, which needs separate address logic.
; Other sequences besides this one would be OK.
define i64 @f3(i64 %a, i16 *%src) {
; CHECK-LABEL: f3:
; CHECK: agfi %r3, 524288
; CHECK: mgh %r2, 0(%r3)
; CHECK: br %r14
%ptr = getelementptr i16, i16 *%src, i64 262144
%b = load i16, i16 *%ptr
%bext = sext i16 %b to i64
%mul = mul i64 %a, %bext
ret i64 %mul
}
; Check the high end of the negative aligned MGH range.
define i64 @f4(i64 %a, i16 *%src) {
; CHECK-LABEL: f4:
; CHECK: mgh %r2, -2(%r3)
; CHECK: br %r14
%ptr = getelementptr i16, i16 *%src, i64 -1
%b = load i16, i16 *%ptr
%bext = sext i16 %b to i64
%mul = mul i64 %a, %bext
ret i64 %mul
}
; Check the low end of the MGH range.
define i64 @f5(i64 %a, i16 *%src) {
; CHECK-LABEL: f5:
; CHECK: mgh %r2, -524288(%r3)
; CHECK: br %r14
%ptr = getelementptr i16, i16 *%src, i64 -262144
%b = load i16, i16 *%ptr
%bext = sext i16 %b to i64
%mul = mul i64 %a, %bext
ret i64 %mul
}
; Check the next word down, which needs separate address logic.
; Other sequences besides this one would be OK.
define i64 @f6(i64 %a, i16 *%src) {
; CHECK-LABEL: f6:
; CHECK: agfi %r3, -524290
; CHECK: mgh %r2, 0(%r3)
; CHECK: br %r14
%ptr = getelementptr i16, i16 *%src, i64 -262145
%b = load i16, i16 *%ptr
%bext = sext i16 %b to i64
%mul = mul i64 %a, %bext
ret i64 %mul
}
; Check that MGH allows an index.
define i64 @f7(i64 %a, i64 %src, i64 %index) {
; CHECK-LABEL: f7:
; CHECK: mgh %r2, 524284({{%r4,%r3|%r3,%r4}})
; CHECK: br %r14
%add1 = add i64 %src, %index
%add2 = add i64 %add1, 524284
%ptr = inttoptr i64 %add2 to i16 *
%b = load i16, i16 *%ptr
%bext = sext i16 %b to i64
%mul = mul i64 %a, %bext
ret i64 %mul
}

View File

@ -0,0 +1,165 @@
; Test signed high-part i64->i128 multiplications on z14.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
declare i64 @foo()
; Check sign-extended multiplication in which only the high part is used.
define i64 @f1(i64 %dummy, i64 %a, i64 %b) {
; CHECK-LABEL: f1:
; CHECK-NOT: {{%r[234]}}
; CHECK: mgrk %r2, %r3, %r4
; CHECK: br %r14
%ax = sext i64 %a to i128
%bx = sext i64 %b to i128
%mulx = mul i128 %ax, %bx
%highx = lshr i128 %mulx, 64
%high = trunc i128 %highx to i64
ret i64 %high
}
; Check sign-extended multiplication in which only part of the high half
; is used.
define i64 @f2(i64 %dummy, i64 %a, i64 %b) {
; CHECK-LABEL: f2:
; CHECK-NOT: {{%r[234]}}
; CHECK: mgrk [[REG:%r[0-9]+]], %r3, %r4
; CHECK: srlg %r2, [[REG]], 3
; CHECK: br %r14
%ax = sext i64 %a to i128
%bx = sext i64 %b to i128
%mulx = mul i128 %ax, %bx
%highx = lshr i128 %mulx, 67
%high = trunc i128 %highx to i64
ret i64 %high
}
; Check sign-extended multiplication in which the result is split into
; high and low halves.
define i64 @f3(i64 %dummy, i64 %a, i64 %b) {
; CHECK-LABEL: f3:
; CHECK-NOT: {{%r[234]}}
; CHECK: mgrk %r2, %r3, %r4
; CHECK: ogr %r2, %r3
; CHECK: br %r14
%ax = sext i64 %a to i128
%bx = sext i64 %b to i128
%mulx = mul i128 %ax, %bx
%highx = lshr i128 %mulx, 64
%high = trunc i128 %highx to i64
%low = trunc i128 %mulx to i64
%or = or i64 %high, %low
ret i64 %or
}
; Check MG with no displacement.
define i64 @f4(i64 %dummy, i64 %a, i64 *%src) {
; CHECK-LABEL: f4:
; CHECK-NOT: {{%r[234]}}
; CHECK: mg %r2, 0(%r4)
; CHECK: br %r14
%b = load i64 , i64 *%src
%ax = sext i64 %a to i128
%bx = sext i64 %b to i128
%mulx = mul i128 %ax, %bx
%highx = lshr i128 %mulx, 64
%high = trunc i128 %highx to i64
ret i64 %high
}
; Check the high end of the aligned MG range.
define i64 @f5(i64 %dummy, i64 %a, i64 *%src) {
; CHECK-LABEL: f5:
; CHECK: mg %r2, 524280(%r4)
; CHECK: br %r14
%ptr = getelementptr i64, i64 *%src, i64 65535
%b = load i64 , i64 *%ptr
%ax = sext i64 %a to i128
%bx = sext i64 %b to i128
%mulx = mul i128 %ax, %bx
%highx = lshr i128 %mulx, 64
%high = trunc i128 %highx to i64
ret i64 %high
}
; Check the next doubleword up, which requires separate address logic.
; Other sequences besides this one would be OK.
define i64 @f6(i64 %dummy, i64 %a, i64 *%src) {
; CHECK-LABEL: f6:
; CHECK: agfi %r4, 524288
; CHECK: mg %r2, 0(%r4)
; CHECK: br %r14
%ptr = getelementptr i64, i64 *%src, i64 65536
%b = load i64 , i64 *%ptr
%ax = sext i64 %a to i128
%bx = sext i64 %b to i128
%mulx = mul i128 %ax, %bx
%highx = lshr i128 %mulx, 64
%high = trunc i128 %highx to i64
ret i64 %high
}
; Check the high end of the negative aligned MG range.
define i64 @f7(i64 %dummy, i64 %a, i64 *%src) {
; CHECK-LABEL: f7:
; CHECK: mg %r2, -8(%r4)
; CHECK: br %r14
%ptr = getelementptr i64, i64 *%src, i64 -1
%b = load i64 , i64 *%ptr
%ax = sext i64 %a to i128
%bx = sext i64 %b to i128
%mulx = mul i128 %ax, %bx
%highx = lshr i128 %mulx, 64
%high = trunc i128 %highx to i64
ret i64 %high
}
; Check the low end of the MG range.
define i64 @f8(i64 %dummy, i64 %a, i64 *%src) {
; CHECK-LABEL: f8:
; CHECK: mg %r2, -524288(%r4)
; CHECK: br %r14
%ptr = getelementptr i64, i64 *%src, i64 -65536
%b = load i64 , i64 *%ptr
%ax = sext i64 %a to i128
%bx = sext i64 %b to i128
%mulx = mul i128 %ax, %bx
%highx = lshr i128 %mulx, 64
%high = trunc i128 %highx to i64
ret i64 %high
}
; Check the next doubleword down, which needs separate address logic.
; Other sequences besides this one would be OK.
define i64 @f9(i64 *%dest, i64 %a, i64 *%src) {
; CHECK-LABEL: f9:
; CHECK: agfi %r4, -524296
; CHECK: mg %r2, 0(%r4)
; CHECK: br %r14
%ptr = getelementptr i64, i64 *%src, i64 -65537
%b = load i64 , i64 *%ptr
%ax = sext i64 %a to i128
%bx = sext i64 %b to i128
%mulx = mul i128 %ax, %bx
%highx = lshr i128 %mulx, 64
%high = trunc i128 %highx to i64
ret i64 %high
}
; Check that MG allows an index.
define i64 @f10(i64 *%dest, i64 %a, i64 %src, i64 %index) {
; CHECK-LABEL: f10:
; CHECK: mg %r2, 524287(%r5,%r4)
; CHECK: br %r14
%add1 = add i64 %src, %index
%add2 = add i64 %add1, 524287
%ptr = inttoptr i64 %add2 to i64 *
%b = load i64 , i64 *%ptr
%ax = sext i64 %a to i128
%bx = sext i64 %b to i128
%mulx = mul i128 %ax, %bx
%highx = lshr i128 %mulx, 64
%high = trunc i128 %highx to i64
ret i64 %high
}

View File

@ -0,0 +1,32 @@
; Test three-operand multiplication instructions on z14.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
; Check MSRKC.
define i32 @f1(i32 %dummy, i32 %a, i32 %b) {
; CHECK-LABEL: f1:
; CHECK: msrkc %r2, %r3, %r4
; CHECK: br %r14
%mul = mul i32 %a, %b
ret i32 %mul
}
; Check MSGRKC.
define i64 @f2(i64 %dummy, i64 %a, i64 %b) {
; CHECK-LABEL: f2:
; CHECK: msgrkc %r2, %r3, %r4
; CHECK: br %r14
%mul = mul i64 %a, %b
ret i64 %mul
}
; Verify that we still use MSGFR for i32->i64 multiplies.
define i64 @f3(i64 %a, i32 %b) {
; CHECK-LABEL: f3:
; CHECK: msgfr %r2, %r3
; CHECK: br %r14
%bext = sext i32 %b to i64
%mul = mul i64 %a, %bext
ret i64 %mul
}

View File

@ -0,0 +1,95 @@
; Test subtractions of a sign-extended i16 from an i64 on z14.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
declare i64 @foo()
; Check SGH with no displacement.
define i64 @f1(i64 %a, i16 *%src) {
; CHECK-LABEL: f1:
; CHECK: sgh %r2, 0(%r3)
; CHECK: br %r14
%b = load i16, i16 *%src
%bext = sext i16 %b to i64
%sub = sub i64 %a, %bext
ret i64 %sub
}
; Check the high end of the aligned SGH range.
define i64 @f2(i64 %a, i16 *%src) {
; CHECK-LABEL: f2:
; CHECK: sgh %r2, 524286(%r3)
; CHECK: br %r14
%ptr = getelementptr i16, i16 *%src, i64 262143
%b = load i16, i16 *%ptr
%bext = sext i16 %b to i64
%sub = sub i64 %a, %bext
ret i64 %sub
}
; Check the next word up, which needs separate address logic.
; Other sequences besides this one would be OK.
define i64 @f3(i64 %a, i16 *%src) {
; CHECK-LABEL: f3:
; CHECK: agfi %r3, 524288
; CHECK: sgh %r2, 0(%r3)
; CHECK: br %r14
%ptr = getelementptr i16, i16 *%src, i64 262144
%b = load i16, i16 *%ptr
%bext = sext i16 %b to i64
%sub = sub i64 %a, %bext
ret i64 %sub
}
; Check the high end of the negative aligned SGH range.
define i64 @f4(i64 %a, i16 *%src) {
; CHECK-LABEL: f4:
; CHECK: sgh %r2, -2(%r3)
; CHECK: br %r14
%ptr = getelementptr i16, i16 *%src, i64 -1
%b = load i16, i16 *%ptr
%bext = sext i16 %b to i64
%sub = sub i64 %a, %bext
ret i64 %sub
}
; Check the low end of the SGH range.
define i64 @f5(i64 %a, i16 *%src) {
; CHECK-LABEL: f5:
; CHECK: sgh %r2, -524288(%r3)
; CHECK: br %r14
%ptr = getelementptr i16, i16 *%src, i64 -262144
%b = load i16, i16 *%ptr
%bext = sext i16 %b to i64
%sub = sub i64 %a, %bext
ret i64 %sub
}
; Check the next word down, which needs separate address logic.
; Other sequences besides this one would be OK.
define i64 @f6(i64 %a, i16 *%src) {
; CHECK-LABEL: f6:
; CHECK: agfi %r3, -524290
; CHECK: sgh %r2, 0(%r3)
; CHECK: br %r14
%ptr = getelementptr i16, i16 *%src, i64 -262145
%b = load i16, i16 *%ptr
%bext = sext i16 %b to i64
%sub = sub i64 %a, %bext
ret i64 %sub
}
; Check that SGH allows an index.
define i64 @f7(i64 %a, i64 %src, i64 %index) {
; CHECK-LABEL: f7:
; CHECK: sgh %r2, 524284({{%r4,%r3|%r3,%r4}})
; CHECK: br %r14
%add1 = add i64 %src, %index
%add2 = add i64 %add1, 524284
%ptr = inttoptr i64 %add2 to i16 *
%b = load i16, i16 *%ptr
%bext = sext i16 %b to i64
%sub = sub i64 %a, %bext
ret i64 %sub
}

View File

@ -0,0 +1,47 @@
; Test vector NAND on z14.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
; Test a v16i8 NAND.
define <16 x i8> @f1(<16 x i8> %dummy, <16 x i8> %val1, <16 x i8> %val2) {
; CHECK-LABEL: f1:
; CHECK: vnn %v24, %v26, %v28
; CHECK: br %r14
%ret = and <16 x i8> %val1, %val2
%not = xor <16 x i8> %ret, <i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1>
ret <16 x i8> %not
}
; Test a v8i16 NAND.
define <8 x i16> @f2(<8 x i16> %dummy, <8 x i16> %val1, <8 x i16> %val2) {
; CHECK-LABEL: f2:
; CHECK: vnn %v24, %v26, %v28
; CHECK: br %r14
%ret = and <8 x i16> %val1, %val2
%not = xor <8 x i16> %ret, <i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1>
ret <8 x i16> %not
}
; Test a v4i32 NAND.
define <4 x i32> @f3(<4 x i32> %dummy, <4 x i32> %val1, <4 x i32> %val2) {
; CHECK-LABEL: f3:
; CHECK: vnn %v24, %v26, %v28
; CHECK: br %r14
%ret = and <4 x i32> %val1, %val2
%not = xor <4 x i32> %ret, <i32 -1, i32 -1, i32 -1, i32 -1>
ret <4 x i32> %not
}
; Test a v2i64 NAND.
define <2 x i64> @f4(<2 x i64> %dummy, <2 x i64> %val1, <2 x i64> %val2) {
; CHECK-LABEL: f4:
; CHECK: vnn %v24, %v26, %v28
; CHECK: br %r14
%ret = and <2 x i64> %val1, %val2
%not = xor <2 x i64> %ret, <i64 -1, i64 -1>
ret <2 x i64> %not
}

View File

@ -0,0 +1,45 @@
; Test vector population-count instruction on z14.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
declare <16 x i8> @llvm.ctpop.v16i8(<16 x i8> %a)
declare <8 x i16> @llvm.ctpop.v8i16(<8 x i16> %a)
declare <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %a)
declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a)
define <16 x i8> @f1(<16 x i8> %a) {
; CHECK-LABEL: f1:
; CHECK: vpopctb %v24, %v24
; CHECK: br %r14
%popcnt = call <16 x i8> @llvm.ctpop.v16i8(<16 x i8> %a)
ret <16 x i8> %popcnt
}
define <8 x i16> @f2(<8 x i16> %a) {
; CHECK-LABEL: f2:
; CHECK: vpopcth %v24, %v24
; CHECK: br %r14
%popcnt = call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> %a)
ret <8 x i16> %popcnt
}
define <4 x i32> @f3(<4 x i32> %a) {
; CHECK-LABEL: f3:
; CHECK: vpopctf %v24, %v24
; CHECK: br %r14
%popcnt = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %a)
ret <4 x i32> %popcnt
}
define <2 x i64> @f4(<2 x i64> %a) {
; CHECK-LABEL: f4:
; CHECK: vpopctg %v24, %v24
; CHECK: br %r14
%popcnt = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a)
ret <2 x i64> %popcnt
}

View File

@ -0,0 +1,212 @@
; Test vector intrinsics added with z14.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
declare <2 x i64> @llvm.s390.vbperm(<16 x i8>, <16 x i8>)
declare <16 x i8> @llvm.s390.vmslg(<2 x i64>, <2 x i64>, <16 x i8>, i32)
declare <16 x i8> @llvm.s390.vlrl(i32, i8 *)
declare void @llvm.s390.vstrl(<16 x i8>, i32, i8 *)
declare <2 x double> @llvm.s390.vfmaxdb(<2 x double>, <2 x double>, i32)
declare <2 x double> @llvm.s390.vfmindb(<2 x double>, <2 x double>, i32)
; VBPERM.
define <2 x i64> @test_vbperm(<16 x i8> %a, <16 x i8> %b) {
; CHECK-LABEL: test_vbperm:
; CHECK: vbperm %v24, %v24, %v26
; CHECK: br %r14
%res = call <2 x i64> @llvm.s390.vbperm(<16 x i8> %a, <16 x i8> %b)
ret <2 x i64> %res
}
; VMSLG with no shifts.
define <16 x i8> @test_vmslg1(<2 x i64> %a, <2 x i64> %b, <16 x i8> %c) {
; CHECK-LABEL: test_vmslg1:
; CHECK: vmslg %v24, %v24, %v26, %v28, 0
; CHECK: br %r14
%res = call <16 x i8> @llvm.s390.vmslg(<2 x i64> %a, <2 x i64> %b, <16 x i8> %c, i32 0)
ret <16 x i8> %res
}
; VMSLG with both shifts.
define <16 x i8> @test_vmslg2(<2 x i64> %a, <2 x i64> %b, <16 x i8> %c) {
; CHECK-LABEL: test_vmslg2:
; CHECK: vmslg %v24, %v24, %v26, %v28, 12
; CHECK: br %r14
%res = call <16 x i8> @llvm.s390.vmslg(<2 x i64> %a, <2 x i64> %b, <16 x i8> %c, i32 12)
ret <16 x i8> %res
}
; VLRLR with the lowest in-range displacement.
define <16 x i8> @test_vlrlr1(i8 *%ptr, i32 %length) {
; CHECK-LABEL: test_vlrlr1:
; CHECK: vlrlr %v24, %r3, 0(%r2)
; CHECK: br %r14
%res = call <16 x i8> @llvm.s390.vlrl(i32 %length, i8 *%ptr)
ret <16 x i8> %res
}
; VLRLR with the highest in-range displacement.
define <16 x i8> @test_vlrlr2(i8 *%base, i32 %length) {
; CHECK-LABEL: test_vlrlr2:
; CHECK: vlrlr %v24, %r3, 4095(%r2)
; CHECK: br %r14
%ptr = getelementptr i8, i8 *%base, i64 4095
%res = call <16 x i8> @llvm.s390.vlrl(i32 %length, i8 *%ptr)
ret <16 x i8> %res
}
; VLRLR with an out-of-range displacement.
define <16 x i8> @test_vlrlr3(i8 *%base, i32 %length) {
; CHECK-LABEL: test_vlrlr3:
; CHECK: vlrlr %v24, %r3, 0({{%r[1-5]}})
; CHECK: br %r14
%ptr = getelementptr i8, i8 *%base, i64 4096
%res = call <16 x i8> @llvm.s390.vlrl(i32 %length, i8 *%ptr)
ret <16 x i8> %res
}
; Check that VLRLR doesn't allow an index.
define <16 x i8> @test_vlrlr4(i8 *%base, i64 %index, i32 %length) {
; CHECK-LABEL: test_vlrlr4:
; CHECK: vlrlr %v24, %r4, 0({{%r[1-5]}})
; CHECK: br %r14
%ptr = getelementptr i8, i8 *%base, i64 %index
%res = call <16 x i8> @llvm.s390.vlrl(i32 %length, i8 *%ptr)
ret <16 x i8> %res
}
; VLRL with the lowest in-range displacement.
define <16 x i8> @test_vlrl1(i8 *%ptr) {
; CHECK-LABEL: test_vlrl1:
; CHECK: vlrl %v24, 0(%r2), 0
; CHECK: br %r14
%res = call <16 x i8> @llvm.s390.vlrl(i32 0, i8 *%ptr)
ret <16 x i8> %res
}
; VLRL with the highest in-range displacement.
define <16 x i8> @test_vlrl2(i8 *%base) {
; CHECK-LABEL: test_vlrl2:
; CHECK: vlrl %v24, 4095(%r2), 0
; CHECK: br %r14
%ptr = getelementptr i8, i8 *%base, i64 4095
%res = call <16 x i8> @llvm.s390.vlrl(i32 0, i8 *%ptr)
ret <16 x i8> %res
}
; VLRL with an out-of-range displacement.
define <16 x i8> @test_vlrl3(i8 *%base) {
; CHECK-LABEL: test_vlrl3:
; CHECK: vlrl %v24, 0({{%r[1-5]}}), 0
; CHECK: br %r14
%ptr = getelementptr i8, i8 *%base, i64 4096
%res = call <16 x i8> @llvm.s390.vlrl(i32 0, i8 *%ptr)
ret <16 x i8> %res
}
; Check that VLRL doesn't allow an index.
define <16 x i8> @test_vlrl4(i8 *%base, i64 %index) {
; CHECK-LABEL: test_vlrl4:
; CHECK: vlrl %v24, 0({{%r[1-5]}}), 0
; CHECK: br %r14
%ptr = getelementptr i8, i8 *%base, i64 %index
%res = call <16 x i8> @llvm.s390.vlrl(i32 0, i8 *%ptr)
ret <16 x i8> %res
}
; VSTRLR with the lowest in-range displacement.
define void @test_vstrlr1(<16 x i8> %vec, i8 *%ptr, i32 %length) {
; CHECK-LABEL: test_vstrlr1:
; CHECK: vstrlr %v24, %r3, 0(%r2)
; CHECK: br %r14
call void @llvm.s390.vstrl(<16 x i8> %vec, i32 %length, i8 *%ptr)
ret void
}
; VSTRLR with the highest in-range displacement.
define void @test_vstrlr2(<16 x i8> %vec, i8 *%base, i32 %length) {
; CHECK-LABEL: test_vstrlr2:
; CHECK: vstrlr %v24, %r3, 4095(%r2)
; CHECK: br %r14
%ptr = getelementptr i8, i8 *%base, i64 4095
call void @llvm.s390.vstrl(<16 x i8> %vec, i32 %length, i8 *%ptr)
ret void
}
; VSTRLR with an out-of-range displacement.
define void @test_vstrlr3(<16 x i8> %vec, i8 *%base, i32 %length) {
; CHECK-LABEL: test_vstrlr3:
; CHECK: vstrlr %v24, %r3, 0({{%r[1-5]}})
; CHECK: br %r14
%ptr = getelementptr i8, i8 *%base, i64 4096
call void @llvm.s390.vstrl(<16 x i8> %vec, i32 %length, i8 *%ptr)
ret void
}
; Check that VSTRLR doesn't allow an index.
define void @test_vstrlr4(<16 x i8> %vec, i8 *%base, i64 %index, i32 %length) {
; CHECK-LABEL: test_vstrlr4:
; CHECK: vstrlr %v24, %r4, 0({{%r[1-5]}})
; CHECK: br %r14
%ptr = getelementptr i8, i8 *%base, i64 %index
call void @llvm.s390.vstrl(<16 x i8> %vec, i32 %length, i8 *%ptr)
ret void
}
; VSTRL with the lowest in-range displacement.
define void @test_vstrl1(<16 x i8> %vec, i8 *%ptr) {
; CHECK-LABEL: test_vstrl1:
; CHECK: vstrl %v24, 0(%r2), 8
; CHECK: br %r14
call void @llvm.s390.vstrl(<16 x i8> %vec, i32 8, i8 *%ptr)
ret void
}
; VSTRL with the highest in-range displacement.
define void @test_vstrl2(<16 x i8> %vec, i8 *%base) {
; CHECK-LABEL: test_vstrl2:
; CHECK: vstrl %v24, 4095(%r2), 8
; CHECK: br %r14
%ptr = getelementptr i8, i8 *%base, i64 4095
call void @llvm.s390.vstrl(<16 x i8> %vec, i32 8, i8 *%ptr)
ret void
}
; VSTRL with an out-of-range displacement.
define void @test_vstrl3(<16 x i8> %vec, i8 *%base) {
; CHECK-LABEL: test_vstrl3:
; CHECK: vstrl %v24, 0({{%r[1-5]}}), 8
; CHECK: br %r14
%ptr = getelementptr i8, i8 *%base, i64 4096
call void @llvm.s390.vstrl(<16 x i8> %vec, i32 8, i8 *%ptr)
ret void
}
; Check that VSTRL doesn't allow an index.
define void @test_vstrl4(<16 x i8> %vec, i8 *%base, i64 %index) {
; CHECK-LABEL: test_vstrl4:
; CHECK: vstrl %v24, 0({{%r[1-5]}}), 8
; CHECK: br %r14
%ptr = getelementptr i8, i8 *%base, i64 %index
call void @llvm.s390.vstrl(<16 x i8> %vec, i32 8, i8 *%ptr)
ret void
}
; VFMAXDB.
define <2 x double> @test_vfmaxdb(<2 x double> %a, <2 x double> %b) {
; CHECK-LABEL: test_vfmaxdb:
; CHECK: vfmaxdb %v24, %v24, %v26, 4
; CHECK: br %r14
%res = call <2 x double> @llvm.s390.vfmaxdb(<2 x double> %a, <2 x double> %b, i32 4)
ret <2 x double> %res
}
; VFMINDB.
define <2 x double> @test_vfmindb(<2 x double> %a, <2 x double> %b) {
; CHECK-LABEL: test_vfmindb:
; CHECK: vfmindb %v24, %v24, %v26, 4
; CHECK: br %r14
%res = call <2 x double> @llvm.s390.vfmindb(<2 x double> %a, <2 x double> %b, i32 4)
ret <2 x double> %res
}

View File

@ -0,0 +1,58 @@
; Test vector maximum on z14.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
declare double @fmax(double, double)
declare double @llvm.maxnum.f64(double, double)
declare <2 x double> @llvm.maxnum.v2f64(<2 x double>, <2 x double>)
; Test the fmax library function.
define double @f1(double %dummy, double %val1, double %val2) {
; CHECK-LABEL: f1:
; CHECK: wfmaxdb %f0, %f2, %f4, 4
; CHECK: br %r14
%ret = call double @fmax(double %val1, double %val2) readnone
ret double %ret
}
; Test the f64 maxnum intrinsic.
define double @f2(double %dummy, double %val1, double %val2) {
; CHECK-LABEL: f2:
; CHECK: wfmaxdb %f0, %f2, %f4, 4
; CHECK: br %r14
%ret = call double @llvm.maxnum.f64(double %val1, double %val2)
ret double %ret
}
; Test a f64 constant compare/select resulting in maxnum.
define double @f3(double %dummy, double %val) {
; CHECK-LABEL: f3:
; CHECK: lzdr [[REG:%f[0-9]+]]
; CHECK: wfmaxdb %f0, %f2, [[REG]], 4
; CHECK: br %r14
%cmp = fcmp ogt double %val, 0.0
%ret = select i1 %cmp, double %val, double 0.0
ret double %ret
}
; Test a f64 constant compare/select resulting in maxnan.
define double @f4(double %dummy, double %val) {
; CHECK-LABEL: f4:
; CHECK: lzdr [[REG:%f[0-9]+]]
; CHECK: wfmaxdb %f0, %f2, [[REG]], 1
; CHECK: br %r14
%cmp = fcmp ugt double %val, 0.0
%ret = select i1 %cmp, double %val, double 0.0
ret double %ret
}
; Test the v2f64 maxnum intrinsic.
define <2 x double> @f5(<2 x double> %dummy, <2 x double> %val1,
<2 x double> %val2) {
; CHECK-LABEL: f5:
; CHECK: vfmaxdb %v24, %v26, %v28, 4
; CHECK: br %r14
%ret = call <2 x double> @llvm.maxnum.v2f64(<2 x double> %val1, <2 x double> %val2)
ret <2 x double> %ret
}

View File

@ -0,0 +1,58 @@
; Test vector minimum on z14.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
declare double @fmin(double, double)
declare double @llvm.minnum.f64(double, double)
declare <2 x double> @llvm.minnum.v2f64(<2 x double>, <2 x double>)
; Test the fmin library function.
define double @f1(double %dummy, double %val1, double %val2) {
; CHECK-LABEL: f1:
; CHECK: wfmindb %f0, %f2, %f4, 4
; CHECK: br %r14
%ret = call double @fmin(double %val1, double %val2) readnone
ret double %ret
}
; Test the f64 minnum intrinsic.
define double @f2(double %dummy, double %val1, double %val2) {
; CHECK-LABEL: f2:
; CHECK: wfmindb %f0, %f2, %f4, 4
; CHECK: br %r14
%ret = call double @llvm.minnum.f64(double %val1, double %val2)
ret double %ret
}
; Test a f64 constant compare/select resulting in minnum.
define double @f3(double %dummy, double %val) {
; CHECK-LABEL: f3:
; CHECK: lzdr [[REG:%f[0-9]+]]
; CHECK: wfmindb %f0, %f2, [[REG]], 4
; CHECK: br %r14
%cmp = fcmp olt double %val, 0.0
%ret = select i1 %cmp, double %val, double 0.0
ret double %ret
}
; Test a f64 constant compare/select resulting in minnan.
define double @f4(double %dummy, double %val) {
; CHECK-LABEL: f4:
; CHECK: lzdr [[REG:%f[0-9]+]]
; CHECK: wfmindb %f0, %f2, [[REG]], 1
; CHECK: br %r14
%cmp = fcmp ult double %val, 0.0
%ret = select i1 %cmp, double %val, double 0.0
ret double %ret
}
; Test the v2f64 minnum intrinsic.
define <2 x double> @f5(<2 x double> %dummy, <2 x double> %val1,
<2 x double> %val2) {
; CHECK-LABEL: f5:
; CHECK: vfmindb %v24, %v26, %v28, 4
; CHECK: br %r14
%ret = call <2 x double> @llvm.minnum.v2f64(<2 x double> %val1, <2 x double> %val2)
ret <2 x double> %ret
}

View File

@ -0,0 +1,24 @@
; Test insertions of memory values into 0 on z14.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
; Test VLLEZLF.
define <4 x i32> @f1(i32 *%ptr) {
; CHECK-LABEL: f1:
; CHECK: vllezlf %v24, 0(%r2)
; CHECK: br %r14
%val = load i32, i32 *%ptr
%ret = insertelement <4 x i32> zeroinitializer, i32 %val, i32 0
ret <4 x i32> %ret
}
; Test VLLEZLF with a float.
define <4 x float> @f2(float *%ptr) {
; CHECK-LABEL: f2:
; CHECK: vllezlf %v24, 0(%r2)
; CHECK: br %r14
%val = load float, float *%ptr
%ret = insertelement <4 x float> zeroinitializer, float %val, i32 0
ret <4 x float> %ret
}

View File

@ -0,0 +1,32 @@
; Test vector negative multiply-and-add on z14.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
declare <2 x double> @llvm.fma.v2f64(<2 x double>, <2 x double>, <2 x double>)
; Test a v2f64 negative multiply-and-add.
define <2 x double> @f1(<2 x double> %dummy, <2 x double> %val1,
<2 x double> %val2, <2 x double> %val3) {
; CHECK-LABEL: f1:
; CHECK: vfnmadb %v24, %v26, %v28, %v30
; CHECK: br %r14
%ret = call <2 x double> @llvm.fma.v2f64 (<2 x double> %val1,
<2 x double> %val2,
<2 x double> %val3)
%negret = fsub <2 x double> <double -0.0, double -0.0>, %ret
ret <2 x double> %negret
}
; Test a v2f64 negative multiply-and-subtract.
define <2 x double> @f2(<2 x double> %dummy, <2 x double> %val1,
<2 x double> %val2, <2 x double> %val3) {
; CHECK-LABEL: f2:
; CHECK: vfnmsdb %v24, %v26, %v28, %v30
; CHECK: br %r14
%negval3 = fsub <2 x double> <double -0.0, double -0.0>, %val3
%ret = call <2 x double> @llvm.fma.v2f64 (<2 x double> %val1,
<2 x double> %val2,
<2 x double> %negval3)
%negret = fsub <2 x double> <double -0.0, double -0.0>, %ret
ret <2 x double> %negret
}

View File

@ -0,0 +1,91 @@
; Test vector OR-NOT on z14.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
; Test a v16i8 OR-NOT.
define <16 x i8> @f1(<16 x i8> %dummy, <16 x i8> %val1, <16 x i8> %val2) {
; CHECK-LABEL: f1:
; CHECK: voc %v24, %v26, %v28
; CHECK: br %r14
%not = xor <16 x i8> %val2, <i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1>
%ret = or <16 x i8> %val1, %not
ret <16 x i8> %ret
}
; ...and again with the reverse.
define <16 x i8> @f2(<16 x i8> %dummy, <16 x i8> %val1, <16 x i8> %val2) {
; CHECK-LABEL: f2:
; CHECK: voc %v24, %v28, %v26
; CHECK: br %r14
%not = xor <16 x i8> %val1, <i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1>
%ret = or <16 x i8> %not, %val2
ret <16 x i8> %ret
}
; Test a v8i16 OR-NOT.
define <8 x i16> @f3(<8 x i16> %dummy, <8 x i16> %val1, <8 x i16> %val2) {
; CHECK-LABEL: f3:
; CHECK: voc %v24, %v26, %v28
; CHECK: br %r14
%not = xor <8 x i16> %val2, <i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1>
%ret = or <8 x i16> %val1, %not
ret <8 x i16> %ret
}
; ...and again with the reverse.
define <8 x i16> @f4(<8 x i16> %dummy, <8 x i16> %val1, <8 x i16> %val2) {
; CHECK-LABEL: f4:
; CHECK: voc %v24, %v28, %v26
; CHECK: br %r14
%not = xor <8 x i16> %val1, <i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1>
%ret = or <8 x i16> %not, %val2
ret <8 x i16> %ret
}
; Test a v4i32 OR-NOT.
define <4 x i32> @f5(<4 x i32> %dummy, <4 x i32> %val1, <4 x i32> %val2) {
; CHECK-LABEL: f5:
; CHECK: voc %v24, %v26, %v28
; CHECK: br %r14
%not = xor <4 x i32> %val2, <i32 -1, i32 -1, i32 -1, i32 -1>
%ret = or <4 x i32> %val1, %not
ret <4 x i32> %ret
}
; ...and again with the reverse.
define <4 x i32> @f6(<4 x i32> %dummy, <4 x i32> %val1, <4 x i32> %val2) {
; CHECK-LABEL: f6:
; CHECK: voc %v24, %v28, %v26
; CHECK: br %r14
%not = xor <4 x i32> %val1, <i32 -1, i32 -1, i32 -1, i32 -1>
%ret = or <4 x i32> %not, %val2
ret <4 x i32> %ret
}
; Test a v2i64 OR-NOT.
define <2 x i64> @f7(<2 x i64> %dummy, <2 x i64> %val1, <2 x i64> %val2) {
; CHECK-LABEL: f7:
; CHECK: voc %v24, %v26, %v28
; CHECK: br %r14
%not = xor <2 x i64> %val2, <i64 -1, i64 -1>
%ret = or <2 x i64> %val1, %not
ret <2 x i64> %ret
}
; ...and again with the reverse.
define <2 x i64> @f8(<2 x i64> %dummy, <2 x i64> %val1, <2 x i64> %val2) {
; CHECK-LABEL: f8:
; CHECK: voc %v24, %v28, %v26
; CHECK: br %r14
%not = xor <2 x i64> %val1, <i64 -1, i64 -1>
%ret = or <2 x i64> %not, %val2
ret <2 x i64> %ret
}

View File

@ -0,0 +1,47 @@
; Test vector NOT-XOR on z14.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
; Test a v16i8 NOT-XOR.
define <16 x i8> @f1(<16 x i8> %dummy, <16 x i8> %val1, <16 x i8> %val2) {
; CHECK-LABEL: f1:
; CHECK: vnx %v24, %v26, %v28
; CHECK: br %r14
%ret = xor <16 x i8> %val1, %val2
%not = xor <16 x i8> %ret, <i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1>
ret <16 x i8> %not
}
; Test a v8i16 NOT-XOR.
define <8 x i16> @f2(<8 x i16> %dummy, <8 x i16> %val1, <8 x i16> %val2) {
; CHECK-LABEL: f2:
; CHECK: vnx %v24, %v26, %v28
; CHECK: br %r14
%ret = xor <8 x i16> %val1, %val2
%not = xor <8 x i16> %ret, <i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1>
ret <8 x i16> %not
}
; Test a v4i32 NOT-XOR.
define <4 x i32> @f3(<4 x i32> %dummy, <4 x i32> %val1, <4 x i32> %val2) {
; CHECK-LABEL: f3:
; CHECK: vnx %v24, %v26, %v28
; CHECK: br %r14
%ret = xor <4 x i32> %val1, %val2
%not = xor <4 x i32> %ret, <i32 -1, i32 -1, i32 -1, i32 -1>
ret <4 x i32> %not
}
; Test a v2i64 NOT-XOR.
define <2 x i64> @f4(<2 x i64> %dummy, <2 x i64> %val1, <2 x i64> %val2) {
; CHECK-LABEL: f4:
; CHECK: vnx %v24, %v26, %v28
; CHECK: br %r14
%ret = xor <2 x i64> %val1, %val2
%not = xor <2 x i64> %ret, <i64 -1, i64 -1>
ret <2 x i64> %not
}

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,19 @@
# RUN: not llvm-mc -triple s390x-linux-gnu -mcpu=arch11 < %s 2> %t
# RUN: FileCheck < %t %s
#CHECK: error: instruction requires: miscellaneous-extensions-2
#CHECK: agh %r0, 0
agh %r0, 0
#CHECK: error: instruction requires: miscellaneous-extensions-2
#CHECK: bi 0
#CHECK: error: instruction requires: miscellaneous-extensions-2
#CHECK: bic 0, 0
bi 0
bic 0, 0
#CHECK: error: invalid operand
#CHECK: cdpt %f0, 0(1), -1
#CHECK: error: invalid operand
@ -150,6 +163,16 @@
cxpt %f0, 0(-), 0
cxpt %f15, 0(1), 0
#CHECK: error: instruction requires: insert-reference-bits-multiple
#CHECK: irbm %r0, %r0
irbm %r0, %r0
#CHECK: error: instruction requires: message-security-assist-extension8
#CHECK: kma %r2, %r4, %r6
kma %r2, %r4, %r6
#CHECK: error: invalid operand
#CHECK: lcbb %r0, 0, -1
#CHECK: error: invalid operand
@ -167,6 +190,21 @@
lcbb %r0, 4096, 0
lcbb %r0, 0(%v1,%r2), 0
#CHECK: error: instruction requires: guarded-storage
#CHECK: lgg %r0, 0
lgg %r0, 0
#CHECK: error: instruction requires: guarded-storage
#CHECK: lgsc %r0, 0
lgsc %r0, 0
#CHECK: error: instruction requires: guarded-storage
#CHECK: llgfsg %r0, 0
llgfsg %r0, 0
#CHECK: error: invalid operand
#CHECK: llzrgf %r0, -524289
#CHECK: error: invalid operand
@ -249,6 +287,41 @@
lzrg %r0, -524289
lzrg %r0, 524288
#CHECK: error: instruction requires: miscellaneous-extensions-2
#CHECK: mg %r0, 0
mg %r0, 0
#CHECK: error: instruction requires: miscellaneous-extensions-2
#CHECK: mgh %r0, 0
mgh %r0, 0
#CHECK: error: instruction requires: miscellaneous-extensions-2
#CHECK: mgrk %r0, %r0, %r0
mgrk %r0, %r0, %r0
#CHECK: error: instruction requires: miscellaneous-extensions-2
#CHECK: msc %r0, 0
msc %r0, 0
#CHECK: error: instruction requires: miscellaneous-extensions-2
#CHECK: msgc %r0, 0
msgc %r0, 0
#CHECK: error: instruction requires: miscellaneous-extensions-2
#CHECK: msrkc %r0, %r0, %r0
msrkc %r0, %r0, %r0
#CHECK: error: instruction requires: miscellaneous-extensions-2
#CHECK: msgrkc %r0, %r0, %r0
msgrkc %r0, %r0, %r0
#CHECK: error: invalid register pair
#CHECK: ppno %r1, %r2
#CHECK: error: invalid register pair
@ -257,6 +330,21 @@
ppno %r1, %r2
ppno %r2, %r1
#CHECK: error: instruction requires: message-security-assist-extension7
#CHECK: prno %r2, %r4
prno %r2, %r4
#CHECK: error: instruction requires: miscellaneous-extensions-2
#CHECK: sgh %r0, 0
sgh %r0, 0
#CHECK: error: instruction requires: guarded-storage
#CHECK: stgsc %r0, 0
stgsc %r0, 0
#CHECK: error: invalid operand
#CHECK: stocfh %r0, 0, -1
#CHECK: error: invalid operand
@ -274,6 +362,16 @@
stocfh %r0, 524288, 1
stocfh %r0, 0(%r1,%r2), 1
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vap %v0, %v0, %v0, 0, 0
vap %v0, %v0, %v0, 0, 0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vbperm %v0, %v0, %v0
vbperm %v0, %v0, %v0
#CHECK: error: invalid operand
#CHECK: vcdg %v0, %v0, 0, 0, -1
#CHECK: error: invalid operand
@ -410,6 +508,35 @@
vclgdb %v0, %v0, -1, 0
vclgdb %v0, %v0, 16, 0
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vcp %v0, %v0, 0
vcp %v0, %v0, 0
#CHECK: vcvb %r0, %v0, 0
vcvb %r0, %v0, 0
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vcvbg %r0, %v0, 0
vcvbg %r0, %v0, 0
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vcvd %v0, %r0, 0, 0
vcvd %v0, %r0, 0, 0
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vcvdg %v0, %r0, 0, 0
vcvdg %v0, %r0, 0, 0
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vdp %v0, %v0, %v0, 0, 0
vdp %v0, %v0, %v0, 0, 0
#CHECK: error: invalid operand
#CHECK: verim %v0, %v0, %v0, 0, -1
#CHECK: error: invalid operand
@ -1130,6 +1257,62 @@
vfidb %v0, %v0, -1, 0
vfidb %v0, %v0, 16, 0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vfkedb %v0, %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vfkedbs %v0, %v0, %v0
vfkedb %v0, %v0, %v0
vfkedbs %v0, %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vfkhdb %v0, %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vfkhdbs %v0, %v0, %v0
vfkhdb %v0, %v0, %v0
vfkhdbs %v0, %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vfkhedb %v0, %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vfkhedbs %v0, %v0, %v0
vfkhedb %v0, %v0, %v0
vfkhedbs %v0, %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vfmax %v0, %v0, %v0, 0, 0, 0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vfmaxdb %v0, %v0, %v0, 0
vfmax %v0, %v0, %v0, 0, 0, 0
vfmaxdb %v0, %v0, %v0, 0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vfmin %v0, %v0, %v0, 0, 0, 0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vfmindb %v0, %v0, %v0, 0
vfmin %v0, %v0, %v0, 0, 0, 0
vfmindb %v0, %v0, %v0, 0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vfnma %v0, %v0, %v0, %v0, 0, 0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vfnmadb %v0, %v0, %v0, %v0
vfnma %v0, %v0, %v0, %v0, 0, 0
vfnmadb %v0, %v0, %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vfnms %v0, %v0, %v0, %v0, 0, 0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vfnmsdb %v0, %v0, %v0, %v0
vfnms %v0, %v0, %v0, %v0, 0, 0
vfnmsdb %v0, %v0, %v0, %v0
#CHECK: error: invalid operand
#CHECK: vftci %v0, %v0, 0, 0, -1
#CHECK: error: invalid operand
@ -1615,6 +1798,11 @@
vlgvh %r0, %v0, 4096
vlgvh %r0, %v0, 0(%r0)
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vlip %v0, 0, 0
vlip %v0, 0, 0
#CHECK: error: invalid operand
#CHECK: vll %v0, %r0, -1
#CHECK: error: invalid operand
@ -1687,6 +1875,11 @@
vllezh %v0, 4096
vllezh %v0, 0(%v1,%r2)
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vllezlf %v0, 0
vllezlf %v0, 0
#CHECK: error: invalid operand
#CHECK: vlm %v0, %v0, -1
#CHECK: error: invalid operand
@ -1756,6 +1949,16 @@
vlreph %v0, 4096
vlreph %v0, 0(%v1,%r2)
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vlrl %v0, 0, 0
vlrl %v0, 0, 0
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vlrlr %v0, %r0, 0
vlrlr %v0, %r0, 0
#CHECK: error: invalid operand
#CHECK: vlvg %v0, %r0, 0, -1
#CHECK: error: invalid operand
@ -1817,6 +2020,39 @@
vlvgh %v0, %r0, 4096
vlvgh %v0, %r0, 0(%r0)
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vmp %v0, %v0, %v0, 0, 0
vmp %v0, %v0, %v0, 0, 0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vmsl %v0, %v0, %v0, %v0, 0, 0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vmslg %v0, %v0, %v0, %v0, 0
vmsl %v0, %v0, %v0, %v0, 0, 0
vmslg %v0, %v0, %v0, %v0, 0
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vmsp %v0, %v0, %v0, 0, 0
vmsp %v0, %v0, %v0, 0, 0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vnn %v0, %v0, %v0
vnn %v0, %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vnx %v0, %v0, %v0
vnx %v0, %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: voc %v0, %v0, %v0
voc %v0, %v0, %v0
#CHECK: error: invalid operand
#CHECK: vpdi %v0, %v0, %v0, -1
#CHECK: error: invalid operand
@ -1825,6 +2061,30 @@
vpdi %v0, %v0, %v0, -1
vpdi %v0, %v0, %v0, 16
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vpkz %v0, 0, 0
vpkz %v0, 0, 0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vpopctb %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vpopctf %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vpopctg %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: vpopcth %v0, %v0
vpopctb %v0, %v0
vpopctf %v0, %v0
vpopctg %v0, %v0
vpopcth %v0, %v0
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vpsop %v0, %v0, 0, 0, 0
vpsop %v0, %v0, 0, 0, 0
#CHECK: error: invalid operand
#CHECK: vrep %v0, %v0, 0, -1
#CHECK: error: invalid operand
@ -1917,6 +2177,11 @@
vrepih %v0, -32769
vrepih %v0, 32768
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vrp %v0, %v0, %v0, 0, 0
vrp %v0, %v0, %v0, 0, 0
#CHECK: error: vector index required
#CHECK: vscef %v0, 0(%r1), 0
#CHECK: error: vector index required
@ -1957,6 +2222,11 @@
vsceg %v0, -1(%v0,%r1), 0
vsceg %v0, 4096(%v0,%r1), 0
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vsdp %v0, %v0, %v0, 0, 0
vsdp %v0, %v0, %v0, 0, 0
#CHECK: error: invalid operand
#CHECK: vsldb %v0, %v0, %v0, -1
#CHECK: error: invalid operand
@ -1965,6 +2235,16 @@
vsldb %v0, %v0, %v0, -1
vsldb %v0, %v0, %v0, 256
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vsp %v0, %v0, %v0, 0, 0
vsp %v0, %v0, %v0, 0, 0
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vsrp %v0, %v0, 0, 0, 0
vsrp %v0, %v0, 0, 0, 0
#CHECK: error: invalid operand
#CHECK: vst %v0, -1
#CHECK: error: invalid operand
@ -2251,6 +2531,26 @@
vstrczhs %v0, %v0, %v0
vstrczhs %v0, %v0, %v0, %v0, 0, 0
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vstrl %v0, 0, 0
vstrl %v0, 0, 0
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vstrlr %v0, %r0, 0
vstrlr %v0, %r0, 0
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vtp %v0
vtp %v0
#CHECK: error: instruction requires: vector-packed-decimal
#CHECK: vupkz %v0, 0, 0
vupkz %v0, 0, 0
#CHECK: error: invalid operand
#CHECK: wcdgb %v0, %v0, 0, -1
#CHECK: error: invalid operand
@ -2321,6 +2621,50 @@
wfidb %v0, %v0, -1, 0
wfidb %v0, %v0, 16, 0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: wfkedb %v0, %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: wfkedbs %v0, %v0, %v0
wfkedb %v0, %v0, %v0
wfkedbs %v0, %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: wfkhdb %v0, %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: wfkhdbs %v0, %v0, %v0
wfkhdb %v0, %v0, %v0
wfkhdbs %v0, %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: wfkhedb %v0, %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: wfkhedbs %v0, %v0, %v0
wfkhedb %v0, %v0, %v0
wfkhedbs %v0, %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: wfmaxdb %v0, %v0, %v0, 0
wfmaxdb %v0, %v0, %v0, 0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: wfmindb %v0, %v0, %v0, 0
wfmindb %v0, %v0, %v0, 0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: wfnmadb %v0, %v0, %v0, %v0
wfnmadb %v0, %v0, %v0, %v0
#CHECK: error: instruction requires: vector-enhancements-1
#CHECK: wfnmsdb %v0, %v0, %v0, %v0
wfnmsdb %v0, %v0, %v0, %v0
#CHECK: error: invalid operand
#CHECK: wftcidb %v0, %v0, -1
#CHECK: error: invalid operand

View File

@ -0,0 +1,562 @@
# For z14 only.
# RUN: not llvm-mc -triple s390x-linux-gnu -mcpu=z14 < %s 2> %t
# RUN: FileCheck < %t %s
# RUN: not llvm-mc -triple s390x-linux-gnu -mcpu=arch12 < %s 2> %t
# RUN: FileCheck < %t %s
#CHECK: error: invalid operand
#CHECK: bi -524289
#CHECK: error: invalid operand
#CHECK: bi 524288
bi -524289
bi 524288
#CHECK: error: invalid operand
#CHECK: bic -1, 0(%r1)
#CHECK: error: invalid operand
#CHECK: bic 16, 0(%r1)
#CHECK: error: invalid operand
#CHECK: bic 0, -524289
#CHECK: error: invalid operand
#CHECK: bic 0, 524288
bic -1, 0(%r1)
bic 16, 0(%r1)
bic 0, -524289
bic 0, 524288
#CHECK: error: invalid operand
#CHECK: agh %r0, -524289
#CHECK: error: invalid operand
#CHECK: agh %r0, 524288
agh %r0, -524289
agh %r0, 524288
#CHECK: error: invalid register pair
#CHECK: kma %r1, %r2, %r4
#CHECK: error: invalid register pair
#CHECK: kma %r2, %r1, %r4
#CHECK: error: invalid register pair
#CHECK: kma %r2, %r4, %r1
kma %r1, %r2, %r4
kma %r2, %r1, %r4
kma %r2, %r4, %r1
#CHECK: error: invalid operand
#CHECK: lgg %r0, -524289
#CHECK: error: invalid operand
#CHECK: lgg %r0, 524288
lgg %r0, -524289
lgg %r0, 524288
#CHECK: error: invalid operand
#CHECK: lgsc %r0, -524289
#CHECK: error: invalid operand
#CHECK: lgsc %r0, 524288
lgsc %r0, -524289
lgsc %r0, 524288
#CHECK: error: invalid operand
#CHECK: llgfsg %r0, -524289
#CHECK: error: invalid operand
#CHECK: llgfsg %r0, 524288
llgfsg %r0, -524289
llgfsg %r0, 524288
#CHECK: error: invalid operand
#CHECK: mg %r0, -524289
#CHECK: error: invalid operand
#CHECK: mg %r0, 524288
#CHECK: error: invalid register pair
#CHECK: mg %r1, 0
mg %r0, -524289
mg %r0, 524288
mg %r1, 0
#CHECK: error: invalid operand
#CHECK: mgh %r0, -524289
#CHECK: error: invalid operand
#CHECK: mgh %r0, 524288
mgh %r0, -524289
mgh %r0, 524288
#CHECK: error: invalid register pair
#CHECK: mgrk %r1, %r0, %r0
mgrk %r1, %r0, %r0
#CHECK: error: invalid operand
#CHECK: msc %r0, -524289
#CHECK: error: invalid operand
#CHECK: msc %r0, 524288
msc %r0, -524289
msc %r0, 524288
#CHECK: error: invalid operand
#CHECK: msgc %r0, -524289
#CHECK: error: invalid operand
#CHECK: msgc %r0, 524288
msgc %r0, -524289
msgc %r0, 524288
#CHECK: error: invalid register pair
#CHECK: prno %r1, %r2
#CHECK: error: invalid register pair
#CHECK: prno %r2, %r1
prno %r1, %r2
prno %r2, %r1
#CHECK: error: invalid operand
#CHECK: sgh %r0, -524289
#CHECK: error: invalid operand
#CHECK: sgh %r0, 524288
sgh %r0, -524289
sgh %r0, 524288
#CHECK: error: invalid operand
#CHECK: stgsc %r0, -524289
#CHECK: error: invalid operand
#CHECK: stgsc %r0, 524288
stgsc %r0, -524289
stgsc %r0, 524288
#CHECK: error: invalid operand
#CHECK: vap %v0, %v0, %v0, 0, -1
#CHECK: error: invalid operand
#CHECK: vap %v0, %v0, %v0, 0, 16
#CHECK: error: invalid operand
#CHECK: vap %v0, %v0, %v0, -1, 0
#CHECK: error: invalid operand
#CHECK: vap %v0, %v0, %v0, 256, 0
vap %v0, %v0, %v0, 0, -1
vap %v0, %v0, %v0, 0, 16
vap %v0, %v0, %v0, -1, 0
vap %v0, %v0, %v0, 256, 0
#CHECK: error: invalid operand
#CHECK: vcp %v0, %v0, -1
#CHECK: error: invalid operand
#CHECK: vcp %v0, %v0, 16
vcp %v0, %v0, -1
vcp %v0, %v0, 16
#CHECK: error: invalid operand
#CHECK: vcvb %r0, %v0, -1
#CHECK: error: invalid operand
#CHECK: vcvb %r0, %v0, 16
vcvb %r0, %v0, -1
vcvb %r0, %v0, 16
#CHECK: error: invalid operand
#CHECK: vcvbg %r0, %v0, -1
#CHECK: error: invalid operand
#CHECK: vcvbg %r0, %v0, 16
vcvbg %r0, %v0, -1
vcvbg %r0, %v0, 16
#CHECK: error: invalid operand
#CHECK: vcvd %r0, %v0, 0, -1
#CHECK: error: invalid operand
#CHECK: vcvd %r0, %v0, 0, 16
#CHECK: error: invalid operand
#CHECK: vcvd %r0, %v0, -1, 0
#CHECK: error: invalid operand
#CHECK: vcvd %r0, %v0, 256, 0
vcvd %r0, %v0, 0, -1
vcvd %r0, %v0, 0, 16
vcvd %r0, %v0, -1, 0
vcvd %r0, %v0, 256, 0
#CHECK: error: invalid operand
#CHECK: vcvdg %r0, %v0, 0, -1
#CHECK: error: invalid operand
#CHECK: vcvdg %r0, %v0, 0, 16
#CHECK: error: invalid operand
#CHECK: vcvdg %r0, %v0, -1, 0
#CHECK: error: invalid operand
#CHECK: vcvdg %r0, %v0, 256, 0
vcvdg %r0, %v0, 0, -1
vcvdg %r0, %v0, 0, 16
vcvdg %r0, %v0, -1, 0
vcvdg %r0, %v0, 256, 0
#CHECK: error: invalid operand
#CHECK: vdp %v0, %v0, %v0, 0, -1
#CHECK: error: invalid operand
#CHECK: vdp %v0, %v0, %v0, 0, 16
#CHECK: error: invalid operand
#CHECK: vdp %v0, %v0, %v0, -1, 0
#CHECK: error: invalid operand
#CHECK: vdp %v0, %v0, %v0, 256, 0
vdp %v0, %v0, %v0, 0, -1
vdp %v0, %v0, %v0, 0, 16
vdp %v0, %v0, %v0, -1, 0
vdp %v0, %v0, %v0, 256, 0
#CHECK: error: invalid operand
#CHECK: vfmax %v0, %v0, %v0, 0, 0, -1
#CHECK: error: invalid operand
#CHECK: vfmax %v0, %v0, %v0, 0, 0, 16
#CHECK: error: invalid operand
#CHECK: vfmax %v0, %v0, %v0, 0, -1, 0
#CHECK: error: invalid operand
#CHECK: vfmax %v0, %v0, %v0, 0, 16, 0
#CHECK: error: invalid operand
#CHECK: vfmax %v0, %v0, %v0, -1, 0, 0
#CHECK: error: invalid operand
#CHECK: vfmax %v0, %v0, %v0, 16, 0, 0
vfmax %v0, %v0, %v0, 0, 0, -1
vfmax %v0, %v0, %v0, 0, 0, 16
vfmax %v0, %v0, %v0, 0, -1, 0
vfmax %v0, %v0, %v0, 0, 16, 0
vfmax %v0, %v0, %v0, -1, 0, 0
vfmax %v0, %v0, %v0, 16, 0, 0
#CHECK: error: invalid operand
#CHECK: vfmaxdb %v0, %v0, %v0, -1
#CHECK: error: invalid operand
#CHECK: vfmaxdb %v0, %v0, %v0, 16
vfmaxdb %v0, %v0, %v0, -1
vfmaxdb %v0, %v0, %v0, 16
#CHECK: error: invalid operand
#CHECK: vfmin %v0, %v0, %v0, 0, 0, -1
#CHECK: error: invalid operand
#CHECK: vfmin %v0, %v0, %v0, 0, 0, 16
#CHECK: error: invalid operand
#CHECK: vfmin %v0, %v0, %v0, 0, -1, 0
#CHECK: error: invalid operand
#CHECK: vfmin %v0, %v0, %v0, 0, 16, 0
#CHECK: error: invalid operand
#CHECK: vfmin %v0, %v0, %v0, -1, 0, 0
#CHECK: error: invalid operand
#CHECK: vfmin %v0, %v0, %v0, 16, 0, 0
vfmin %v0, %v0, %v0, 0, 0, -1
vfmin %v0, %v0, %v0, 0, 0, 16
vfmin %v0, %v0, %v0, 0, -1, 0
vfmin %v0, %v0, %v0, 0, 16, 0
vfmin %v0, %v0, %v0, -1, 0, 0
vfmin %v0, %v0, %v0, 16, 0, 0
#CHECK: error: invalid operand
#CHECK: vfmindb %v0, %v0, %v0, -1
#CHECK: error: invalid operand
#CHECK: vfmindb %v0, %v0, %v0, 16
vfmindb %v0, %v0, %v0, -1
vfmindb %v0, %v0, %v0, 16
#CHECK: error: invalid operand
#CHECK: vfnma %v0, %v0, %v0, %v0, 0, -1
#CHECK: error: invalid operand
#CHECK: vfnma %v0, %v0, %v0, %v0, 0, 16
#CHECK: error: invalid operand
#CHECK: vfnma %v0, %v0, %v0, %v0, -1, 0
#CHECK: error: invalid operand
#CHECK: vfnma %v0, %v0, %v0, %v0, 16, 0
vfnma %v0, %v0, %v0, %v0, 0, -1
vfnma %v0, %v0, %v0, %v0, 0, 16
vfnma %v0, %v0, %v0, %v0, -1, 0
vfnma %v0, %v0, %v0, %v0, 16, 0
#CHECK: error: invalid operand
#CHECK: vfnms %v0, %v0, %v0, %v0, 0, -1
#CHECK: error: invalid operand
#CHECK: vfnms %v0, %v0, %v0, %v0, 0, 16
#CHECK: error: invalid operand
#CHECK: vfnms %v0, %v0, %v0, %v0, -1, 0
#CHECK: error: invalid operand
#CHECK: vfnms %v0, %v0, %v0, %v0, 16, 0
vfnms %v0, %v0, %v0, %v0, 0, -1
vfnms %v0, %v0, %v0, %v0, 0, 16
vfnms %v0, %v0, %v0, %v0, -1, 0
vfnms %v0, %v0, %v0, %v0, 16, 0
#CHECK: error: invalid operand
#CHECK: vlip %v0, 0, -1
#CHECK: error: invalid operand
#CHECK: vlip %v0, 0, 16
#CHECK: error: invalid operand
#CHECK: vlip %v0, -1, 0
#CHECK: error: invalid operand
#CHECK: vlip %v0, 65536, 0
vlip %v0, 0, -1
vlip %v0, 0, 16
vlip %v0, -1, 0
vlip %v0, 65536, 0
#CHECK: error: invalid operand
#CHECK: vllezlf %v0, -1
#CHECK: error: invalid operand
#CHECK: vllezlf %v0, 4096
#CHECK: error: invalid use of vector addressing
#CHECK: vllezlf %v0, 0(%v1,%r2)
vllezlf %v0, -1
vllezlf %v0, 4096
vllezlf %v0, 0(%v1,%r2)
#CHECK: error: invalid operand
#CHECK: vlrl %v0, 0, -1
#CHECK: error: invalid operand
#CHECK: vlrl %v0, 0, 256
#CHECK: error: invalid operand
#CHECK: vlrl %v0, -1, 0
#CHECK: error: invalid operand
#CHECK: vlrl %v0, 4096, 0
#CHECK: error: %r0 used in an address
#CHECK: vlrl %v0, 0(%r0), 0
vlrl %v0, 0, -1
vlrl %v0, 0, 256
vlrl %v0, -1, 0
vlrl %v0, 4096, 0
vlrl %v0, 0(%r0), 0
#CHECK: error: invalid operand
#CHECK: vlrlr %v0, %r0, -1
#CHECK: error: invalid operand
#CHECK: vlrlr %v0, %r0, 4096
#CHECK: error: %r0 used in an address
#CHECK: vlrlr %v0, %r0, 0(%r0)
vlrlr %v0, %r0, -1
vlrlr %v0, %r0, 4096
vlrlr %v0, %r0, 0(%r0)
#CHECK: error: invalid operand
#CHECK: vmp %v0, %v0, %v0, 0, -1
#CHECK: error: invalid operand
#CHECK: vmp %v0, %v0, %v0, 0, 16
#CHECK: error: invalid operand
#CHECK: vmp %v0, %v0, %v0, -1, 0
#CHECK: error: invalid operand
#CHECK: vmp %v0, %v0, %v0, 256, 0
vmp %v0, %v0, %v0, 0, -1
vmp %v0, %v0, %v0, 0, 16
vmp %v0, %v0, %v0, -1, 0
vmp %v0, %v0, %v0, 256, 0
#CHECK: error: invalid operand
#CHECK: vmsp %v0, %v0, %v0, 0, -1
#CHECK: error: invalid operand
#CHECK: vmsp %v0, %v0, %v0, 0, 16
#CHECK: error: invalid operand
#CHECK: vmsp %v0, %v0, %v0, -1, 0
#CHECK: error: invalid operand
#CHECK: vmsp %v0, %v0, %v0, 256, 0
vmsp %v0, %v0, %v0, 0, -1
vmsp %v0, %v0, %v0, 0, 16
vmsp %v0, %v0, %v0, -1, 0
vmsp %v0, %v0, %v0, 256, 0
#CHECK: error: invalid operand
#CHECK: vmsl %v0, %v0, %v0, %v0, 0, -1
#CHECK: error: invalid operand
#CHECK: vmsl %v0, %v0, %v0, %v0, 0, 16
#CHECK: error: invalid operand
#CHECK: vmsl %v0, %v0, %v0, %v0, -1, 0
#CHECK: error: invalid operand
#CHECK: vmsl %v0, %v0, %v0, %v0, 16, 0
vmsl %v0, %v0, %v0, %v0, 0, -1
vmsl %v0, %v0, %v0, %v0, 0, 16
vmsl %v0, %v0, %v0, %v0, -1, 0
vmsl %v0, %v0, %v0, %v0, 16, 0
#CHECK: error: invalid operand
#CHECK: vmslg %v0, %v0, %v0, %v0, -1
#CHECK: error: invalid operand
#CHECK: vmslg %v0, %v0, %v0, %v0, 16
vmslg %v0, %v0, %v0, %v0, -1
vmslg %v0, %v0, %v0, %v0, 16
#CHECK: error: invalid operand
#CHECK: vpkz %v0, 0, -1
#CHECK: error: invalid operand
#CHECK: vpkz %v0, 0, 256
#CHECK: error: invalid operand
#CHECK: vpkz %v0, -1, 0
#CHECK: error: invalid operand
#CHECK: vpkz %v0, 4096, 0
#CHECK: error: %r0 used in an address
#CHECK: vpkz %v0, 0(%r0), 0
vpkz %v0, 0, -1
vpkz %v0, 0, 256
vpkz %v0, -1, 0
vpkz %v0, 4096, 0
vpkz %v0, 0(%r0), 0
#CHECK: error: invalid operand
#CHECK: vpsop %v0, %v0, 0, 0, -1
#CHECK: error: invalid operand
#CHECK: vpsop %v0, %v0, 0, 0, 16
#CHECK: error: invalid operand
#CHECK: vpsop %v0, %v0, 0, -1, 0
#CHECK: error: invalid operand
#CHECK: vpsop %v0, %v0, 0, 256, 0
#CHECK: error: invalid operand
#CHECK: vpsop %v0, %v0, -1, 0, 0
#CHECK: error: invalid operand
#CHECK: vpsop %v0, %v0, 256, 0, 0
vpsop %v0, %v0, 0, 0, -1
vpsop %v0, %v0, 0, 0, 16
vpsop %v0, %v0, 0, -1, 0
vpsop %v0, %v0, 0, 256, 0
vpsop %v0, %v0, -1, 0, 0
vpsop %v0, %v0, 256, 0, 0
#CHECK: error: invalid operand
#CHECK: vrp %v0, %v0, %v0, 0, -1
#CHECK: error: invalid operand
#CHECK: vrp %v0, %v0, %v0, 0, 16
#CHECK: error: invalid operand
#CHECK: vrp %v0, %v0, %v0, -1, 0
#CHECK: error: invalid operand
#CHECK: vrp %v0, %v0, %v0, 256, 0
vrp %v0, %v0, %v0, 0, -1
vrp %v0, %v0, %v0, 0, 16
vrp %v0, %v0, %v0, -1, 0
vrp %v0, %v0, %v0, 256, 0
#CHECK: error: invalid operand
#CHECK: vsdp %v0, %v0, %v0, 0, -1
#CHECK: error: invalid operand
#CHECK: vsdp %v0, %v0, %v0, 0, 16
#CHECK: error: invalid operand
#CHECK: vsdp %v0, %v0, %v0, -1, 0
#CHECK: error: invalid operand
#CHECK: vsdp %v0, %v0, %v0, 256, 0
vsdp %v0, %v0, %v0, 0, -1
vsdp %v0, %v0, %v0, 0, 16
vsdp %v0, %v0, %v0, -1, 0
vsdp %v0, %v0, %v0, 256, 0
#CHECK: error: invalid operand
#CHECK: vsp %v0, %v0, %v0, 0, -1
#CHECK: error: invalid operand
#CHECK: vsp %v0, %v0, %v0, 0, 16
#CHECK: error: invalid operand
#CHECK: vsp %v0, %v0, %v0, -1, 0
#CHECK: error: invalid operand
#CHECK: vsp %v0, %v0, %v0, 256, 0
vsp %v0, %v0, %v0, 0, -1
vsp %v0, %v0, %v0, 0, 16
vsp %v0, %v0, %v0, -1, 0
vsp %v0, %v0, %v0, 256, 0
#CHECK: error: invalid operand
#CHECK: vsrp %v0, %v0, 0, 0, -1
#CHECK: error: invalid operand
#CHECK: vsrp %v0, %v0, 0, 0, 16
#CHECK: error: invalid operand
#CHECK: vsrp %v0, %v0, 0, -1, 0
#CHECK: error: invalid operand
#CHECK: vsrp %v0, %v0, 0, 256, 0
#CHECK: error: invalid operand
#CHECK: vsrp %v0, %v0, -1, 0, 0
#CHECK: error: invalid operand
#CHECK: vsrp %v0, %v0, 256, 0, 0
vsrp %v0, %v0, 0, 0, -1
vsrp %v0, %v0, 0, 0, 16
vsrp %v0, %v0, 0, -1, 0
vsrp %v0, %v0, 0, 256, 0
vsrp %v0, %v0, -1, 0, 0
vsrp %v0, %v0, 256, 0, 0
#CHECK: error: invalid operand
#CHECK: vstrl %v0, 0, -1
#CHECK: error: invalid operand
#CHECK: vstrl %v0, 0, 256
#CHECK: error: invalid operand
#CHECK: vstrl %v0, -1, 0
#CHECK: error: invalid operand
#CHECK: vstrl %v0, 4096, 0
#CHECK: error: %r0 used in an address
#CHECK: vstrl %v0, 0(%r0), 0
vstrl %v0, 0, -1
vstrl %v0, 0, 256
vstrl %v0, -1, 0
vstrl %v0, 4096, 0
vstrl %v0, 0(%r0), 0
#CHECK: error: invalid operand
#CHECK: vstrlr %v0, %r0, -1
#CHECK: error: invalid operand
#CHECK: vstrlr %v0, %r0, 4096
#CHECK: error: %r0 used in an address
#CHECK: vstrlr %v0, %r0, 0(%r0)
vstrlr %v0, %r0, -1
vstrlr %v0, %r0, 4096
vstrlr %v0, %r0, 0(%r0)
#CHECK: error: invalid operand
#CHECK: vupkz %v0, 0, -1
#CHECK: error: invalid operand
#CHECK: vupkz %v0, 0, 256
#CHECK: error: invalid operand
#CHECK: vupkz %v0, -1, 0
#CHECK: error: invalid operand
#CHECK: vupkz %v0, 4096, 0
#CHECK: error: %r0 used in an address
#CHECK: vupkz %v0, 0(%r0), 0
vupkz %v0, 0, -1
vupkz %v0, 0, 256
vupkz %v0, -1, 0
vupkz %v0, 4096, 0
vupkz %v0, 0(%r0), 0
#CHECK: error: invalid operand
#CHECK: wfmaxdb %v0, %v0, %v0, -1
#CHECK: error: invalid operand
#CHECK: wfmaxdb %v0, %v0, %v0, 16
wfmaxdb %v0, %v0, %v0, -1
wfmaxdb %v0, %v0, %v0, 16
#CHECK: error: invalid operand
#CHECK: wfmindb %v0, %v0, %v0, -1
#CHECK: error: invalid operand
#CHECK: wfmindb %v0, %v0, %v0, 16
wfmindb %v0, %v0, %v0, -1
wfmindb %v0, %v0, %v0, 16

File diff suppressed because it is too large Load Diff