[SystemZ] Add vector intrinsics

This adds intrinsics to allow access to all of the z13 vector instructions.
Note that instructions whose semantics can be described by standard LLVM IR
do not get any intrinsics.

For each instructions whose semantics *cannot* (fully) be described, we
define an LLVM IR target-specific intrinsic that directly maps to this
instruction.

For instructions that also set the condition code, the LLVM IR intrinsic
returns the post-instruction CC value as a second result.  Instruction
selection will attempt to detect code that compares that CC value against
constants and use the condition code directly instead.

Based on a patch by Richard Sandiford.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236527 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ulrich Weigand 2015-05-05 19:31:09 +00:00
parent e07464832d
commit 88b90e11b4
7 changed files with 4161 additions and 152 deletions

View File

@ -11,6 +11,185 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
class SystemZUnaryConv<string name, LLVMType result, LLVMType arg>
: GCCBuiltin<"__builtin_s390_" ## name>,
Intrinsic<[result], [arg], [IntrNoMem]>;
class SystemZUnary<string name, LLVMType type>
: SystemZUnaryConv<name, type, type>;
class SystemZUnaryConvCC<LLVMType result, LLVMType arg>
: Intrinsic<[result, llvm_i32_ty], [arg], [IntrNoMem]>;
class SystemZUnaryCC<LLVMType type>
: SystemZUnaryConvCC<type, type>;
class SystemZBinaryConv<string name, LLVMType result, LLVMType arg>
: GCCBuiltin<"__builtin_s390_" ## name>,
Intrinsic<[result], [arg, arg], [IntrNoMem]>;
class SystemZBinary<string name, LLVMType type>
: SystemZBinaryConv<name, type, type>;
class SystemZBinaryInt<string name, LLVMType type>
: GCCBuiltin<"__builtin_s390_" ## name>,
Intrinsic<[type], [type, llvm_i32_ty], [IntrNoMem]>;
class SystemZBinaryConvCC<LLVMType result, LLVMType arg>
: Intrinsic<[result, llvm_i32_ty], [arg, arg], [IntrNoMem]>;
class SystemZBinaryConvIntCC<LLVMType result, LLVMType arg>
: Intrinsic<[result, llvm_i32_ty], [arg, llvm_i32_ty], [IntrNoMem]>;
class SystemZBinaryCC<LLVMType type>
: SystemZBinaryConvCC<type, type>;
class SystemZTernaryConv<string name, LLVMType result, LLVMType arg>
: GCCBuiltin<"__builtin_s390_" ## name>,
Intrinsic<[result], [arg, arg, result], [IntrNoMem]>;
class SystemZTernary<string name, LLVMType type>
: SystemZTernaryConv<name, type, type>;
class SystemZTernaryInt<string name, LLVMType type>
: GCCBuiltin<"__builtin_s390_" ## name>,
Intrinsic<[type], [type, type, llvm_i32_ty], [IntrNoMem]>;
class SystemZTernaryIntCC<LLVMType type>
: Intrinsic<[type, llvm_i32_ty], [type, type, llvm_i32_ty], [IntrNoMem]>;
class SystemZQuaternaryInt<string name, LLVMType type>
: GCCBuiltin<"__builtin_s390_" ## name>,
Intrinsic<[type], [type, type, type, llvm_i32_ty], [IntrNoMem]>;
class SystemZQuaternaryIntCC<LLVMType type>
: Intrinsic<[type, llvm_i32_ty], [type, type, type, llvm_i32_ty],
[IntrNoMem]>;
multiclass SystemZUnaryExtBHF<string name> {
def b : SystemZUnaryConv<name##"b", llvm_v8i16_ty, llvm_v16i8_ty>;
def h : SystemZUnaryConv<name##"h", llvm_v4i32_ty, llvm_v8i16_ty>;
def f : SystemZUnaryConv<name##"f", llvm_v2i64_ty, llvm_v4i32_ty>;
}
multiclass SystemZUnaryExtBHWF<string name> {
def b : SystemZUnaryConv<name##"b", llvm_v8i16_ty, llvm_v16i8_ty>;
def hw : SystemZUnaryConv<name##"hw", llvm_v4i32_ty, llvm_v8i16_ty>;
def f : SystemZUnaryConv<name##"f", llvm_v2i64_ty, llvm_v4i32_ty>;
}
multiclass SystemZUnaryBHF<string name> {
def b : SystemZUnary<name##"b", llvm_v16i8_ty>;
def h : SystemZUnary<name##"h", llvm_v8i16_ty>;
def f : SystemZUnary<name##"f", llvm_v4i32_ty>;
}
multiclass SystemZUnaryBHFG<string name> : SystemZUnaryBHF<name> {
def g : SystemZUnary<name##"g", llvm_v2i64_ty>;
}
multiclass SystemZUnaryCCBHF {
def bs : SystemZUnaryCC<llvm_v16i8_ty>;
def hs : SystemZUnaryCC<llvm_v8i16_ty>;
def fs : SystemZUnaryCC<llvm_v4i32_ty>;
}
multiclass SystemZBinaryTruncHFG<string name> {
def h : SystemZBinaryConv<name##"h", llvm_v16i8_ty, llvm_v8i16_ty>;
def f : SystemZBinaryConv<name##"f", llvm_v8i16_ty, llvm_v4i32_ty>;
def g : SystemZBinaryConv<name##"g", llvm_v4i32_ty, llvm_v2i64_ty>;
}
multiclass SystemZBinaryTruncCCHFG {
def hs : SystemZBinaryConvCC<llvm_v16i8_ty, llvm_v8i16_ty>;
def fs : SystemZBinaryConvCC<llvm_v8i16_ty, llvm_v4i32_ty>;
def gs : SystemZBinaryConvCC<llvm_v4i32_ty, llvm_v2i64_ty>;
}
multiclass SystemZBinaryExtBHF<string name> {
def b : SystemZBinaryConv<name##"b", llvm_v8i16_ty, llvm_v16i8_ty>;
def h : SystemZBinaryConv<name##"h", llvm_v4i32_ty, llvm_v8i16_ty>;
def f : SystemZBinaryConv<name##"f", llvm_v2i64_ty, llvm_v4i32_ty>;
}
multiclass SystemZBinaryExtBHFG<string name> : SystemZBinaryExtBHF<name> {
def g : SystemZBinaryConv<name##"g", llvm_v16i8_ty, llvm_v2i64_ty>;
}
multiclass SystemZBinaryBHF<string name> {
def b : SystemZBinary<name##"b", llvm_v16i8_ty>;
def h : SystemZBinary<name##"h", llvm_v8i16_ty>;
def f : SystemZBinary<name##"f", llvm_v4i32_ty>;
}
multiclass SystemZBinaryBHFG<string name> : SystemZBinaryBHF<name> {
def g : SystemZBinary<name##"g", llvm_v2i64_ty>;
}
multiclass SystemZBinaryIntBHFG<string name> {
def b : SystemZBinaryInt<name##"b", llvm_v16i8_ty>;
def h : SystemZBinaryInt<name##"h", llvm_v8i16_ty>;
def f : SystemZBinaryInt<name##"f", llvm_v4i32_ty>;
def g : SystemZBinaryInt<name##"g", llvm_v2i64_ty>;
}
multiclass SystemZBinaryCCBHF {
def bs : SystemZBinaryCC<llvm_v16i8_ty>;
def hs : SystemZBinaryCC<llvm_v8i16_ty>;
def fs : SystemZBinaryCC<llvm_v4i32_ty>;
}
multiclass SystemZCompareBHFG<string name> {
def bs : SystemZBinaryCC<llvm_v16i8_ty>;
def hs : SystemZBinaryCC<llvm_v8i16_ty>;
def fs : SystemZBinaryCC<llvm_v4i32_ty>;
def gs : SystemZBinaryCC<llvm_v2i64_ty>;
}
multiclass SystemZTernaryExtBHF<string name> {
def b : SystemZTernaryConv<name##"b", llvm_v8i16_ty, llvm_v16i8_ty>;
def h : SystemZTernaryConv<name##"h", llvm_v4i32_ty, llvm_v8i16_ty>;
def f : SystemZTernaryConv<name##"f", llvm_v2i64_ty, llvm_v4i32_ty>;
}
multiclass SystemZTernaryExtBHFG<string name> : SystemZTernaryExtBHF<name> {
def g : SystemZTernaryConv<name##"g", llvm_v16i8_ty, llvm_v2i64_ty>;
}
multiclass SystemZTernaryBHF<string name> {
def b : SystemZTernary<name##"b", llvm_v16i8_ty>;
def h : SystemZTernary<name##"h", llvm_v8i16_ty>;
def f : SystemZTernary<name##"f", llvm_v4i32_ty>;
}
multiclass SystemZTernaryIntBHF<string name> {
def b : SystemZTernaryInt<name##"b", llvm_v16i8_ty>;
def h : SystemZTernaryInt<name##"h", llvm_v8i16_ty>;
def f : SystemZTernaryInt<name##"f", llvm_v4i32_ty>;
}
multiclass SystemZTernaryIntCCBHF {
def bs : SystemZTernaryIntCC<llvm_v16i8_ty>;
def hs : SystemZTernaryIntCC<llvm_v8i16_ty>;
def fs : SystemZTernaryIntCC<llvm_v4i32_ty>;
}
multiclass SystemZQuaternaryIntBHF<string name> {
def b : SystemZQuaternaryInt<name##"b", llvm_v16i8_ty>;
def h : SystemZQuaternaryInt<name##"h", llvm_v8i16_ty>;
def f : SystemZQuaternaryInt<name##"f", llvm_v4i32_ty>;
}
multiclass SystemZQuaternaryIntBHFG<string name> : SystemZQuaternaryIntBHF<name> {
def g : SystemZQuaternaryInt<name##"g", llvm_v2i64_ty>;
}
multiclass SystemZQuaternaryIntCCBHF {
def bs : SystemZQuaternaryIntCC<llvm_v16i8_ty>;
def hs : SystemZQuaternaryIntCC<llvm_v8i16_ty>;
def fs : SystemZQuaternaryIntCC<llvm_v4i32_ty>;
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// Transactional-execution intrinsics // Transactional-execution intrinsics
@ -44,3 +223,154 @@ let TargetPrefix = "s390" in {
Intrinsic<[], [llvm_i32_ty]>; Intrinsic<[], [llvm_i32_ty]>;
} }
//===----------------------------------------------------------------------===//
//
// Vector intrinsics
//
//===----------------------------------------------------------------------===//
let TargetPrefix = "s390" in {
def int_s390_lcbb : GCCBuiltin<"__builtin_s390_lcbb">,
Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_s390_vlbb : GCCBuiltin<"__builtin_s390_vlbb">,
Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty, llvm_i32_ty],
[IntrReadArgMem]>;
def int_s390_vll : GCCBuiltin<"__builtin_s390_vll">,
Intrinsic<[llvm_v16i8_ty], [llvm_i32_ty, llvm_ptr_ty],
[IntrReadArgMem]>;
def int_s390_vpdi : GCCBuiltin<"__builtin_s390_vpdi">,
Intrinsic<[llvm_v2i64_ty],
[llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_s390_vperm : GCCBuiltin<"__builtin_s390_vperm">,
Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
[IntrNoMem]>;
defm int_s390_vpks : SystemZBinaryTruncHFG<"vpks">;
defm int_s390_vpks : SystemZBinaryTruncCCHFG;
defm int_s390_vpkls : SystemZBinaryTruncHFG<"vpkls">;
defm int_s390_vpkls : SystemZBinaryTruncCCHFG;
def int_s390_vstl : GCCBuiltin<"__builtin_s390_vstl">,
Intrinsic<[], [llvm_v16i8_ty, llvm_i32_ty, llvm_ptr_ty],
// In fact write-only but there's no property
// for that.
[IntrReadWriteArgMem]>;
defm int_s390_vupl : SystemZUnaryExtBHWF<"vupl">;
defm int_s390_vupll : SystemZUnaryExtBHF<"vupll">;
defm int_s390_vuph : SystemZUnaryExtBHF<"vuph">;
defm int_s390_vuplh : SystemZUnaryExtBHF<"vuplh">;
defm int_s390_vacc : SystemZBinaryBHFG<"vacc">;
def int_s390_vaq : SystemZBinary<"vaq", llvm_v16i8_ty>;
def int_s390_vacq : SystemZTernary<"vacq", llvm_v16i8_ty>;
def int_s390_vaccq : SystemZBinary<"vaccq", llvm_v16i8_ty>;
def int_s390_vacccq : SystemZTernary<"vacccq", llvm_v16i8_ty>;
defm int_s390_vavg : SystemZBinaryBHFG<"vavg">;
defm int_s390_vavgl : SystemZBinaryBHFG<"vavgl">;
def int_s390_vcksm : SystemZBinary<"vcksm", llvm_v4i32_ty>;
defm int_s390_vgfm : SystemZBinaryExtBHFG<"vgfm">;
defm int_s390_vgfma : SystemZTernaryExtBHFG<"vgfma">;
defm int_s390_vmah : SystemZTernaryBHF<"vmah">;
defm int_s390_vmalh : SystemZTernaryBHF<"vmalh">;
defm int_s390_vmae : SystemZTernaryExtBHF<"vmae">;
defm int_s390_vmale : SystemZTernaryExtBHF<"vmale">;
defm int_s390_vmao : SystemZTernaryExtBHF<"vmao">;
defm int_s390_vmalo : SystemZTernaryExtBHF<"vmalo">;
defm int_s390_vmh : SystemZBinaryBHF<"vmh">;
defm int_s390_vmlh : SystemZBinaryBHF<"vmlh">;
defm int_s390_vme : SystemZBinaryExtBHF<"vme">;
defm int_s390_vmle : SystemZBinaryExtBHF<"vmle">;
defm int_s390_vmo : SystemZBinaryExtBHF<"vmo">;
defm int_s390_vmlo : SystemZBinaryExtBHF<"vmlo">;
defm int_s390_verllv : SystemZBinaryBHFG<"verllv">;
defm int_s390_verll : SystemZBinaryIntBHFG<"verll">;
defm int_s390_verim : SystemZQuaternaryIntBHFG<"verim">;
def int_s390_vsl : SystemZBinary<"vsl", llvm_v16i8_ty>;
def int_s390_vslb : SystemZBinary<"vslb", llvm_v16i8_ty>;
def int_s390_vsra : SystemZBinary<"vsra", llvm_v16i8_ty>;
def int_s390_vsrab : SystemZBinary<"vsrab", llvm_v16i8_ty>;
def int_s390_vsrl : SystemZBinary<"vsrl", llvm_v16i8_ty>;
def int_s390_vsrlb : SystemZBinary<"vsrlb", llvm_v16i8_ty>;
def int_s390_vsldb : GCCBuiltin<"__builtin_s390_vsldb">,
Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
[IntrNoMem]>;
defm int_s390_vscbi : SystemZBinaryBHFG<"vscbi">;
def int_s390_vsq : SystemZBinary<"vsq", llvm_v16i8_ty>;
def int_s390_vsbiq : SystemZTernary<"vsbiq", llvm_v16i8_ty>;
def int_s390_vscbiq : SystemZBinary<"vscbiq", llvm_v16i8_ty>;
def int_s390_vsbcbiq : SystemZTernary<"vsbcbiq", llvm_v16i8_ty>;
def int_s390_vsumb : SystemZBinaryConv<"vsumb", llvm_v4i32_ty, llvm_v16i8_ty>;
def int_s390_vsumh : SystemZBinaryConv<"vsumh", llvm_v4i32_ty, llvm_v8i16_ty>;
def int_s390_vsumgh : SystemZBinaryConv<"vsumgh", llvm_v2i64_ty,
llvm_v8i16_ty>;
def int_s390_vsumgf : SystemZBinaryConv<"vsumgf", llvm_v2i64_ty,
llvm_v4i32_ty>;
def int_s390_vsumqf : SystemZBinaryConv<"vsumqf", llvm_v16i8_ty,
llvm_v4i32_ty>;
def int_s390_vsumqg : SystemZBinaryConv<"vsumqg", llvm_v16i8_ty,
llvm_v2i64_ty>;
def int_s390_vtm : SystemZBinaryConv<"vtm", llvm_i32_ty, llvm_v16i8_ty>;
defm int_s390_vceq : SystemZCompareBHFG<"vceq">;
defm int_s390_vch : SystemZCompareBHFG<"vch">;
defm int_s390_vchl : SystemZCompareBHFG<"vchl">;
defm int_s390_vfae : SystemZTernaryIntBHF<"vfae">;
defm int_s390_vfae : SystemZTernaryIntCCBHF;
defm int_s390_vfaez : SystemZTernaryIntBHF<"vfaez">;
defm int_s390_vfaez : SystemZTernaryIntCCBHF;
defm int_s390_vfee : SystemZBinaryBHF<"vfee">;
defm int_s390_vfee : SystemZBinaryCCBHF;
defm int_s390_vfeez : SystemZBinaryBHF<"vfeez">;
defm int_s390_vfeez : SystemZBinaryCCBHF;
defm int_s390_vfene : SystemZBinaryBHF<"vfene">;
defm int_s390_vfene : SystemZBinaryCCBHF;
defm int_s390_vfenez : SystemZBinaryBHF<"vfenez">;
defm int_s390_vfenez : SystemZBinaryCCBHF;
defm int_s390_vistr : SystemZUnaryBHF<"vistr">;
defm int_s390_vistr : SystemZUnaryCCBHF;
defm int_s390_vstrc : SystemZQuaternaryIntBHF<"vstrc">;
defm int_s390_vstrc : SystemZQuaternaryIntCCBHF;
defm int_s390_vstrcz : SystemZQuaternaryIntBHF<"vstrcz">;
defm int_s390_vstrcz : SystemZQuaternaryIntCCBHF;
def int_s390_vfcedbs : SystemZBinaryConvCC<llvm_v2i64_ty, llvm_v2f64_ty>;
def int_s390_vfchdbs : SystemZBinaryConvCC<llvm_v2i64_ty, llvm_v2f64_ty>;
def int_s390_vfchedbs : SystemZBinaryConvCC<llvm_v2i64_ty, llvm_v2f64_ty>;
def int_s390_vftcidb : SystemZBinaryConvIntCC<llvm_v2i64_ty, llvm_v2f64_ty>;
def int_s390_vfidb : Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
}

View File

@ -80,6 +80,13 @@ const unsigned CCMASK_TEND_TX = CCMASK_0;
const unsigned CCMASK_TEND_NOTX = CCMASK_2; const unsigned CCMASK_TEND_NOTX = CCMASK_2;
const unsigned CCMASK_TEND = CCMASK_TEND_TX | CCMASK_TEND_NOTX; const unsigned CCMASK_TEND = CCMASK_TEND_TX | CCMASK_TEND_NOTX;
// Condition-code mask assignments for vector comparisons (and similar
// operations).
const unsigned CCMASK_VCMP_ALL = CCMASK_0;
const unsigned CCMASK_VCMP_MIXED = CCMASK_1;
const unsigned CCMASK_VCMP_NONE = CCMASK_3;
const unsigned CCMASK_VCMP = CCMASK_0 | CCMASK_1 | CCMASK_3;
// The position of the low CC bit in an IPM result. // The position of the low CC bit in an IPM result.
const unsigned IPM_CC = 28; const unsigned IPM_CC = 28;

View File

@ -440,6 +440,7 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &tm,
// Handle intrinsics. // Handle intrinsics.
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom); setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
// We want to use MVC in preference to even a single load/store pair. // We want to use MVC in preference to even a single load/store pair.
MaxStoresPerMemcpy = 0; MaxStoresPerMemcpy = 0;
@ -1253,6 +1254,143 @@ static bool isIntrinsicWithCCAndChain(SDValue Op, unsigned &Opcode,
} }
} }
// Return true if Op is an intrinsic node without chain that returns the
// CC value as its final argument. Provide the associated SystemZISD
// opcode and the mask of valid CC values if so.
static bool isIntrinsicWithCC(SDValue Op, unsigned &Opcode, unsigned &CCValid) {
unsigned Id = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
switch (Id) {
case Intrinsic::s390_vpkshs:
case Intrinsic::s390_vpksfs:
case Intrinsic::s390_vpksgs:
Opcode = SystemZISD::PACKS_CC;
CCValid = SystemZ::CCMASK_VCMP;
return true;
case Intrinsic::s390_vpklshs:
case Intrinsic::s390_vpklsfs:
case Intrinsic::s390_vpklsgs:
Opcode = SystemZISD::PACKLS_CC;
CCValid = SystemZ::CCMASK_VCMP;
return true;
case Intrinsic::s390_vceqbs:
case Intrinsic::s390_vceqhs:
case Intrinsic::s390_vceqfs:
case Intrinsic::s390_vceqgs:
Opcode = SystemZISD::VICMPES;
CCValid = SystemZ::CCMASK_VCMP;
return true;
case Intrinsic::s390_vchbs:
case Intrinsic::s390_vchhs:
case Intrinsic::s390_vchfs:
case Intrinsic::s390_vchgs:
Opcode = SystemZISD::VICMPHS;
CCValid = SystemZ::CCMASK_VCMP;
return true;
case Intrinsic::s390_vchlbs:
case Intrinsic::s390_vchlhs:
case Intrinsic::s390_vchlfs:
case Intrinsic::s390_vchlgs:
Opcode = SystemZISD::VICMPHLS;
CCValid = SystemZ::CCMASK_VCMP;
return true;
case Intrinsic::s390_vtm:
Opcode = SystemZISD::VTM;
CCValid = SystemZ::CCMASK_VCMP;
return true;
case Intrinsic::s390_vfaebs:
case Intrinsic::s390_vfaehs:
case Intrinsic::s390_vfaefs:
Opcode = SystemZISD::VFAE_CC;
CCValid = SystemZ::CCMASK_ANY;
return true;
case Intrinsic::s390_vfaezbs:
case Intrinsic::s390_vfaezhs:
case Intrinsic::s390_vfaezfs:
Opcode = SystemZISD::VFAEZ_CC;
CCValid = SystemZ::CCMASK_ANY;
return true;
case Intrinsic::s390_vfeebs:
case Intrinsic::s390_vfeehs:
case Intrinsic::s390_vfeefs:
Opcode = SystemZISD::VFEE_CC;
CCValid = SystemZ::CCMASK_ANY;
return true;
case Intrinsic::s390_vfeezbs:
case Intrinsic::s390_vfeezhs:
case Intrinsic::s390_vfeezfs:
Opcode = SystemZISD::VFEEZ_CC;
CCValid = SystemZ::CCMASK_ANY;
return true;
case Intrinsic::s390_vfenebs:
case Intrinsic::s390_vfenehs:
case Intrinsic::s390_vfenefs:
Opcode = SystemZISD::VFENE_CC;
CCValid = SystemZ::CCMASK_ANY;
return true;
case Intrinsic::s390_vfenezbs:
case Intrinsic::s390_vfenezhs:
case Intrinsic::s390_vfenezfs:
Opcode = SystemZISD::VFENEZ_CC;
CCValid = SystemZ::CCMASK_ANY;
return true;
case Intrinsic::s390_vistrbs:
case Intrinsic::s390_vistrhs:
case Intrinsic::s390_vistrfs:
Opcode = SystemZISD::VISTR_CC;
CCValid = SystemZ::CCMASK_0 | SystemZ::CCMASK_3;
return true;
case Intrinsic::s390_vstrcbs:
case Intrinsic::s390_vstrchs:
case Intrinsic::s390_vstrcfs:
Opcode = SystemZISD::VSTRC_CC;
CCValid = SystemZ::CCMASK_ANY;
return true;
case Intrinsic::s390_vstrczbs:
case Intrinsic::s390_vstrczhs:
case Intrinsic::s390_vstrczfs:
Opcode = SystemZISD::VSTRCZ_CC;
CCValid = SystemZ::CCMASK_ANY;
return true;
case Intrinsic::s390_vfcedbs:
Opcode = SystemZISD::VFCMPES;
CCValid = SystemZ::CCMASK_VCMP;
return true;
case Intrinsic::s390_vfchdbs:
Opcode = SystemZISD::VFCMPHS;
CCValid = SystemZ::CCMASK_VCMP;
return true;
case Intrinsic::s390_vfchedbs:
Opcode = SystemZISD::VFCMPHES;
CCValid = SystemZ::CCMASK_VCMP;
return true;
case Intrinsic::s390_vftcidb:
Opcode = SystemZISD::VFTCI;
CCValid = SystemZ::CCMASK_VCMP;
return true;
default:
return false;
}
}
// Emit an intrinsic with chain with a glued value instead of its CC result. // Emit an intrinsic with chain with a glued value instead of its CC result.
static SDValue emitIntrinsicWithChainAndGlue(SelectionDAG &DAG, SDValue Op, static SDValue emitIntrinsicWithChainAndGlue(SelectionDAG &DAG, SDValue Op,
unsigned Opcode) { unsigned Opcode) {
@ -1273,6 +1411,23 @@ static SDValue emitIntrinsicWithChainAndGlue(SelectionDAG &DAG, SDValue Op,
return Intr; return Intr;
} }
// Emit an intrinsic with a glued value instead of its CC result.
static SDValue emitIntrinsicWithGlue(SelectionDAG &DAG, SDValue Op,
unsigned Opcode) {
// Copy all operands except the intrinsic ID.
unsigned NumOps = Op.getNumOperands();
SmallVector<SDValue, 6> Ops;
Ops.reserve(NumOps - 1);
for (unsigned I = 1; I < NumOps; ++I)
Ops.push_back(Op.getOperand(I));
if (Op->getNumValues() == 1)
return DAG.getNode(Opcode, SDLoc(Op), MVT::Glue, Ops);
assert(Op->getNumValues() == 2 && "Expected exactly one non-CC result");
SDVTList RawVTs = DAG.getVTList(Op->getValueType(0), MVT::Glue);
return DAG.getNode(Opcode, SDLoc(Op), RawVTs, Ops);
}
// CC is a comparison that will be implemented using an integer or // CC is a comparison that will be implemented using an integer or
// floating-point comparison. Return the condition code mask for // floating-point comparison. Return the condition code mask for
// a branch on true. In the integer case, CCMASK_CMP_UO is set for // a branch on true. In the integer case, CCMASK_CMP_UO is set for
@ -1876,6 +2031,10 @@ static Comparison getCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1,
CmpOp0.getResNo() == 0 && CmpOp0->hasNUsesOfValue(1, 0) && CmpOp0.getResNo() == 0 && CmpOp0->hasNUsesOfValue(1, 0) &&
isIntrinsicWithCCAndChain(CmpOp0, Opcode, CCValid)) isIntrinsicWithCCAndChain(CmpOp0, Opcode, CCValid))
return getIntrinsicCmp(DAG, Opcode, CmpOp0, CCValid, Constant, Cond); return getIntrinsicCmp(DAG, Opcode, CmpOp0, CCValid, Constant, Cond);
if (CmpOp0.getOpcode() == ISD::INTRINSIC_WO_CHAIN &&
CmpOp0.getResNo() == CmpOp0->getNumValues() - 1 &&
isIntrinsicWithCC(CmpOp0, Opcode, CCValid))
return getIntrinsicCmp(DAG, Opcode, CmpOp0, CCValid, Constant, Cond);
} }
Comparison C(CmpOp0, CmpOp1); Comparison C(CmpOp0, CmpOp1);
C.CCMask = CCMaskForCondCode(Cond); C.CCMask = CCMaskForCondCode(Cond);
@ -1924,6 +2083,9 @@ static SDValue emitCmp(SelectionDAG &DAG, SDLoc DL, Comparison &C) {
case ISD::INTRINSIC_W_CHAIN: case ISD::INTRINSIC_W_CHAIN:
Op = emitIntrinsicWithChainAndGlue(DAG, C.Op0, C.Opcode); Op = emitIntrinsicWithChainAndGlue(DAG, C.Op0, C.Opcode);
break; break;
case ISD::INTRINSIC_WO_CHAIN:
Op = emitIntrinsicWithGlue(DAG, C.Op0, C.Opcode);
break;
default: default:
llvm_unreachable("Invalid comparison operands"); llvm_unreachable("Invalid comparison operands");
} }
@ -3058,6 +3220,67 @@ SystemZTargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
return SDValue(); return SDValue();
} }
SDValue
SystemZTargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
SelectionDAG &DAG) const {
unsigned Opcode, CCValid;
if (isIntrinsicWithCC(Op, Opcode, CCValid)) {
SDValue Glued = emitIntrinsicWithGlue(DAG, Op, Opcode);
SDValue CC = getCCResult(DAG, Glued.getNode());
if (Op->getNumValues() == 1)
return CC;
assert(Op->getNumValues() == 2 && "Expected a CC and non-CC result");
return DAG.getNode(ISD::MERGE_VALUES, SDLoc(Op), Op->getVTList(),
Glued, CC);
}
unsigned Id = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
switch (Id) {
case Intrinsic::s390_vpdi:
return DAG.getNode(SystemZISD::PERMUTE_DWORDS, SDLoc(Op), Op.getValueType(),
Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
case Intrinsic::s390_vperm:
return DAG.getNode(SystemZISD::PERMUTE, SDLoc(Op), Op.getValueType(),
Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
case Intrinsic::s390_vuphb:
case Intrinsic::s390_vuphh:
case Intrinsic::s390_vuphf:
return DAG.getNode(SystemZISD::UNPACK_HIGH, SDLoc(Op), Op.getValueType(),
Op.getOperand(1));
case Intrinsic::s390_vuplhb:
case Intrinsic::s390_vuplhh:
case Intrinsic::s390_vuplhf:
return DAG.getNode(SystemZISD::UNPACKL_HIGH, SDLoc(Op), Op.getValueType(),
Op.getOperand(1));
case Intrinsic::s390_vuplb:
case Intrinsic::s390_vuplhw:
case Intrinsic::s390_vuplf:
return DAG.getNode(SystemZISD::UNPACK_LOW, SDLoc(Op), Op.getValueType(),
Op.getOperand(1));
case Intrinsic::s390_vupllb:
case Intrinsic::s390_vupllh:
case Intrinsic::s390_vupllf:
return DAG.getNode(SystemZISD::UNPACKL_LOW, SDLoc(Op), Op.getValueType(),
Op.getOperand(1));
case Intrinsic::s390_vsumb:
case Intrinsic::s390_vsumh:
case Intrinsic::s390_vsumgh:
case Intrinsic::s390_vsumgf:
case Intrinsic::s390_vsumqf:
case Intrinsic::s390_vsumqg:
return DAG.getNode(SystemZISD::VSUM, SDLoc(Op), Op.getValueType(),
Op.getOperand(1), Op.getOperand(2));
}
return SDValue();
}
namespace { namespace {
// Says that SystemZISD operation Opcode can be used to perform the equivalent // Says that SystemZISD operation Opcode can be used to perform the equivalent
// of a VPERM with permute vector Bytes. If Opcode takes three operands, // of a VPERM with permute vector Bytes. If Opcode takes three operands,
@ -4117,6 +4340,8 @@ SDValue SystemZTargetLowering::LowerOperation(SDValue Op,
return lowerPREFETCH(Op, DAG); return lowerPREFETCH(Op, DAG);
case ISD::INTRINSIC_W_CHAIN: case ISD::INTRINSIC_W_CHAIN:
return lowerINTRINSIC_W_CHAIN(Op, DAG); return lowerINTRINSIC_W_CHAIN(Op, DAG);
case ISD::INTRINSIC_WO_CHAIN:
return lowerINTRINSIC_WO_CHAIN(Op, DAG);
case ISD::BUILD_VECTOR: case ISD::BUILD_VECTOR:
return lowerBUILD_VECTOR(Op, DAG); return lowerBUILD_VECTOR(Op, DAG);
case ISD::VECTOR_SHUFFLE: case ISD::VECTOR_SHUFFLE:
@ -4195,6 +4420,8 @@ const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const {
OPCODE(PERMUTE_DWORDS); OPCODE(PERMUTE_DWORDS);
OPCODE(PERMUTE); OPCODE(PERMUTE);
OPCODE(PACK); OPCODE(PACK);
OPCODE(PACKS_CC);
OPCODE(PACKLS_CC);
OPCODE(UNPACK_HIGH); OPCODE(UNPACK_HIGH);
OPCODE(UNPACKL_HIGH); OPCODE(UNPACKL_HIGH);
OPCODE(UNPACK_LOW); OPCODE(UNPACK_LOW);
@ -4206,11 +4433,28 @@ const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const {
OPCODE(VICMPE); OPCODE(VICMPE);
OPCODE(VICMPH); OPCODE(VICMPH);
OPCODE(VICMPHL); OPCODE(VICMPHL);
OPCODE(VICMPES);
OPCODE(VICMPHS);
OPCODE(VICMPHLS);
OPCODE(VFCMPE); OPCODE(VFCMPE);
OPCODE(VFCMPH); OPCODE(VFCMPH);
OPCODE(VFCMPHE); OPCODE(VFCMPHE);
OPCODE(VFCMPES);
OPCODE(VFCMPHS);
OPCODE(VFCMPHES);
OPCODE(VFTCI);
OPCODE(VEXTEND); OPCODE(VEXTEND);
OPCODE(VROUND); OPCODE(VROUND);
OPCODE(VTM);
OPCODE(VFAE_CC);
OPCODE(VFAEZ_CC);
OPCODE(VFEE_CC);
OPCODE(VFEEZ_CC);
OPCODE(VFENE_CC);
OPCODE(VFENEZ_CC);
OPCODE(VISTR_CC);
OPCODE(VSTRC_CC);
OPCODE(VSTRCZ_CC);
OPCODE(ATOMIC_SWAPW); OPCODE(ATOMIC_SWAPW);
OPCODE(ATOMIC_LOADW_ADD); OPCODE(ATOMIC_LOADW_ADD);
OPCODE(ATOMIC_LOADW_SUB); OPCODE(ATOMIC_LOADW_SUB);

View File

@ -201,6 +201,11 @@ enum {
// Pack vector operands 0 and 1 into a single vector with half-sized elements. // Pack vector operands 0 and 1 into a single vector with half-sized elements.
PACK, PACK,
// Likewise, but saturate the result and set CC. PACKS_CC does signed
// saturation and PACKLS_CC does unsigned saturation.
PACKS_CC,
PACKLS_CC,
// Unpack the first half of vector operand 0 into double-sized elements. // Unpack the first half of vector operand 0 into double-sized elements.
// UNPACK_HIGH sign-extends and UNPACKL_HIGH zero-extends. // UNPACK_HIGH sign-extends and UNPACKL_HIGH zero-extends.
UNPACK_HIGH, UNPACK_HIGH,
@ -228,6 +233,11 @@ enum {
VICMPH, VICMPH,
VICMPHL, VICMPHL,
// Likewise, but also set the condition codes on the result.
VICMPES,
VICMPHS,
VICMPHLS,
// Compare floating-point vector operands 0 and 1 to preoduce the usual 0/-1 // Compare floating-point vector operands 0 and 1 to preoduce the usual 0/-1
// vector result. VFCMPE is for "ordered and equal", VFCMPH for "ordered and // vector result. VFCMPE is for "ordered and equal", VFCMPH for "ordered and
// greater than" and VFCMPHE for "ordered and greater than or equal to". // greater than" and VFCMPHE for "ordered and greater than or equal to".
@ -235,6 +245,14 @@ enum {
VFCMPH, VFCMPH,
VFCMPHE, VFCMPHE,
// Likewise, but also set the condition codes on the result.
VFCMPES,
VFCMPHS,
VFCMPHES,
// Test floating-point data class for vectors.
VFTCI,
// Extend the even f32 elements of vector operand 0 to produce a vector // Extend the even f32 elements of vector operand 0 to produce a vector
// of f64 elements. // of f64 elements.
VEXTEND, VEXTEND,
@ -243,6 +261,20 @@ enum {
// even elements of the result. // even elements of the result.
VROUND, VROUND,
// AND the two vector operands together and set CC based on the result.
VTM,
// String operations that set CC as a side-effect.
VFAE_CC,
VFAEZ_CC,
VFEE_CC,
VFEEZ_CC,
VFENE_CC,
VFENEZ_CC,
VISTR_CC,
VSTRC_CC,
VSTRCZ_CC,
// Wrappers around the inner loop of an 8- or 16-bit ATOMIC_SWAP or // Wrappers around the inner loop of an 8- or 16-bit ATOMIC_SWAP or
// ATOMIC_LOAD_<op>. // ATOMIC_LOAD_<op>.
// //
@ -438,6 +470,7 @@ private:
SDValue lowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const; SDValue lowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerPREFETCH(SDValue Op, SelectionDAG &DAG) const; SDValue lowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const; SDValue lowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const; SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) const; SDValue lowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) const;

View File

@ -100,17 +100,20 @@ let Predicates = [FeatureVector] in {
def VL : UnaryVRX<"vl", 0xE706, null_frag, v128any, 16>; def VL : UnaryVRX<"vl", 0xE706, null_frag, v128any, 16>;
// Load to block boundary. The number of loaded bytes is only known // Load to block boundary. The number of loaded bytes is only known
// at run time. // at run time. The instruction is really polymorphic, but v128b matches
def VLBB : BinaryVRX<"vlbb", 0xE707, null_frag, v128any, 0>; // the return type of the associated intrinsic.
def VLBB : BinaryVRX<"vlbb", 0xE707, int_s390_vlbb, v128b, 0>;
// Load count to block boundary. // Load count to block boundary.
let Defs = [CC] in let Defs = [CC] in
def LCBB : InstRXE<0xE727, (outs GR32:$R1), def LCBB : InstRXE<0xE727, (outs GR32:$R1),
(ins bdxaddr12only:$XBD2, imm32zx4:$M3), (ins bdxaddr12only:$XBD2, imm32zx4:$M3),
"lcbb\t$R1, $XBD2, $M3", []>; "lcbb\t$R1, $XBD2, $M3",
[(set GR32:$R1, (int_s390_lcbb bdxaddr12only:$XBD2,
imm32zx4:$M3))]>;
// Load with length. The number of loaded bytes is only known at run time. // Load with length. The number of loaded bytes is only known at run time.
def VLL : BinaryVRSb<"vll", 0xE737, null_frag, 0>; def VLL : BinaryVRSb<"vll", 0xE737, int_s390_vll, 0>;
// Load multiple. // Load multiple.
def VLM : LoadMultipleVRSa<"vlm", 0xE736>; def VLM : LoadMultipleVRSa<"vlm", 0xE736>;
@ -185,7 +188,7 @@ let Predicates = [FeatureVector] in {
def VST : StoreVRX<"vst", 0xE70E, null_frag, v128any, 16>; def VST : StoreVRX<"vst", 0xE70E, null_frag, v128any, 16>;
// Store with length. The number of stored bytes is only known at run time. // Store with length. The number of stored bytes is only known at run time.
def VSTL : StoreLengthVRSb<"vstl", 0xE73F, null_frag, 0>; def VSTL : StoreLengthVRSb<"vstl", 0xE73F, int_s390_vstl, 0>;
// Store multiple. // Store multiple.
def VSTM : StoreMultipleVRSa<"vstm", 0xE73E>; def VSTM : StoreMultipleVRSa<"vstm", 0xE73E>;
@ -266,19 +269,19 @@ let Predicates = [FeatureVector] in {
def VPKG : BinaryVRRc<"vpkg", 0xE794, z_pack, v128f, v128g, 3>; def VPKG : BinaryVRRc<"vpkg", 0xE794, z_pack, v128f, v128g, 3>;
// Pack saturate. // Pack saturate.
defm VPKSH : BinaryVRRbSPair<"vpksh", 0xE797, null_frag, null_frag, defm VPKSH : BinaryVRRbSPair<"vpksh", 0xE797, int_s390_vpksh, z_packs_cc,
v128b, v128h, 1>; v128b, v128h, 1>;
defm VPKSF : BinaryVRRbSPair<"vpksf", 0xE797, null_frag, null_frag, defm VPKSF : BinaryVRRbSPair<"vpksf", 0xE797, int_s390_vpksf, z_packs_cc,
v128h, v128f, 2>; v128h, v128f, 2>;
defm VPKSG : BinaryVRRbSPair<"vpksg", 0xE797, null_frag, null_frag, defm VPKSG : BinaryVRRbSPair<"vpksg", 0xE797, int_s390_vpksg, z_packs_cc,
v128f, v128g, 3>; v128f, v128g, 3>;
// Pack saturate logical. // Pack saturate logical.
defm VPKLSH : BinaryVRRbSPair<"vpklsh", 0xE795, null_frag, null_frag, defm VPKLSH : BinaryVRRbSPair<"vpklsh", 0xE795, int_s390_vpklsh, z_packls_cc,
v128b, v128h, 1>; v128b, v128h, 1>;
defm VPKLSF : BinaryVRRbSPair<"vpklsf", 0xE795, null_frag, null_frag, defm VPKLSF : BinaryVRRbSPair<"vpklsf", 0xE795, int_s390_vpklsf, z_packls_cc,
v128h, v128f, 2>; v128h, v128f, 2>;
defm VPKLSG : BinaryVRRbSPair<"vpklsg", 0xE795, null_frag, null_frag, defm VPKLSG : BinaryVRRbSPair<"vpklsg", 0xE795, int_s390_vpklsg, z_packls_cc,
v128f, v128g, 3>; v128f, v128g, 3>;
// Sign-extend to doubleword. // Sign-extend to doubleword.
@ -344,20 +347,20 @@ let Predicates = [FeatureVector] in {
def VAH : BinaryVRRc<"vah", 0xE7F3, add, v128h, v128h, 1>; def VAH : BinaryVRRc<"vah", 0xE7F3, add, v128h, v128h, 1>;
def VAF : BinaryVRRc<"vaf", 0xE7F3, add, v128f, v128f, 2>; def VAF : BinaryVRRc<"vaf", 0xE7F3, add, v128f, v128f, 2>;
def VAG : BinaryVRRc<"vag", 0xE7F3, add, v128g, v128g, 3>; def VAG : BinaryVRRc<"vag", 0xE7F3, add, v128g, v128g, 3>;
def VAQ : BinaryVRRc<"vaq", 0xE7F3, null_frag, v128q, v128q, 4>; def VAQ : BinaryVRRc<"vaq", 0xE7F3, int_s390_vaq, v128q, v128q, 4>;
// Add compute carry. // Add compute carry.
def VACCB : BinaryVRRc<"vaccb", 0xE7F1, null_frag, v128b, v128b, 0>; def VACCB : BinaryVRRc<"vaccb", 0xE7F1, int_s390_vaccb, v128b, v128b, 0>;
def VACCH : BinaryVRRc<"vacch", 0xE7F1, null_frag, v128h, v128h, 1>; def VACCH : BinaryVRRc<"vacch", 0xE7F1, int_s390_vacch, v128h, v128h, 1>;
def VACCF : BinaryVRRc<"vaccf", 0xE7F1, null_frag, v128f, v128f, 2>; def VACCF : BinaryVRRc<"vaccf", 0xE7F1, int_s390_vaccf, v128f, v128f, 2>;
def VACCG : BinaryVRRc<"vaccg", 0xE7F1, null_frag, v128g, v128g, 3>; def VACCG : BinaryVRRc<"vaccg", 0xE7F1, int_s390_vaccg, v128g, v128g, 3>;
def VACCQ : BinaryVRRc<"vaccq", 0xE7F1, null_frag, v128q, v128q, 4>; def VACCQ : BinaryVRRc<"vaccq", 0xE7F1, int_s390_vaccq, v128q, v128q, 4>;
// Add with carry. // Add with carry.
def VACQ : TernaryVRRd<"vacq", 0xE7BB, null_frag, v128q, v128q, 4>; def VACQ : TernaryVRRd<"vacq", 0xE7BB, int_s390_vacq, v128q, v128q, 4>;
// Add with carry compute carry. // Add with carry compute carry.
def VACCCQ : TernaryVRRd<"vacccq", 0xE7B9, null_frag, v128q, v128q, 4>; def VACCCQ : TernaryVRRd<"vacccq", 0xE7B9, int_s390_vacccq, v128q, v128q, 4>;
// And. // And.
def VN : BinaryVRRc<"vn", 0xE768, null_frag, v128any, v128any>; def VN : BinaryVRRc<"vn", 0xE768, null_frag, v128any, v128any>;
@ -366,19 +369,19 @@ let Predicates = [FeatureVector] in {
def VNC : BinaryVRRc<"vnc", 0xE769, null_frag, v128any, v128any>; def VNC : BinaryVRRc<"vnc", 0xE769, null_frag, v128any, v128any>;
// Average. // Average.
def VAVGB : BinaryVRRc<"vavgb", 0xE7F2, null_frag, v128b, v128b, 0>; def VAVGB : BinaryVRRc<"vavgb", 0xE7F2, int_s390_vavgb, v128b, v128b, 0>;
def VAVGH : BinaryVRRc<"vavgh", 0xE7F2, null_frag, v128h, v128h, 1>; def VAVGH : BinaryVRRc<"vavgh", 0xE7F2, int_s390_vavgh, v128h, v128h, 1>;
def VAVGF : BinaryVRRc<"vavgf", 0xE7F2, null_frag, v128f, v128f, 2>; def VAVGF : BinaryVRRc<"vavgf", 0xE7F2, int_s390_vavgf, v128f, v128f, 2>;
def VAVGG : BinaryVRRc<"vavgg", 0xE7F2, null_frag, v128g, v128g, 3>; def VAVGG : BinaryVRRc<"vavgg", 0xE7F2, int_s390_vavgg, v128g, v128g, 3>;
// Average logical. // Average logical.
def VAVGLB : BinaryVRRc<"vavglb", 0xE7F0, null_frag, v128b, v128b, 0>; def VAVGLB : BinaryVRRc<"vavglb", 0xE7F0, int_s390_vavglb, v128b, v128b, 0>;
def VAVGLH : BinaryVRRc<"vavglh", 0xE7F0, null_frag, v128h, v128h, 1>; def VAVGLH : BinaryVRRc<"vavglh", 0xE7F0, int_s390_vavglh, v128h, v128h, 1>;
def VAVGLF : BinaryVRRc<"vavglf", 0xE7F0, null_frag, v128f, v128f, 2>; def VAVGLF : BinaryVRRc<"vavglf", 0xE7F0, int_s390_vavglf, v128f, v128f, 2>;
def VAVGLG : BinaryVRRc<"vavglg", 0xE7F0, null_frag, v128g, v128g, 3>; def VAVGLG : BinaryVRRc<"vavglg", 0xE7F0, int_s390_vavglg, v128g, v128g, 3>;
// Checksum. // Checksum.
def VCKSM : BinaryVRRc<"vcksm", 0xE766, null_frag, v128any, v128any>; def VCKSM : BinaryVRRc<"vcksm", 0xE766, int_s390_vcksm, v128f, v128f>;
// Count leading zeros. // Count leading zeros.
def VCLZB : UnaryVRRa<"vclzb", 0xE753, ctlz, v128b, v128b, 0>; def VCLZB : UnaryVRRa<"vclzb", 0xE753, ctlz, v128b, v128b, 0>;
@ -396,16 +399,16 @@ let Predicates = [FeatureVector] in {
def VX : BinaryVRRc<"vx", 0xE76D, null_frag, v128any, v128any>; def VX : BinaryVRRc<"vx", 0xE76D, null_frag, v128any, v128any>;
// Galois field multiply sum. // Galois field multiply sum.
def VGFMB : BinaryVRRc<"vgfmb", 0xE7B4, null_frag, v128b, v128b, 0>; def VGFMB : BinaryVRRc<"vgfmb", 0xE7B4, int_s390_vgfmb, v128h, v128b, 0>;
def VGFMH : BinaryVRRc<"vgfmh", 0xE7B4, null_frag, v128h, v128h, 1>; def VGFMH : BinaryVRRc<"vgfmh", 0xE7B4, int_s390_vgfmh, v128f, v128h, 1>;
def VGFMF : BinaryVRRc<"vgfmf", 0xE7B4, null_frag, v128f, v128f, 2>; def VGFMF : BinaryVRRc<"vgfmf", 0xE7B4, int_s390_vgfmf, v128g, v128f, 2>;
def VGFMG : BinaryVRRc<"vgfmg", 0xE7B4, null_frag, v128g, v128g, 3>; def VGFMG : BinaryVRRc<"vgfmg", 0xE7B4, int_s390_vgfmg, v128q, v128g, 3>;
// Galois field multiply sum and accumulate. // Galois field multiply sum and accumulate.
def VGFMAB : TernaryVRRd<"vgfmab", 0xE7BC, null_frag, v128b, v128b, 0>; def VGFMAB : TernaryVRRd<"vgfmab", 0xE7BC, int_s390_vgfmab, v128h, v128b, 0>;
def VGFMAH : TernaryVRRd<"vgfmah", 0xE7BC, null_frag, v128h, v128h, 1>; def VGFMAH : TernaryVRRd<"vgfmah", 0xE7BC, int_s390_vgfmah, v128f, v128h, 1>;
def VGFMAF : TernaryVRRd<"vgfmaf", 0xE7BC, null_frag, v128f, v128f, 2>; def VGFMAF : TernaryVRRd<"vgfmaf", 0xE7BC, int_s390_vgfmaf, v128g, v128f, 2>;
def VGFMAG : TernaryVRRd<"vgfmag", 0xE7BC, null_frag, v128g, v128g, 3>; def VGFMAG : TernaryVRRd<"vgfmag", 0xE7BC, int_s390_vgfmag, v128q, v128g, 3>;
// Load complement. // Load complement.
def VLCB : UnaryVRRa<"vlcb", 0xE7DE, z_vneg, v128b, v128b, 0>; def VLCB : UnaryVRRa<"vlcb", 0xE7DE, z_vneg, v128b, v128b, 0>;
@ -449,44 +452,44 @@ let Predicates = [FeatureVector] in {
def VMALF : TernaryVRRd<"vmalf", 0xE7AA, z_muladd, v128f, v128f, 2>; def VMALF : TernaryVRRd<"vmalf", 0xE7AA, z_muladd, v128f, v128f, 2>;
// Multiply and add high. // Multiply and add high.
def VMAHB : TernaryVRRd<"vmahb", 0xE7AB, null_frag, v128b, v128b, 0>; def VMAHB : TernaryVRRd<"vmahb", 0xE7AB, int_s390_vmahb, v128b, v128b, 0>;
def VMAHH : TernaryVRRd<"vmahh", 0xE7AB, null_frag, v128h, v128h, 1>; def VMAHH : TernaryVRRd<"vmahh", 0xE7AB, int_s390_vmahh, v128h, v128h, 1>;
def VMAHF : TernaryVRRd<"vmahf", 0xE7AB, null_frag, v128f, v128f, 2>; def VMAHF : TernaryVRRd<"vmahf", 0xE7AB, int_s390_vmahf, v128f, v128f, 2>;
// Multiply and add logical high. // Multiply and add logical high.
def VMALHB : TernaryVRRd<"vmalhb", 0xE7A9, null_frag, v128b, v128b, 0>; def VMALHB : TernaryVRRd<"vmalhb", 0xE7A9, int_s390_vmalhb, v128b, v128b, 0>;
def VMALHH : TernaryVRRd<"vmalhh", 0xE7A9, null_frag, v128h, v128h, 1>; def VMALHH : TernaryVRRd<"vmalhh", 0xE7A9, int_s390_vmalhh, v128h, v128h, 1>;
def VMALHF : TernaryVRRd<"vmalhf", 0xE7A9, null_frag, v128f, v128f, 2>; def VMALHF : TernaryVRRd<"vmalhf", 0xE7A9, int_s390_vmalhf, v128f, v128f, 2>;
// Multiply and add even. // Multiply and add even.
def VMAEB : TernaryVRRd<"vmaeb", 0xE7AE, null_frag, v128h, v128b, 0>; def VMAEB : TernaryVRRd<"vmaeb", 0xE7AE, int_s390_vmaeb, v128h, v128b, 0>;
def VMAEH : TernaryVRRd<"vmaeh", 0xE7AE, null_frag, v128f, v128h, 1>; def VMAEH : TernaryVRRd<"vmaeh", 0xE7AE, int_s390_vmaeh, v128f, v128h, 1>;
def VMAEF : TernaryVRRd<"vmaef", 0xE7AE, null_frag, v128g, v128f, 2>; def VMAEF : TernaryVRRd<"vmaef", 0xE7AE, int_s390_vmaef, v128g, v128f, 2>;
// Multiply and add logical even. // Multiply and add logical even.
def VMALEB : TernaryVRRd<"vmaleb", 0xE7AC, null_frag, v128h, v128b, 0>; def VMALEB : TernaryVRRd<"vmaleb", 0xE7AC, int_s390_vmaleb, v128h, v128b, 0>;
def VMALEH : TernaryVRRd<"vmaleh", 0xE7AC, null_frag, v128f, v128h, 1>; def VMALEH : TernaryVRRd<"vmaleh", 0xE7AC, int_s390_vmaleh, v128f, v128h, 1>;
def VMALEF : TernaryVRRd<"vmalef", 0xE7AC, null_frag, v128g, v128f, 2>; def VMALEF : TernaryVRRd<"vmalef", 0xE7AC, int_s390_vmalef, v128g, v128f, 2>;
// Multiply and add odd. // Multiply and add odd.
def VMAOB : TernaryVRRd<"vmaob", 0xE7AF, null_frag, v128h, v128b, 0>; def VMAOB : TernaryVRRd<"vmaob", 0xE7AF, int_s390_vmaob, v128h, v128b, 0>;
def VMAOH : TernaryVRRd<"vmaoh", 0xE7AF, null_frag, v128f, v128h, 1>; def VMAOH : TernaryVRRd<"vmaoh", 0xE7AF, int_s390_vmaoh, v128f, v128h, 1>;
def VMAOF : TernaryVRRd<"vmaof", 0xE7AF, null_frag, v128g, v128f, 2>; def VMAOF : TernaryVRRd<"vmaof", 0xE7AF, int_s390_vmaof, v128g, v128f, 2>;
// Multiply and add logical odd. // Multiply and add logical odd.
def VMALOB : TernaryVRRd<"vmalob", 0xE7AD, null_frag, v128h, v128b, 0>; def VMALOB : TernaryVRRd<"vmalob", 0xE7AD, int_s390_vmalob, v128h, v128b, 0>;
def VMALOH : TernaryVRRd<"vmaloh", 0xE7AD, null_frag, v128f, v128h, 1>; def VMALOH : TernaryVRRd<"vmaloh", 0xE7AD, int_s390_vmaloh, v128f, v128h, 1>;
def VMALOF : TernaryVRRd<"vmalof", 0xE7AD, null_frag, v128g, v128f, 2>; def VMALOF : TernaryVRRd<"vmalof", 0xE7AD, int_s390_vmalof, v128g, v128f, 2>;
// Multiply high. // Multiply high.
def VMHB : BinaryVRRc<"vmhb", 0xE7A3, null_frag, v128b, v128b, 0>; def VMHB : BinaryVRRc<"vmhb", 0xE7A3, int_s390_vmhb, v128b, v128b, 0>;
def VMHH : BinaryVRRc<"vmhh", 0xE7A3, null_frag, v128h, v128h, 1>; def VMHH : BinaryVRRc<"vmhh", 0xE7A3, int_s390_vmhh, v128h, v128h, 1>;
def VMHF : BinaryVRRc<"vmhf", 0xE7A3, null_frag, v128f, v128f, 2>; def VMHF : BinaryVRRc<"vmhf", 0xE7A3, int_s390_vmhf, v128f, v128f, 2>;
// Multiply logical high. // Multiply logical high.
def VMLHB : BinaryVRRc<"vmlhb", 0xE7A1, null_frag, v128b, v128b, 0>; def VMLHB : BinaryVRRc<"vmlhb", 0xE7A1, int_s390_vmlhb, v128b, v128b, 0>;
def VMLHH : BinaryVRRc<"vmlhh", 0xE7A1, null_frag, v128h, v128h, 1>; def VMLHH : BinaryVRRc<"vmlhh", 0xE7A1, int_s390_vmlhh, v128h, v128h, 1>;
def VMLHF : BinaryVRRc<"vmlhf", 0xE7A1, null_frag, v128f, v128f, 2>; def VMLHF : BinaryVRRc<"vmlhf", 0xE7A1, int_s390_vmlhf, v128f, v128f, 2>;
// Multiply low. // Multiply low.
def VMLB : BinaryVRRc<"vmlb", 0xE7A2, mul, v128b, v128b, 0>; def VMLB : BinaryVRRc<"vmlb", 0xE7A2, mul, v128b, v128b, 0>;
@ -494,24 +497,24 @@ let Predicates = [FeatureVector] in {
def VMLF : BinaryVRRc<"vmlf", 0xE7A2, mul, v128f, v128f, 2>; def VMLF : BinaryVRRc<"vmlf", 0xE7A2, mul, v128f, v128f, 2>;
// Multiply even. // Multiply even.
def VMEB : BinaryVRRc<"vmeb", 0xE7A6, null_frag, v128h, v128b, 0>; def VMEB : BinaryVRRc<"vmeb", 0xE7A6, int_s390_vmeb, v128h, v128b, 0>;
def VMEH : BinaryVRRc<"vmeh", 0xE7A6, null_frag, v128f, v128h, 1>; def VMEH : BinaryVRRc<"vmeh", 0xE7A6, int_s390_vmeh, v128f, v128h, 1>;
def VMEF : BinaryVRRc<"vmef", 0xE7A6, null_frag, v128g, v128f, 2>; def VMEF : BinaryVRRc<"vmef", 0xE7A6, int_s390_vmef, v128g, v128f, 2>;
// Multiply logical even. // Multiply logical even.
def VMLEB : BinaryVRRc<"vmleb", 0xE7A4, null_frag, v128h, v128b, 0>; def VMLEB : BinaryVRRc<"vmleb", 0xE7A4, int_s390_vmleb, v128h, v128b, 0>;
def VMLEH : BinaryVRRc<"vmleh", 0xE7A4, null_frag, v128f, v128h, 1>; def VMLEH : BinaryVRRc<"vmleh", 0xE7A4, int_s390_vmleh, v128f, v128h, 1>;
def VMLEF : BinaryVRRc<"vmlef", 0xE7A4, null_frag, v128g, v128f, 2>; def VMLEF : BinaryVRRc<"vmlef", 0xE7A4, int_s390_vmlef, v128g, v128f, 2>;
// Multiply odd. // Multiply odd.
def VMOB : BinaryVRRc<"vmob", 0xE7A7, null_frag, v128h, v128b, 0>; def VMOB : BinaryVRRc<"vmob", 0xE7A7, int_s390_vmob, v128h, v128b, 0>;
def VMOH : BinaryVRRc<"vmoh", 0xE7A7, null_frag, v128f, v128h, 1>; def VMOH : BinaryVRRc<"vmoh", 0xE7A7, int_s390_vmoh, v128f, v128h, 1>;
def VMOF : BinaryVRRc<"vmof", 0xE7A7, null_frag, v128g, v128f, 2>; def VMOF : BinaryVRRc<"vmof", 0xE7A7, int_s390_vmof, v128g, v128f, 2>;
// Multiply logical odd. // Multiply logical odd.
def VMLOB : BinaryVRRc<"vmlob", 0xE7A5, null_frag, v128h, v128b, 0>; def VMLOB : BinaryVRRc<"vmlob", 0xE7A5, int_s390_vmlob, v128h, v128b, 0>;
def VMLOH : BinaryVRRc<"vmloh", 0xE7A5, null_frag, v128f, v128h, 1>; def VMLOH : BinaryVRRc<"vmloh", 0xE7A5, int_s390_vmloh, v128f, v128h, 1>;
def VMLOF : BinaryVRRc<"vmlof", 0xE7A5, null_frag, v128g, v128f, 2>; def VMLOF : BinaryVRRc<"vmlof", 0xE7A5, int_s390_vmlof, v128g, v128f, 2>;
// Nor. // Nor.
def VNO : BinaryVRRc<"vno", 0xE76B, null_frag, v128any, v128any>; def VNO : BinaryVRRc<"vno", 0xE76B, null_frag, v128any, v128any>;
@ -524,22 +527,26 @@ let Predicates = [FeatureVector] in {
def : Pat<(v16i8 (z_popcnt VR128:$x)), (VPOPCT VR128:$x, 0)>; def : Pat<(v16i8 (z_popcnt VR128:$x)), (VPOPCT VR128:$x, 0)>;
// Element rotate left logical (with vector shift amount). // Element rotate left logical (with vector shift amount).
def VERLLVB : BinaryVRRc<"verllvb", 0xE773, null_frag, v128b, v128b, 0>; def VERLLVB : BinaryVRRc<"verllvb", 0xE773, int_s390_verllvb,
def VERLLVH : BinaryVRRc<"verllvh", 0xE773, null_frag, v128h, v128h, 1>; v128b, v128b, 0>;
def VERLLVF : BinaryVRRc<"verllvf", 0xE773, null_frag, v128f, v128f, 2>; def VERLLVH : BinaryVRRc<"verllvh", 0xE773, int_s390_verllvh,
def VERLLVG : BinaryVRRc<"verllvg", 0xE773, null_frag, v128g, v128g, 3>; v128h, v128h, 1>;
def VERLLVF : BinaryVRRc<"verllvf", 0xE773, int_s390_verllvf,
v128f, v128f, 2>;
def VERLLVG : BinaryVRRc<"verllvg", 0xE773, int_s390_verllvg,
v128g, v128g, 3>;
// Element rotate left logical (with scalar shift amount). // Element rotate left logical (with scalar shift amount).
def VERLLB : BinaryVRSa<"verllb", 0xE733, null_frag, v128b, v128b, 0>; def VERLLB : BinaryVRSa<"verllb", 0xE733, int_s390_verllb, v128b, v128b, 0>;
def VERLLH : BinaryVRSa<"verllh", 0xE733, null_frag, v128h, v128h, 1>; def VERLLH : BinaryVRSa<"verllh", 0xE733, int_s390_verllh, v128h, v128h, 1>;
def VERLLF : BinaryVRSa<"verllf", 0xE733, null_frag, v128f, v128f, 2>; def VERLLF : BinaryVRSa<"verllf", 0xE733, int_s390_verllf, v128f, v128f, 2>;
def VERLLG : BinaryVRSa<"verllg", 0xE733, null_frag, v128g, v128g, 3>; def VERLLG : BinaryVRSa<"verllg", 0xE733, int_s390_verllg, v128g, v128g, 3>;
// Element rotate and insert under mask. // Element rotate and insert under mask.
def VERIMB : QuaternaryVRId<"verimb", 0xE772, null_frag, v128b, v128b, 0>; def VERIMB : QuaternaryVRId<"verimb", 0xE772, int_s390_verimb, v128b, v128b, 0>;
def VERIMH : QuaternaryVRId<"verimh", 0xE772, null_frag, v128h, v128h, 1>; def VERIMH : QuaternaryVRId<"verimh", 0xE772, int_s390_verimh, v128h, v128h, 1>;
def VERIMF : QuaternaryVRId<"verimf", 0xE772, null_frag, v128f, v128f, 2>; def VERIMF : QuaternaryVRId<"verimf", 0xE772, int_s390_verimf, v128f, v128f, 2>;
def VERIMG : QuaternaryVRId<"verimg", 0xE772, null_frag, v128g, v128g, 3>; def VERIMG : QuaternaryVRId<"verimg", 0xE772, int_s390_verimg, v128g, v128g, 3>;
// Element shift left (with vector shift amount). // Element shift left (with vector shift amount).
def VESLVB : BinaryVRRc<"veslvb", 0xE770, z_vshl, v128b, v128b, 0>; def VESLVB : BinaryVRRc<"veslvb", 0xE770, z_vshl, v128b, v128b, 0>;
@ -578,45 +585,48 @@ let Predicates = [FeatureVector] in {
def VESRLG : BinaryVRSa<"vesrlg", 0xE738, z_vsrl_by_scalar, v128g, v128g, 3>; def VESRLG : BinaryVRSa<"vesrlg", 0xE738, z_vsrl_by_scalar, v128g, v128g, 3>;
// Shift left. // Shift left.
def VSL : BinaryVRRc<"vsl", 0xE774, null_frag, v128b, v128b>; def VSL : BinaryVRRc<"vsl", 0xE774, int_s390_vsl, v128b, v128b>;
// Shift left by byte. // Shift left by byte.
def VSLB : BinaryVRRc<"vslb", 0xE775, null_frag, v128b, v128b>; def VSLB : BinaryVRRc<"vslb", 0xE775, int_s390_vslb, v128b, v128b>;
// Shift left double by byte. // Shift left double by byte.
def VSLDB : TernaryVRId<"vsldb", 0xE777, z_shl_double, v128b, v128b, 0>; def VSLDB : TernaryVRId<"vsldb", 0xE777, z_shl_double, v128b, v128b, 0>;
def : Pat<(int_s390_vsldb VR128:$x, VR128:$y, imm32zx8:$z),
(VSLDB VR128:$x, VR128:$y, imm32zx8:$z)>;
// Shift right arithmetic. // Shift right arithmetic.
def VSRA : BinaryVRRc<"vsra", 0xE77E, null_frag, v128b, v128b>; def VSRA : BinaryVRRc<"vsra", 0xE77E, int_s390_vsra, v128b, v128b>;
// Shift right arithmetic by byte. // Shift right arithmetic by byte.
def VSRAB : BinaryVRRc<"vsrab", 0xE77F, null_frag, v128b, v128b>; def VSRAB : BinaryVRRc<"vsrab", 0xE77F, int_s390_vsrab, v128b, v128b>;
// Shift right logical. // Shift right logical.
def VSRL : BinaryVRRc<"vsrl", 0xE77C, null_frag, v128b, v128b>; def VSRL : BinaryVRRc<"vsrl", 0xE77C, int_s390_vsrl, v128b, v128b>;
// Shift right logical by byte. // Shift right logical by byte.
def VSRLB : BinaryVRRc<"vsrlb", 0xE77D, null_frag, v128b, v128b>; def VSRLB : BinaryVRRc<"vsrlb", 0xE77D, int_s390_vsrlb, v128b, v128b>;
// Subtract. // Subtract.
def VSB : BinaryVRRc<"vsb", 0xE7F7, sub, v128b, v128b, 0>; def VSB : BinaryVRRc<"vsb", 0xE7F7, sub, v128b, v128b, 0>;
def VSH : BinaryVRRc<"vsh", 0xE7F7, sub, v128h, v128h, 1>; def VSH : BinaryVRRc<"vsh", 0xE7F7, sub, v128h, v128h, 1>;
def VSF : BinaryVRRc<"vsf", 0xE7F7, sub, v128f, v128f, 2>; def VSF : BinaryVRRc<"vsf", 0xE7F7, sub, v128f, v128f, 2>;
def VSG : BinaryVRRc<"vsg", 0xE7F7, sub, v128g, v128g, 3>; def VSG : BinaryVRRc<"vsg", 0xE7F7, sub, v128g, v128g, 3>;
def VSQ : BinaryVRRc<"vsq", 0xE7F7, null_frag, v128q, v128q, 4>; def VSQ : BinaryVRRc<"vsq", 0xE7F7, int_s390_vsq, v128q, v128q, 4>;
// Subtract compute borrow indication. // Subtract compute borrow indication.
def VSCBIB : BinaryVRRc<"vscbib", 0xE7F5, null_frag, v128b, v128b, 0>; def VSCBIB : BinaryVRRc<"vscbib", 0xE7F5, int_s390_vscbib, v128b, v128b, 0>;
def VSCBIH : BinaryVRRc<"vscbih", 0xE7F5, null_frag, v128h, v128h, 1>; def VSCBIH : BinaryVRRc<"vscbih", 0xE7F5, int_s390_vscbih, v128h, v128h, 1>;
def VSCBIF : BinaryVRRc<"vscbif", 0xE7F5, null_frag, v128f, v128f, 2>; def VSCBIF : BinaryVRRc<"vscbif", 0xE7F5, int_s390_vscbif, v128f, v128f, 2>;
def VSCBIG : BinaryVRRc<"vscbig", 0xE7F5, null_frag, v128g, v128g, 3>; def VSCBIG : BinaryVRRc<"vscbig", 0xE7F5, int_s390_vscbig, v128g, v128g, 3>;
def VSCBIQ : BinaryVRRc<"vscbiq", 0xE7F5, null_frag, v128q, v128q, 4>; def VSCBIQ : BinaryVRRc<"vscbiq", 0xE7F5, int_s390_vscbiq, v128q, v128q, 4>;
// Subtract with borrow indication. // Subtract with borrow indication.
def VSBIQ : TernaryVRRd<"vsbiq", 0xE7BF, null_frag, v128q, v128q, 4>; def VSBIQ : TernaryVRRd<"vsbiq", 0xE7BF, int_s390_vsbiq, v128q, v128q, 4>;
// Subtract with borrow compute borrow indication. // Subtract with borrow compute borrow indication.
def VSBCBIQ : TernaryVRRd<"vsbcbiq", 0xE7BD, null_frag, v128q, v128q, 4>; def VSBCBIQ : TernaryVRRd<"vsbcbiq", 0xE7BD, int_s390_vsbcbiq,
v128q, v128q, 4>;
// Sum across doubleword. // Sum across doubleword.
def VSUMGH : BinaryVRRc<"vsumgh", 0xE765, z_vsum, v128g, v128h, 1>; def VSUMGH : BinaryVRRc<"vsumgh", 0xE765, z_vsum, v128g, v128h, 1>;
@ -742,38 +752,38 @@ let Predicates = [FeatureVector] in {
} }
// Compare equal. // Compare equal.
defm VCEQB : BinaryVRRbSPair<"vceqb", 0xE7F8, z_vicmpe, null_frag, defm VCEQB : BinaryVRRbSPair<"vceqb", 0xE7F8, z_vicmpe, z_vicmpes,
v128b, v128b, 0>; v128b, v128b, 0>;
defm VCEQH : BinaryVRRbSPair<"vceqh", 0xE7F8, z_vicmpe, null_frag, defm VCEQH : BinaryVRRbSPair<"vceqh", 0xE7F8, z_vicmpe, z_vicmpes,
v128h, v128h, 1>; v128h, v128h, 1>;
defm VCEQF : BinaryVRRbSPair<"vceqf", 0xE7F8, z_vicmpe, null_frag, defm VCEQF : BinaryVRRbSPair<"vceqf", 0xE7F8, z_vicmpe, z_vicmpes,
v128f, v128f, 2>; v128f, v128f, 2>;
defm VCEQG : BinaryVRRbSPair<"vceqg", 0xE7F8, z_vicmpe, null_frag, defm VCEQG : BinaryVRRbSPair<"vceqg", 0xE7F8, z_vicmpe, z_vicmpes,
v128g, v128g, 3>; v128g, v128g, 3>;
// Compare high. // Compare high.
defm VCHB : BinaryVRRbSPair<"vchb", 0xE7FB, z_vicmph, null_frag, defm VCHB : BinaryVRRbSPair<"vchb", 0xE7FB, z_vicmph, z_vicmphs,
v128b, v128b, 0>; v128b, v128b, 0>;
defm VCHH : BinaryVRRbSPair<"vchh", 0xE7FB, z_vicmph, null_frag, defm VCHH : BinaryVRRbSPair<"vchh", 0xE7FB, z_vicmph, z_vicmphs,
v128h, v128h, 1>; v128h, v128h, 1>;
defm VCHF : BinaryVRRbSPair<"vchf", 0xE7FB, z_vicmph, null_frag, defm VCHF : BinaryVRRbSPair<"vchf", 0xE7FB, z_vicmph, z_vicmphs,
v128f, v128f, 2>; v128f, v128f, 2>;
defm VCHG : BinaryVRRbSPair<"vchg", 0xE7FB, z_vicmph, null_frag, defm VCHG : BinaryVRRbSPair<"vchg", 0xE7FB, z_vicmph, z_vicmphs,
v128g, v128g, 3>; v128g, v128g, 3>;
// Compare high logical. // Compare high logical.
defm VCHLB : BinaryVRRbSPair<"vchlb", 0xE7F9, z_vicmphl, null_frag, defm VCHLB : BinaryVRRbSPair<"vchlb", 0xE7F9, z_vicmphl, z_vicmphls,
v128b, v128b, 0>; v128b, v128b, 0>;
defm VCHLH : BinaryVRRbSPair<"vchlh", 0xE7F9, z_vicmphl, null_frag, defm VCHLH : BinaryVRRbSPair<"vchlh", 0xE7F9, z_vicmphl, z_vicmphls,
v128h, v128h, 1>; v128h, v128h, 1>;
defm VCHLF : BinaryVRRbSPair<"vchlf", 0xE7F9, z_vicmphl, null_frag, defm VCHLF : BinaryVRRbSPair<"vchlf", 0xE7F9, z_vicmphl, z_vicmphls,
v128f, v128f, 2>; v128f, v128f, 2>;
defm VCHLG : BinaryVRRbSPair<"vchlg", 0xE7F9, z_vicmphl, null_frag, defm VCHLG : BinaryVRRbSPair<"vchlg", 0xE7F9, z_vicmphl, z_vicmphls,
v128g, v128g, 3>; v128g, v128g, 3>;
// Test under mask. // Test under mask.
let Defs = [CC] in let Defs = [CC] in
def VTM : CompareVRRa<"vtm", 0xE7D8, null_frag, v128any, 0>; def VTM : CompareVRRa<"vtm", 0xE7D8, z_vtm, v128b, 0>;
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -823,7 +833,7 @@ let Predicates = [FeatureVector] in {
def WFDDB : BinaryVRRc<"wfddb", 0xE7E5, fdiv, v64db, v64db, 3, 8>; def WFDDB : BinaryVRRc<"wfddb", 0xE7E5, fdiv, v64db, v64db, 3, 8>;
// Load FP integer. // Load FP integer.
def VFIDB : TernaryVRRa<"vfidb", 0xE7C7, null_frag, v128db, v128db, 3, 0>; def VFIDB : TernaryVRRa<"vfidb", 0xE7C7, int_s390_vfidb, v128db, v128db, 3, 0>;
def WFIDB : TernaryVRRa<"wfidb", 0xE7C7, null_frag, v64db, v64db, 3, 8>; def WFIDB : TernaryVRRa<"wfidb", 0xE7C7, null_frag, v64db, v64db, 3, 8>;
defm : VectorRounding<VFIDB, v128db>; defm : VectorRounding<VFIDB, v128db>;
defm : VectorRounding<WFIDB, v64db>; defm : VectorRounding<WFIDB, v64db>;
@ -872,7 +882,7 @@ let Predicates = [FeatureVector] in {
// Test data class immediate. // Test data class immediate.
let Defs = [CC] in { let Defs = [CC] in {
def VFTCIDB : BinaryVRIe<"vftcidb", 0xE74A, null_frag, v128g, v128db, 3, 0>; def VFTCIDB : BinaryVRIe<"vftcidb", 0xE74A, z_vftci, v128g, v128db, 3, 0>;
def WFTCIDB : BinaryVRIe<"wftcidb", 0xE74A, null_frag, v64g, v64db, 3, 8>; def WFTCIDB : BinaryVRIe<"wftcidb", 0xE74A, null_frag, v64g, v64db, 3, 8>;
} }
} }
@ -891,19 +901,19 @@ let Predicates = [FeatureVector] in {
def WFKDB : CompareVRRa<"wfkdb", 0xE7CA, null_frag, v64db, 3>; def WFKDB : CompareVRRa<"wfkdb", 0xE7CA, null_frag, v64db, 3>;
// Compare equal. // Compare equal.
defm VFCEDB : BinaryVRRcSPair<"vfcedb", 0xE7E8, z_vfcmpe, null_frag, defm VFCEDB : BinaryVRRcSPair<"vfcedb", 0xE7E8, z_vfcmpe, z_vfcmpes,
v128g, v128db, 3, 0>; v128g, v128db, 3, 0>;
defm WFCEDB : BinaryVRRcSPair<"wfcedb", 0xE7E8, null_frag, null_frag, defm WFCEDB : BinaryVRRcSPair<"wfcedb", 0xE7E8, null_frag, null_frag,
v64g, v64db, 3, 8>; v64g, v64db, 3, 8>;
// Compare high. // Compare high.
defm VFCHDB : BinaryVRRcSPair<"vfchdb", 0xE7EB, z_vfcmph, null_frag, defm VFCHDB : BinaryVRRcSPair<"vfchdb", 0xE7EB, z_vfcmph, z_vfcmphs,
v128g, v128db, 3, 0>; v128g, v128db, 3, 0>;
defm WFCHDB : BinaryVRRcSPair<"wfchdb", 0xE7EB, null_frag, null_frag, defm WFCHDB : BinaryVRRcSPair<"wfchdb", 0xE7EB, null_frag, null_frag,
v64g, v64db, 3, 8>; v64g, v64db, 3, 8>;
// Compare high or equal. // Compare high or equal.
defm VFCHEDB : BinaryVRRcSPair<"vfchedb", 0xE7EA, z_vfcmphe, null_frag, defm VFCHEDB : BinaryVRRcSPair<"vfchedb", 0xE7EA, z_vfcmphe, z_vfcmphes,
v128g, v128db, 3, 0>; v128g, v128db, 3, 0>;
defm WFCHEDB : BinaryVRRcSPair<"wfchedb", 0xE7EA, null_frag, null_frag, defm WFCHEDB : BinaryVRRcSPair<"wfchedb", 0xE7EA, null_frag, null_frag,
v64g, v64db, 3, 8>; v64g, v64db, 3, 8>;
@ -1026,62 +1036,62 @@ let AddedComplexity = 4 in {
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
let Predicates = [FeatureVector] in { let Predicates = [FeatureVector] in {
defm VFAEB : TernaryVRRbSPair<"vfaeb", 0xE782, null_frag, null_frag, defm VFAEB : TernaryVRRbSPair<"vfaeb", 0xE782, int_s390_vfaeb, z_vfae_cc,
v128b, v128b, 0, 0>; v128b, v128b, 0, 0>;
defm VFAEH : TernaryVRRbSPair<"vfaeh", 0xE782, null_frag, null_frag, defm VFAEH : TernaryVRRbSPair<"vfaeh", 0xE782, int_s390_vfaeh, z_vfae_cc,
v128h, v128h, 1, 0>; v128h, v128h, 1, 0>;
defm VFAEF : TernaryVRRbSPair<"vfaef", 0xE782, null_frag, null_frag, defm VFAEF : TernaryVRRbSPair<"vfaef", 0xE782, int_s390_vfaef, z_vfae_cc,
v128f, v128f, 2, 0>; v128f, v128f, 2, 0>;
defm VFAEZB : TernaryVRRbSPair<"vfaezb", 0xE782, null_frag, null_frag, defm VFAEZB : TernaryVRRbSPair<"vfaezb", 0xE782, int_s390_vfaezb, z_vfaez_cc,
v128b, v128b, 0, 2>; v128b, v128b, 0, 2>;
defm VFAEZH : TernaryVRRbSPair<"vfaezh", 0xE782, null_frag, null_frag, defm VFAEZH : TernaryVRRbSPair<"vfaezh", 0xE782, int_s390_vfaezh, z_vfaez_cc,
v128h, v128h, 1, 2>; v128h, v128h, 1, 2>;
defm VFAEZF : TernaryVRRbSPair<"vfaezf", 0xE782, null_frag, null_frag, defm VFAEZF : TernaryVRRbSPair<"vfaezf", 0xE782, int_s390_vfaezf, z_vfaez_cc,
v128f, v128f, 2, 2>; v128f, v128f, 2, 2>;
defm VFEEB : BinaryVRRbSPair<"vfeeb", 0xE780, null_frag, null_frag, defm VFEEB : BinaryVRRbSPair<"vfeeb", 0xE780, int_s390_vfeeb, z_vfee_cc,
v128b, v128b, 0, 0, 1>; v128b, v128b, 0, 0, 1>;
defm VFEEH : BinaryVRRbSPair<"vfeeh", 0xE780, null_frag, null_frag, defm VFEEH : BinaryVRRbSPair<"vfeeh", 0xE780, int_s390_vfeeh, z_vfee_cc,
v128h, v128h, 1, 0, 1>; v128h, v128h, 1, 0, 1>;
defm VFEEF : BinaryVRRbSPair<"vfeef", 0xE780, null_frag, null_frag, defm VFEEF : BinaryVRRbSPair<"vfeef", 0xE780, int_s390_vfeef, z_vfee_cc,
v128f, v128f, 2, 0, 1>; v128f, v128f, 2, 0, 1>;
defm VFEEZB : BinaryVRRbSPair<"vfeezb", 0xE780, null_frag, null_frag, defm VFEEZB : BinaryVRRbSPair<"vfeezb", 0xE780, int_s390_vfeezb, z_vfeez_cc,
v128b, v128b, 0, 2, 3>; v128b, v128b, 0, 2, 3>;
defm VFEEZH : BinaryVRRbSPair<"vfeezh", 0xE780, null_frag, null_frag, defm VFEEZH : BinaryVRRbSPair<"vfeezh", 0xE780, int_s390_vfeezh, z_vfeez_cc,
v128h, v128h, 1, 2, 3>; v128h, v128h, 1, 2, 3>;
defm VFEEZF : BinaryVRRbSPair<"vfeezf", 0xE780, null_frag, null_frag, defm VFEEZF : BinaryVRRbSPair<"vfeezf", 0xE780, int_s390_vfeezf, z_vfeez_cc,
v128f, v128f, 2, 2, 3>; v128f, v128f, 2, 2, 3>;
defm VFENEB : BinaryVRRbSPair<"vfeneb", 0xE781, null_frag, null_frag, defm VFENEB : BinaryVRRbSPair<"vfeneb", 0xE781, int_s390_vfeneb, z_vfene_cc,
v128b, v128b, 0, 0, 1>; v128b, v128b, 0, 0, 1>;
defm VFENEH : BinaryVRRbSPair<"vfeneh", 0xE781, null_frag, null_frag, defm VFENEH : BinaryVRRbSPair<"vfeneh", 0xE781, int_s390_vfeneh, z_vfene_cc,
v128h, v128h, 1, 0, 1>; v128h, v128h, 1, 0, 1>;
defm VFENEF : BinaryVRRbSPair<"vfenef", 0xE781, null_frag, null_frag, defm VFENEF : BinaryVRRbSPair<"vfenef", 0xE781, int_s390_vfenef, z_vfene_cc,
v128f, v128f, 2, 0, 1>; v128f, v128f, 2, 0, 1>;
defm VFENEZB : BinaryVRRbSPair<"vfenezb", 0xE781, null_frag, null_frag, defm VFENEZB : BinaryVRRbSPair<"vfenezb", 0xE781, int_s390_vfenezb,
v128b, v128b, 0, 2, 3>; z_vfenez_cc, v128b, v128b, 0, 2, 3>;
defm VFENEZH : BinaryVRRbSPair<"vfenezh", 0xE781, null_frag, null_frag, defm VFENEZH : BinaryVRRbSPair<"vfenezh", 0xE781, int_s390_vfenezh,
v128h, v128h, 1, 2, 3>; z_vfenez_cc, v128h, v128h, 1, 2, 3>;
defm VFENEZF : BinaryVRRbSPair<"vfenezf", 0xE781, null_frag, null_frag, defm VFENEZF : BinaryVRRbSPair<"vfenezf", 0xE781, int_s390_vfenezf,
v128f, v128f, 2, 2, 3>; z_vfenez_cc, v128f, v128f, 2, 2, 3>;
defm VISTRB : UnaryVRRaSPair<"vistrb", 0xE75C, null_frag, null_frag, defm VISTRB : UnaryVRRaSPair<"vistrb", 0xE75C, int_s390_vistrb, z_vistr_cc,
v128b, v128b, 0>; v128b, v128b, 0>;
defm VISTRH : UnaryVRRaSPair<"vistrh", 0xE75C, null_frag, null_frag, defm VISTRH : UnaryVRRaSPair<"vistrh", 0xE75C, int_s390_vistrh, z_vistr_cc,
v128h, v128h, 1>; v128h, v128h, 1>;
defm VISTRF : UnaryVRRaSPair<"vistrf", 0xE75C, null_frag, null_frag, defm VISTRF : UnaryVRRaSPair<"vistrf", 0xE75C, int_s390_vistrf, z_vistr_cc,
v128f, v128f, 2>; v128f, v128f, 2>;
defm VSTRCB : QuaternaryVRRdSPair<"vstrcb", 0xE78A, null_frag, null_frag, defm VSTRCB : QuaternaryVRRdSPair<"vstrcb", 0xE78A, int_s390_vstrcb,
v128b, v128b, 0, 0>; z_vstrc_cc, v128b, v128b, 0, 0>;
defm VSTRCH : QuaternaryVRRdSPair<"vstrch", 0xE78A, null_frag, null_frag, defm VSTRCH : QuaternaryVRRdSPair<"vstrch", 0xE78A, int_s390_vstrch,
v128h, v128h, 1, 0>; z_vstrc_cc, v128h, v128h, 1, 0>;
defm VSTRCF : QuaternaryVRRdSPair<"vstrcf", 0xE78A, null_frag, null_frag, defm VSTRCF : QuaternaryVRRdSPair<"vstrcf", 0xE78A, int_s390_vstrcf,
v128f, v128f, 2, 0>; z_vstrc_cc, v128f, v128f, 2, 0>;
defm VSTRCZB : QuaternaryVRRdSPair<"vstrczb", 0xE78A, null_frag, null_frag, defm VSTRCZB : QuaternaryVRRdSPair<"vstrczb", 0xE78A, int_s390_vstrczb,
v128b, v128b, 0, 2>; z_vstrcz_cc, v128b, v128b, 0, 2>;
defm VSTRCZH : QuaternaryVRRdSPair<"vstrczh", 0xE78A, null_frag, null_frag, defm VSTRCZH : QuaternaryVRRdSPair<"vstrczh", 0xE78A, int_s390_vstrczh,
v128h, v128h, 1, 2>; z_vstrcz_cc, v128h, v128h, 1, 2>;
defm VSTRCZF : QuaternaryVRRdSPair<"vstrczf", 0xE78A, null_frag, null_frag, defm VSTRCZF : QuaternaryVRRdSPair<"vstrczf", 0xE78A, int_s390_vstrczf,
v128f, v128f, 2, 2>; z_vstrcz_cc, v128f, v128f, 2, 2>;
} }

View File

@ -94,6 +94,9 @@ def SDT_ZReplicate : SDTypeProfile<1, 1,
def SDT_ZVecUnaryConv : SDTypeProfile<1, 1, def SDT_ZVecUnaryConv : SDTypeProfile<1, 1,
[SDTCisVec<0>, [SDTCisVec<0>,
SDTCisVec<1>]>; SDTCisVec<1>]>;
def SDT_ZVecUnary : SDTypeProfile<1, 1,
[SDTCisVec<0>,
SDTCisSameAs<0, 1>]>;
def SDT_ZVecBinary : SDTypeProfile<1, 2, def SDT_ZVecBinary : SDTypeProfile<1, 2,
[SDTCisVec<0>, [SDTCisVec<0>,
SDTCisSameAs<0, 1>, SDTCisSameAs<0, 1>,
@ -106,6 +109,10 @@ def SDT_ZVecBinaryConv : SDTypeProfile<1, 2,
[SDTCisVec<0>, [SDTCisVec<0>,
SDTCisVec<1>, SDTCisVec<1>,
SDTCisSameAs<1, 2>]>; SDTCisSameAs<1, 2>]>;
def SDT_ZVecBinaryConvInt : SDTypeProfile<1, 2,
[SDTCisVec<0>,
SDTCisVec<1>,
SDTCisVT<2, i32>]>;
def SDT_ZRotateMask : SDTypeProfile<1, 2, def SDT_ZRotateMask : SDTypeProfile<1, 2,
[SDTCisVec<0>, [SDTCisVec<0>,
SDTCisVT<1, i32>, SDTCisVT<1, i32>,
@ -124,6 +131,12 @@ def SDT_ZVecTernaryInt : SDTypeProfile<1, 3,
SDTCisSameAs<0, 1>, SDTCisSameAs<0, 1>,
SDTCisSameAs<0, 2>, SDTCisSameAs<0, 2>,
SDTCisVT<3, i32>]>; SDTCisVT<3, i32>]>;
def SDT_ZVecQuaternaryInt : SDTypeProfile<1, 4,
[SDTCisVec<0>,
SDTCisSameAs<0, 1>,
SDTCisSameAs<0, 2>,
SDTCisSameAs<0, 3>,
SDTCisVT<4, i32>]>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Node definitions // Node definitions
@ -193,6 +206,10 @@ def z_permute_dwords : SDNode<"SystemZISD::PERMUTE_DWORDS",
SDT_ZVecTernaryInt>; SDT_ZVecTernaryInt>;
def z_permute : SDNode<"SystemZISD::PERMUTE", SDT_ZVecTernary>; def z_permute : SDNode<"SystemZISD::PERMUTE", SDT_ZVecTernary>;
def z_pack : SDNode<"SystemZISD::PACK", SDT_ZVecBinaryConv>; def z_pack : SDNode<"SystemZISD::PACK", SDT_ZVecBinaryConv>;
def z_packs_cc : SDNode<"SystemZISD::PACKS_CC", SDT_ZVecBinaryConv,
[SDNPOutGlue]>;
def z_packls_cc : SDNode<"SystemZISD::PACKLS_CC", SDT_ZVecBinaryConv,
[SDNPOutGlue]>;
def z_unpack_high : SDNode<"SystemZISD::UNPACK_HIGH", SDT_ZVecUnaryConv>; def z_unpack_high : SDNode<"SystemZISD::UNPACK_HIGH", SDT_ZVecUnaryConv>;
def z_unpackl_high : SDNode<"SystemZISD::UNPACKL_HIGH", SDT_ZVecUnaryConv>; def z_unpackl_high : SDNode<"SystemZISD::UNPACKL_HIGH", SDT_ZVecUnaryConv>;
def z_unpack_low : SDNode<"SystemZISD::UNPACK_LOW", SDT_ZVecUnaryConv>; def z_unpack_low : SDNode<"SystemZISD::UNPACK_LOW", SDT_ZVecUnaryConv>;
@ -207,11 +224,44 @@ def z_vsum : SDNode<"SystemZISD::VSUM", SDT_ZVecBinaryConv>;
def z_vicmpe : SDNode<"SystemZISD::VICMPE", SDT_ZVecBinary>; def z_vicmpe : SDNode<"SystemZISD::VICMPE", SDT_ZVecBinary>;
def z_vicmph : SDNode<"SystemZISD::VICMPH", SDT_ZVecBinary>; def z_vicmph : SDNode<"SystemZISD::VICMPH", SDT_ZVecBinary>;
def z_vicmphl : SDNode<"SystemZISD::VICMPHL", SDT_ZVecBinary>; def z_vicmphl : SDNode<"SystemZISD::VICMPHL", SDT_ZVecBinary>;
def z_vicmpes : SDNode<"SystemZISD::VICMPES", SDT_ZVecBinary,
[SDNPOutGlue]>;
def z_vicmphs : SDNode<"SystemZISD::VICMPHS", SDT_ZVecBinary,
[SDNPOutGlue]>;
def z_vicmphls : SDNode<"SystemZISD::VICMPHLS", SDT_ZVecBinary,
[SDNPOutGlue]>;
def z_vfcmpe : SDNode<"SystemZISD::VFCMPE", SDT_ZVecBinaryConv>; def z_vfcmpe : SDNode<"SystemZISD::VFCMPE", SDT_ZVecBinaryConv>;
def z_vfcmph : SDNode<"SystemZISD::VFCMPH", SDT_ZVecBinaryConv>; def z_vfcmph : SDNode<"SystemZISD::VFCMPH", SDT_ZVecBinaryConv>;
def z_vfcmphe : SDNode<"SystemZISD::VFCMPHE", SDT_ZVecBinaryConv>; def z_vfcmphe : SDNode<"SystemZISD::VFCMPHE", SDT_ZVecBinaryConv>;
def z_vfcmpes : SDNode<"SystemZISD::VFCMPES", SDT_ZVecBinaryConv,
[SDNPOutGlue]>;
def z_vfcmphs : SDNode<"SystemZISD::VFCMPHS", SDT_ZVecBinaryConv,
[SDNPOutGlue]>;
def z_vfcmphes : SDNode<"SystemZISD::VFCMPHES", SDT_ZVecBinaryConv,
[SDNPOutGlue]>;
def z_vextend : SDNode<"SystemZISD::VEXTEND", SDT_ZVecUnaryConv>; def z_vextend : SDNode<"SystemZISD::VEXTEND", SDT_ZVecUnaryConv>;
def z_vround : SDNode<"SystemZISD::VROUND", SDT_ZVecUnaryConv>; def z_vround : SDNode<"SystemZISD::VROUND", SDT_ZVecUnaryConv>;
def z_vtm : SDNode<"SystemZISD::VTM", SDT_ZCmp, [SDNPOutGlue]>;
def z_vfae_cc : SDNode<"SystemZISD::VFAE_CC", SDT_ZVecTernaryInt,
[SDNPOutGlue]>;
def z_vfaez_cc : SDNode<"SystemZISD::VFAEZ_CC", SDT_ZVecTernaryInt,
[SDNPOutGlue]>;
def z_vfee_cc : SDNode<"SystemZISD::VFEE_CC", SDT_ZVecBinary,
[SDNPOutGlue]>;
def z_vfeez_cc : SDNode<"SystemZISD::VFEEZ_CC", SDT_ZVecBinary,
[SDNPOutGlue]>;
def z_vfene_cc : SDNode<"SystemZISD::VFENE_CC", SDT_ZVecBinary,
[SDNPOutGlue]>;
def z_vfenez_cc : SDNode<"SystemZISD::VFENEZ_CC", SDT_ZVecBinary,
[SDNPOutGlue]>;
def z_vistr_cc : SDNode<"SystemZISD::VISTR_CC", SDT_ZVecUnary,
[SDNPOutGlue]>;
def z_vstrc_cc : SDNode<"SystemZISD::VSTRC_CC", SDT_ZVecQuaternaryInt,
[SDNPOutGlue]>;
def z_vstrcz_cc : SDNode<"SystemZISD::VSTRCZ_CC",
SDT_ZVecQuaternaryInt, [SDNPOutGlue]>;
def z_vftci : SDNode<"SystemZISD::VFTCI", SDT_ZVecBinaryConvInt,
[SDNPOutGlue]>;
class AtomicWOp<string name, SDTypeProfile profile = SDT_ZAtomicLoadBinaryW> class AtomicWOp<string name, SDTypeProfile profile = SDT_ZAtomicLoadBinaryW>
: SDNode<"SystemZISD::"##name, profile, : SDNode<"SystemZISD::"##name, profile,

File diff suppressed because it is too large Load Diff