forked from OSchip/llvm-project
[SystemZ] Model floating-point control register
This adds the FPC (floating-point control register) as a reserved physical register and models its use by SystemZ instructions. Note that only the current rounding modes and the IEEE exception masks are modeled. *Changes* of the FPC due to exceptions (in particular the IEEE exception flags and the DXC) are not modeled. At this point, this patch is mostly NFC, but it will prevent scheduling of floating-point instructions across SPFC/LFPC etc. llvm-svn: 360570
This commit is contained in:
parent
869f934d19
commit
8e42f6ddc8
|
|
@ -19,7 +19,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Load and test.
|
||||
let Defs = [CC] in {
|
||||
let Uses = [FPC], Defs = [CC] in {
|
||||
def LTDTR : UnaryRRE<"ltdtr", 0xB3D6, null_frag, FP64, FP64>;
|
||||
def LTXTR : UnaryRRE<"ltxtr", 0xB3DE, null_frag, FP128, FP128>;
|
||||
}
|
||||
|
|
@ -31,25 +31,31 @@ let Defs = [CC] in {
|
|||
|
||||
// Convert floating-point values to narrower representations. The destination
|
||||
// of LDXTR is a 128-bit value, but only the first register of the pair is used.
|
||||
def LEDTR : TernaryRRFe<"ledtr", 0xB3D5, FP32, FP64>;
|
||||
def LDXTR : TernaryRRFe<"ldxtr", 0xB3DD, FP128, FP128>;
|
||||
let Uses = [FPC] in {
|
||||
def LEDTR : TernaryRRFe<"ledtr", 0xB3D5, FP32, FP64>;
|
||||
def LDXTR : TernaryRRFe<"ldxtr", 0xB3DD, FP128, FP128>;
|
||||
}
|
||||
|
||||
// Extend floating-point values to wider representations.
|
||||
def LDETR : BinaryRRFd<"ldetr", 0xB3D4, FP64, FP32>;
|
||||
def LXDTR : BinaryRRFd<"lxdtr", 0xB3DC, FP128, FP64>;
|
||||
let Uses = [FPC] in {
|
||||
def LDETR : BinaryRRFd<"ldetr", 0xB3D4, FP64, FP32>;
|
||||
def LXDTR : BinaryRRFd<"lxdtr", 0xB3DC, FP128, FP64>;
|
||||
}
|
||||
|
||||
// Convert a signed integer value to a floating-point one.
|
||||
def CDGTR : UnaryRRE<"cdgtr", 0xB3F1, null_frag, FP64, GR64>;
|
||||
def CXGTR : UnaryRRE<"cxgtr", 0xB3F9, null_frag, FP128, GR64>;
|
||||
let Predicates = [FeatureFPExtension] in {
|
||||
let Uses = [FPC] in {
|
||||
def CDGTR : UnaryRRE<"cdgtr", 0xB3F1, null_frag, FP64, GR64>;
|
||||
def CXGTR : UnaryRRE<"cxgtr", 0xB3F9, null_frag, FP128, GR64>;
|
||||
let Predicates = [FeatureFPExtension] in {
|
||||
def CDGTRA : TernaryRRFe<"cdgtra", 0xB3F1, FP64, GR64>;
|
||||
def CXGTRA : TernaryRRFe<"cxgtra", 0xB3F9, FP128, GR64>;
|
||||
def CDFTR : TernaryRRFe<"cdftr", 0xB951, FP64, GR32>;
|
||||
def CXFTR : TernaryRRFe<"cxftr", 0xB959, FP128, GR32>;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert an unsigned integer value to a floating-point one.
|
||||
let Predicates = [FeatureFPExtension] in {
|
||||
let Uses = [FPC], Predicates = [FeatureFPExtension] in {
|
||||
def CDLGTR : TernaryRRFe<"cdlgtr", 0xB952, FP64, GR64>;
|
||||
def CXLGTR : TernaryRRFe<"cxlgtr", 0xB95A, FP128, GR64>;
|
||||
def CDLFTR : TernaryRRFe<"cdlftr", 0xB953, FP64, GR32>;
|
||||
|
|
@ -57,7 +63,7 @@ let Predicates = [FeatureFPExtension] in {
|
|||
}
|
||||
|
||||
// Convert a floating-point value to a signed integer value.
|
||||
let Defs = [CC] in {
|
||||
let Uses = [FPC], Defs = [CC] in {
|
||||
def CGDTR : BinaryRRFe<"cgdtr", 0xB3E1, GR64, FP64>;
|
||||
def CGXTR : BinaryRRFe<"cgxtr", 0xB3E9, GR64, FP128>;
|
||||
let Predicates = [FeatureFPExtension] in {
|
||||
|
|
@ -69,7 +75,7 @@ let Defs = [CC] in {
|
|||
}
|
||||
|
||||
// Convert a floating-point value to an unsigned integer value.
|
||||
let Defs = [CC] in {
|
||||
let Uses = [FPC], Defs = [CC] in {
|
||||
let Predicates = [FeatureFPExtension] in {
|
||||
def CLGDTR : TernaryRRFe<"clgdtr", 0xB942, GR64, FP64>;
|
||||
def CLGXTR : TernaryRRFe<"clgxtr", 0xB94A, GR64, FP128>;
|
||||
|
|
@ -107,7 +113,7 @@ let Predicates = [FeatureDFPPackedConversion] in {
|
|||
}
|
||||
|
||||
// Perform floating-point operation.
|
||||
let Defs = [CC, R1L, F0Q], Uses = [R0L, F4Q] in
|
||||
let Defs = [CC, R1L, F0Q], Uses = [FPC, R0L, F4Q] in
|
||||
def PFPO : SideEffectInherentE<"pfpo", 0x010A>;
|
||||
|
||||
|
||||
|
|
@ -117,8 +123,10 @@ let Defs = [CC, R1L, F0Q], Uses = [R0L, F4Q] in
|
|||
|
||||
// Round to an integer, with the second operand (M3) specifying the rounding
|
||||
// mode. M4 can be set to 4 to suppress detection of inexact conditions.
|
||||
def FIDTR : TernaryRRFe<"fidtr", 0xB3D7, FP64, FP64>;
|
||||
def FIXTR : TernaryRRFe<"fixtr", 0xB3DF, FP128, FP128>;
|
||||
let Uses = [FPC] in {
|
||||
def FIDTR : TernaryRRFe<"fidtr", 0xB3D7, FP64, FP64>;
|
||||
def FIXTR : TernaryRRFe<"fixtr", 0xB3DF, FP128, FP128>;
|
||||
}
|
||||
|
||||
// Extract biased exponent.
|
||||
def EEDTR : UnaryRRE<"eedtr", 0xB3E5, null_frag, FP64, FP64>;
|
||||
|
|
@ -134,7 +142,7 @@ def ESXTR : UnaryRRE<"esxtr", 0xB3EF, null_frag, FP128, FP128>;
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Addition.
|
||||
let Defs = [CC] in {
|
||||
let Uses = [FPC], Defs = [CC] in {
|
||||
let isCommutable = 1 in {
|
||||
def ADTR : BinaryRRFa<"adtr", 0xB3D2, null_frag, FP64, FP64, FP64>;
|
||||
def AXTR : BinaryRRFa<"axtr", 0xB3DA, null_frag, FP128, FP128, FP128>;
|
||||
|
|
@ -146,7 +154,7 @@ let Defs = [CC] in {
|
|||
}
|
||||
|
||||
// Subtraction.
|
||||
let Defs = [CC] in {
|
||||
let Uses = [FPC], Defs = [CC] in {
|
||||
def SDTR : BinaryRRFa<"sdtr", 0xB3D3, null_frag, FP64, FP64, FP64>;
|
||||
def SXTR : BinaryRRFa<"sxtr", 0xB3DB, null_frag, FP128, FP128, FP128>;
|
||||
let Predicates = [FeatureFPExtension] in {
|
||||
|
|
@ -156,30 +164,38 @@ let Defs = [CC] in {
|
|||
}
|
||||
|
||||
// Multiplication.
|
||||
let isCommutable = 1 in {
|
||||
let Uses = [FPC] in {
|
||||
let isCommutable = 1 in {
|
||||
def MDTR : BinaryRRFa<"mdtr", 0xB3D0, null_frag, FP64, FP64, FP64>;
|
||||
def MXTR : BinaryRRFa<"mxtr", 0xB3D8, null_frag, FP128, FP128, FP128>;
|
||||
}
|
||||
let Predicates = [FeatureFPExtension] in {
|
||||
}
|
||||
let Predicates = [FeatureFPExtension] in {
|
||||
def MDTRA : TernaryRRFa<"mdtra", 0xB3D0, FP64, FP64, FP64>;
|
||||
def MXTRA : TernaryRRFa<"mxtra", 0xB3D8, FP128, FP128, FP128>;
|
||||
}
|
||||
}
|
||||
|
||||
// Division.
|
||||
def DDTR : BinaryRRFa<"ddtr", 0xB3D1, null_frag, FP64, FP64, FP64>;
|
||||
def DXTR : BinaryRRFa<"dxtr", 0xB3D9, null_frag, FP128, FP128, FP128>;
|
||||
let Predicates = [FeatureFPExtension] in {
|
||||
let Uses = [FPC] in {
|
||||
def DDTR : BinaryRRFa<"ddtr", 0xB3D1, null_frag, FP64, FP64, FP64>;
|
||||
def DXTR : BinaryRRFa<"dxtr", 0xB3D9, null_frag, FP128, FP128, FP128>;
|
||||
let Predicates = [FeatureFPExtension] in {
|
||||
def DDTRA : TernaryRRFa<"ddtra", 0xB3D1, FP64, FP64, FP64>;
|
||||
def DXTRA : TernaryRRFa<"dxtra", 0xB3D9, FP128, FP128, FP128>;
|
||||
}
|
||||
}
|
||||
|
||||
// Quantize.
|
||||
def QADTR : TernaryRRFb<"qadtr", 0xB3F5, FP64, FP64, FP64>;
|
||||
def QAXTR : TernaryRRFb<"qaxtr", 0xB3FD, FP128, FP128, FP128>;
|
||||
let Uses = [FPC] in {
|
||||
def QADTR : TernaryRRFb<"qadtr", 0xB3F5, FP64, FP64, FP64>;
|
||||
def QAXTR : TernaryRRFb<"qaxtr", 0xB3FD, FP128, FP128, FP128>;
|
||||
}
|
||||
|
||||
// Reround.
|
||||
def RRDTR : TernaryRRFb<"rrdtr", 0xB3F7, FP64, FP64, FP64>;
|
||||
def RRXTR : TernaryRRFb<"rrxtr", 0xB3FF, FP128, FP128, FP128>;
|
||||
let Uses = [FPC] in {
|
||||
def RRDTR : TernaryRRFb<"rrdtr", 0xB3F7, FP64, FP64, FP64>;
|
||||
def RRXTR : TernaryRRFb<"rrxtr", 0xB3FF, FP128, FP128, FP128>;
|
||||
}
|
||||
|
||||
// Shift significand left/right.
|
||||
def SLDT : BinaryRXF<"sldt", 0xED40, null_frag, FP64, FP64, null_frag, 0>;
|
||||
|
|
@ -197,13 +213,13 @@ def IEXTR : BinaryRRFb<"iextr", 0xB3FE, null_frag, FP128, FP128, FP128>;
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Compare.
|
||||
let Defs = [CC] in {
|
||||
let Uses = [FPC], Defs = [CC] in {
|
||||
def CDTR : CompareRRE<"cdtr", 0xB3E4, null_frag, FP64, FP64>;
|
||||
def CXTR : CompareRRE<"cxtr", 0xB3EC, null_frag, FP128, FP128>;
|
||||
}
|
||||
|
||||
// Compare and signal.
|
||||
let Defs = [CC] in {
|
||||
let Uses = [FPC], Defs = [CC] in {
|
||||
def KDTR : CompareRRE<"kdtr", 0xB3E0, null_frag, FP64, FP64>;
|
||||
def KXTR : CompareRRE<"kxtr", 0xB3E8, null_frag, FP128, FP128>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ let isCodeGenOnly = 1 in
|
|||
|
||||
// Moves between two floating-point registers that also set the condition
|
||||
// codes.
|
||||
let Defs = [CC], CCValues = 0xF, CompareZeroCCMask = 0xF in {
|
||||
let Uses = [FPC], Defs = [CC], CCValues = 0xF, CompareZeroCCMask = 0xF in {
|
||||
defm LTEBR : LoadAndTestRRE<"ltebr", 0xB302, FP32>;
|
||||
defm LTDBR : LoadAndTestRRE<"ltdbr", 0xB312, FP64>;
|
||||
defm LTXBR : LoadAndTestRRE<"ltxbr", 0xB342, FP128>;
|
||||
|
|
@ -68,7 +68,7 @@ let Predicates = [FeatureNoVector] in {
|
|||
|
||||
// Use a normal load-and-test for compare against zero in case of
|
||||
// vector support (via a pseudo to simplify instruction selection).
|
||||
let Defs = [CC], usesCustomInserter = 1, hasNoSchedulingInfo = 1 in {
|
||||
let Uses = [FPC], Defs = [CC], usesCustomInserter = 1, hasNoSchedulingInfo = 1 in {
|
||||
def LTEBRCompare_VecPseudo : Pseudo<(outs), (ins FP32:$R1, FP32:$R2), []>;
|
||||
def LTDBRCompare_VecPseudo : Pseudo<(outs), (ins FP64:$R1, FP64:$R2), []>;
|
||||
def LTXBRCompare_VecPseudo : Pseudo<(outs), (ins FP128:$R1, FP128:$R2), []>;
|
||||
|
|
@ -173,16 +173,18 @@ let SimpleBDXStore = 1, mayStore = 1 in {
|
|||
// Convert floating-point values to narrower representations, rounding
|
||||
// according to the current mode. The destination of LEXBR and LDXBR
|
||||
// is a 128-bit value, but only the first register of the pair is used.
|
||||
def LEDBR : UnaryRRE<"ledbr", 0xB344, fpround, FP32, FP64>;
|
||||
def LEXBR : UnaryRRE<"lexbr", 0xB346, null_frag, FP128, FP128>;
|
||||
def LDXBR : UnaryRRE<"ldxbr", 0xB345, null_frag, FP128, FP128>;
|
||||
let Uses = [FPC] in {
|
||||
def LEDBR : UnaryRRE<"ledbr", 0xB344, fpround, FP32, FP64>;
|
||||
def LEXBR : UnaryRRE<"lexbr", 0xB346, null_frag, FP128, FP128>;
|
||||
def LDXBR : UnaryRRE<"ldxbr", 0xB345, null_frag, FP128, FP128>;
|
||||
|
||||
def LEDBRA : TernaryRRFe<"ledbra", 0xB344, FP32, FP64>,
|
||||
def LEDBRA : TernaryRRFe<"ledbra", 0xB344, FP32, FP64>,
|
||||
Requires<[FeatureFPExtension]>;
|
||||
def LEXBRA : TernaryRRFe<"lexbra", 0xB346, FP128, FP128>,
|
||||
def LEXBRA : TernaryRRFe<"lexbra", 0xB346, FP128, FP128>,
|
||||
Requires<[FeatureFPExtension]>;
|
||||
def LDXBRA : TernaryRRFe<"ldxbra", 0xB345, FP128, FP128>,
|
||||
def LDXBRA : TernaryRRFe<"ldxbra", 0xB345, FP128, FP128>,
|
||||
Requires<[FeatureFPExtension]>;
|
||||
}
|
||||
|
||||
let Predicates = [FeatureNoVectorEnhancements1] in {
|
||||
def : Pat<(f32 (fpround FP128:$src)),
|
||||
|
|
@ -192,18 +194,22 @@ let Predicates = [FeatureNoVectorEnhancements1] in {
|
|||
}
|
||||
|
||||
// Extend register floating-point values to wider representations.
|
||||
def LDEBR : UnaryRRE<"ldebr", 0xB304, fpextend, FP64, FP32>;
|
||||
def LXEBR : UnaryRRE<"lxebr", 0xB306, null_frag, FP128, FP32>;
|
||||
def LXDBR : UnaryRRE<"lxdbr", 0xB305, null_frag, FP128, FP64>;
|
||||
let Uses = [FPC] in {
|
||||
def LDEBR : UnaryRRE<"ldebr", 0xB304, fpextend, FP64, FP32>;
|
||||
def LXEBR : UnaryRRE<"lxebr", 0xB306, null_frag, FP128, FP32>;
|
||||
def LXDBR : UnaryRRE<"lxdbr", 0xB305, null_frag, FP128, FP64>;
|
||||
}
|
||||
let Predicates = [FeatureNoVectorEnhancements1] in {
|
||||
def : Pat<(f128 (fpextend (f32 FP32:$src))), (LXEBR FP32:$src)>;
|
||||
def : Pat<(f128 (fpextend (f64 FP64:$src))), (LXDBR FP64:$src)>;
|
||||
}
|
||||
|
||||
// Extend memory floating-point values to wider representations.
|
||||
def LDEB : UnaryRXE<"ldeb", 0xED04, extloadf32, FP64, 4>;
|
||||
def LXEB : UnaryRXE<"lxeb", 0xED06, null_frag, FP128, 4>;
|
||||
def LXDB : UnaryRXE<"lxdb", 0xED05, null_frag, FP128, 8>;
|
||||
let Uses = [FPC] in {
|
||||
def LDEB : UnaryRXE<"ldeb", 0xED04, extloadf32, FP64, 4>;
|
||||
def LXEB : UnaryRXE<"lxeb", 0xED06, null_frag, FP128, 4>;
|
||||
def LXDB : UnaryRXE<"lxdb", 0xED05, null_frag, FP128, 8>;
|
||||
}
|
||||
let Predicates = [FeatureNoVectorEnhancements1] in {
|
||||
def : Pat<(f128 (extloadf32 bdxaddr12only:$src)),
|
||||
(LXEB bdxaddr12only:$src)>;
|
||||
|
|
@ -212,17 +218,19 @@ let Predicates = [FeatureNoVectorEnhancements1] in {
|
|||
}
|
||||
|
||||
// Convert a signed integer register value to a floating-point one.
|
||||
def CEFBR : UnaryRRE<"cefbr", 0xB394, sint_to_fp, FP32, GR32>;
|
||||
def CDFBR : UnaryRRE<"cdfbr", 0xB395, sint_to_fp, FP64, GR32>;
|
||||
def CXFBR : UnaryRRE<"cxfbr", 0xB396, sint_to_fp, FP128, GR32>;
|
||||
let Uses = [FPC] in {
|
||||
def CEFBR : UnaryRRE<"cefbr", 0xB394, sint_to_fp, FP32, GR32>;
|
||||
def CDFBR : UnaryRRE<"cdfbr", 0xB395, sint_to_fp, FP64, GR32>;
|
||||
def CXFBR : UnaryRRE<"cxfbr", 0xB396, sint_to_fp, FP128, GR32>;
|
||||
|
||||
def CEGBR : UnaryRRE<"cegbr", 0xB3A4, sint_to_fp, FP32, GR64>;
|
||||
def CDGBR : UnaryRRE<"cdgbr", 0xB3A5, sint_to_fp, FP64, GR64>;
|
||||
def CXGBR : UnaryRRE<"cxgbr", 0xB3A6, sint_to_fp, FP128, GR64>;
|
||||
def CEGBR : UnaryRRE<"cegbr", 0xB3A4, sint_to_fp, FP32, GR64>;
|
||||
def CDGBR : UnaryRRE<"cdgbr", 0xB3A5, sint_to_fp, FP64, GR64>;
|
||||
def CXGBR : UnaryRRE<"cxgbr", 0xB3A6, sint_to_fp, FP128, GR64>;
|
||||
}
|
||||
|
||||
// The FP extension feature provides versions of the above that allow
|
||||
// specifying rounding mode and inexact-exception suppression flags.
|
||||
let Predicates = [FeatureFPExtension] in {
|
||||
let Uses = [FPC], Predicates = [FeatureFPExtension] in {
|
||||
def CEFBRA : TernaryRRFe<"cefbra", 0xB394, FP32, GR32>;
|
||||
def CDFBRA : TernaryRRFe<"cdfbra", 0xB395, FP64, GR32>;
|
||||
def CXFBRA : TernaryRRFe<"cxfbra", 0xB396, FP128, GR32>;
|
||||
|
|
@ -234,6 +242,7 @@ let Predicates = [FeatureFPExtension] in {
|
|||
|
||||
// Convert am unsigned integer register value to a floating-point one.
|
||||
let Predicates = [FeatureFPExtension] in {
|
||||
let Uses = [FPC] in {
|
||||
def CELFBR : TernaryRRFe<"celfbr", 0xB390, FP32, GR32>;
|
||||
def CDLFBR : TernaryRRFe<"cdlfbr", 0xB391, FP64, GR32>;
|
||||
def CXLFBR : TernaryRRFe<"cxlfbr", 0xB392, FP128, GR32>;
|
||||
|
|
@ -241,6 +250,7 @@ let Predicates = [FeatureFPExtension] in {
|
|||
def CELGBR : TernaryRRFe<"celgbr", 0xB3A0, FP32, GR64>;
|
||||
def CDLGBR : TernaryRRFe<"cdlgbr", 0xB3A1, FP64, GR64>;
|
||||
def CXLGBR : TernaryRRFe<"cxlgbr", 0xB3A2, FP128, GR64>;
|
||||
}
|
||||
|
||||
def : Pat<(f32 (uint_to_fp GR32:$src)), (CELFBR 0, GR32:$src, 0)>;
|
||||
def : Pat<(f64 (uint_to_fp GR32:$src)), (CDLFBR 0, GR32:$src, 0)>;
|
||||
|
|
@ -253,7 +263,7 @@ let Predicates = [FeatureFPExtension] in {
|
|||
|
||||
// Convert a floating-point register value to a signed integer value,
|
||||
// with the second operand (modifier M3) specifying the rounding mode.
|
||||
let Defs = [CC] in {
|
||||
let Uses = [FPC], Defs = [CC] in {
|
||||
def CFEBR : BinaryRRFe<"cfebr", 0xB398, GR32, FP32>;
|
||||
def CFDBR : BinaryRRFe<"cfdbr", 0xB399, GR32, FP64>;
|
||||
def CFXBR : BinaryRRFe<"cfxbr", 0xB39A, GR32, FP128>;
|
||||
|
|
@ -274,7 +284,7 @@ def : Pat<(i64 (fp_to_sint FP128:$src)), (CGXBR 5, FP128:$src)>;
|
|||
|
||||
// The FP extension feature provides versions of the above that allow
|
||||
// also specifying the inexact-exception suppression flag.
|
||||
let Predicates = [FeatureFPExtension], Defs = [CC] in {
|
||||
let Uses = [FPC], Predicates = [FeatureFPExtension], Defs = [CC] in {
|
||||
def CFEBRA : TernaryRRFe<"cfebra", 0xB398, GR32, FP32>;
|
||||
def CFDBRA : TernaryRRFe<"cfdbra", 0xB399, GR32, FP64>;
|
||||
def CFXBRA : TernaryRRFe<"cfxbra", 0xB39A, GR32, FP128>;
|
||||
|
|
@ -286,7 +296,7 @@ let Predicates = [FeatureFPExtension], Defs = [CC] in {
|
|||
|
||||
// Convert a floating-point register value to an unsigned integer value.
|
||||
let Predicates = [FeatureFPExtension] in {
|
||||
let Defs = [CC] in {
|
||||
let Uses = [FPC], Defs = [CC] in {
|
||||
def CLFEBR : TernaryRRFe<"clfebr", 0xB39C, GR32, FP32>;
|
||||
def CLFDBR : TernaryRRFe<"clfdbr", 0xB39D, GR32, FP64>;
|
||||
def CLFXBR : TernaryRRFe<"clfxbr", 0xB39E, GR32, FP128>;
|
||||
|
|
@ -352,18 +362,22 @@ let isCodeGenOnly = 1 in
|
|||
def LNDFR_32 : UnaryRRE<"lndfr", 0xB371, fnabs, FP32, FP32>;
|
||||
|
||||
// Square root.
|
||||
def SQEBR : UnaryRRE<"sqebr", 0xB314, fsqrt, FP32, FP32>;
|
||||
def SQDBR : UnaryRRE<"sqdbr", 0xB315, fsqrt, FP64, FP64>;
|
||||
def SQXBR : UnaryRRE<"sqxbr", 0xB316, fsqrt, FP128, FP128>;
|
||||
let Uses = [FPC] in {
|
||||
def SQEBR : UnaryRRE<"sqebr", 0xB314, fsqrt, FP32, FP32>;
|
||||
def SQDBR : UnaryRRE<"sqdbr", 0xB315, fsqrt, FP64, FP64>;
|
||||
def SQXBR : UnaryRRE<"sqxbr", 0xB316, fsqrt, FP128, FP128>;
|
||||
|
||||
def SQEB : UnaryRXE<"sqeb", 0xED14, loadu<fsqrt>, FP32, 4>;
|
||||
def SQDB : UnaryRXE<"sqdb", 0xED15, loadu<fsqrt>, FP64, 8>;
|
||||
def SQEB : UnaryRXE<"sqeb", 0xED14, loadu<fsqrt>, FP32, 4>;
|
||||
def SQDB : UnaryRXE<"sqdb", 0xED15, loadu<fsqrt>, FP64, 8>;
|
||||
}
|
||||
|
||||
// Round to an integer, with the second operand (modifier M3) specifying
|
||||
// the rounding mode. These forms always check for inexact conditions.
|
||||
def FIEBR : BinaryRRFe<"fiebr", 0xB357, FP32, FP32>;
|
||||
def FIDBR : BinaryRRFe<"fidbr", 0xB35F, FP64, FP64>;
|
||||
def FIXBR : BinaryRRFe<"fixbr", 0xB347, FP128, FP128>;
|
||||
let Uses = [FPC] in {
|
||||
def FIEBR : BinaryRRFe<"fiebr", 0xB357, FP32, FP32>;
|
||||
def FIDBR : BinaryRRFe<"fidbr", 0xB35F, FP64, FP64>;
|
||||
def FIXBR : BinaryRRFe<"fixbr", 0xB347, FP128, FP128>;
|
||||
}
|
||||
|
||||
// frint rounds according to the current mode (modifier 0) and detects
|
||||
// inexact conditions.
|
||||
|
|
@ -374,9 +388,11 @@ def : Pat<(frint FP128:$src), (FIXBR 0, FP128:$src)>;
|
|||
let Predicates = [FeatureFPExtension] in {
|
||||
// Extended forms of the FIxBR instructions. M4 can be set to 4
|
||||
// to suppress detection of inexact conditions.
|
||||
let Uses = [FPC] in {
|
||||
def FIEBRA : TernaryRRFe<"fiebra", 0xB357, FP32, FP32>;
|
||||
def FIDBRA : TernaryRRFe<"fidbra", 0xB35F, FP64, FP64>;
|
||||
def FIXBRA : TernaryRRFe<"fixbra", 0xB347, FP128, FP128>;
|
||||
}
|
||||
|
||||
// fnearbyint is like frint but does not detect inexact conditions.
|
||||
def : Pat<(fnearbyint FP32:$src), (FIEBRA 0, FP32:$src, 4)>;
|
||||
|
|
@ -412,7 +428,7 @@ let Predicates = [FeatureFPExtension] in {
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Addition.
|
||||
let Defs = [CC], CCValues = 0xF, CompareZeroCCMask = 0xF in {
|
||||
let Uses = [FPC], Defs = [CC], CCValues = 0xF, CompareZeroCCMask = 0xF in {
|
||||
let isCommutable = 1 in {
|
||||
def AEBR : BinaryRRE<"aebr", 0xB30A, fadd, FP32, FP32>;
|
||||
def ADBR : BinaryRRE<"adbr", 0xB31A, fadd, FP64, FP64>;
|
||||
|
|
@ -423,7 +439,7 @@ let Defs = [CC], CCValues = 0xF, CompareZeroCCMask = 0xF in {
|
|||
}
|
||||
|
||||
// Subtraction.
|
||||
let Defs = [CC], CCValues = 0xF, CompareZeroCCMask = 0xF in {
|
||||
let Uses = [FPC], Defs = [CC], CCValues = 0xF, CompareZeroCCMask = 0xF in {
|
||||
def SEBR : BinaryRRE<"sebr", 0xB30B, fsub, FP32, FP32>;
|
||||
def SDBR : BinaryRRE<"sdbr", 0xB31B, fsub, FP64, FP64>;
|
||||
def SXBR : BinaryRRE<"sxbr", 0xB34B, fsub, FP128, FP128>;
|
||||
|
|
@ -433,36 +449,42 @@ let Defs = [CC], CCValues = 0xF, CompareZeroCCMask = 0xF in {
|
|||
}
|
||||
|
||||
// Multiplication.
|
||||
let isCommutable = 1 in {
|
||||
let Uses = [FPC] in {
|
||||
let isCommutable = 1 in {
|
||||
def MEEBR : BinaryRRE<"meebr", 0xB317, fmul, FP32, FP32>;
|
||||
def MDBR : BinaryRRE<"mdbr", 0xB31C, fmul, FP64, FP64>;
|
||||
def MXBR : BinaryRRE<"mxbr", 0xB34C, fmul, FP128, FP128>;
|
||||
}
|
||||
def MEEB : BinaryRXE<"meeb", 0xED17, fmul, FP32, load, 4>;
|
||||
def MDB : BinaryRXE<"mdb", 0xED1C, fmul, FP64, load, 8>;
|
||||
}
|
||||
def MEEB : BinaryRXE<"meeb", 0xED17, fmul, FP32, load, 4>;
|
||||
def MDB : BinaryRXE<"mdb", 0xED1C, fmul, FP64, load, 8>;
|
||||
|
||||
// f64 multiplication of two FP32 registers.
|
||||
def MDEBR : BinaryRRE<"mdebr", 0xB30C, null_frag, FP64, FP32>;
|
||||
let Uses = [FPC] in
|
||||
def MDEBR : BinaryRRE<"mdebr", 0xB30C, null_frag, FP64, FP32>;
|
||||
def : Pat<(fmul (f64 (fpextend FP32:$src1)), (f64 (fpextend FP32:$src2))),
|
||||
(MDEBR (INSERT_SUBREG (f64 (IMPLICIT_DEF)),
|
||||
FP32:$src1, subreg_h32), FP32:$src2)>;
|
||||
|
||||
// f64 multiplication of an FP32 register and an f32 memory.
|
||||
def MDEB : BinaryRXE<"mdeb", 0xED0C, null_frag, FP64, load, 4>;
|
||||
let Uses = [FPC] in
|
||||
def MDEB : BinaryRXE<"mdeb", 0xED0C, null_frag, FP64, load, 4>;
|
||||
def : Pat<(fmul (f64 (fpextend FP32:$src1)),
|
||||
(f64 (extloadf32 bdxaddr12only:$addr))),
|
||||
(MDEB (INSERT_SUBREG (f64 (IMPLICIT_DEF)), FP32:$src1, subreg_h32),
|
||||
bdxaddr12only:$addr)>;
|
||||
|
||||
// f128 multiplication of two FP64 registers.
|
||||
def MXDBR : BinaryRRE<"mxdbr", 0xB307, null_frag, FP128, FP64>;
|
||||
let Uses = [FPC] in
|
||||
def MXDBR : BinaryRRE<"mxdbr", 0xB307, null_frag, FP128, FP64>;
|
||||
let Predicates = [FeatureNoVectorEnhancements1] in
|
||||
def : Pat<(fmul (f128 (fpextend FP64:$src1)), (f128 (fpextend FP64:$src2))),
|
||||
(MXDBR (INSERT_SUBREG (f128 (IMPLICIT_DEF)),
|
||||
FP64:$src1, subreg_h64), FP64:$src2)>;
|
||||
|
||||
// f128 multiplication of an FP64 register and an f64 memory.
|
||||
def MXDB : BinaryRXE<"mxdb", 0xED07, null_frag, FP128, load, 8>;
|
||||
let Uses = [FPC] in
|
||||
def MXDB : BinaryRXE<"mxdb", 0xED07, null_frag, FP128, load, 8>;
|
||||
let Predicates = [FeatureNoVectorEnhancements1] in
|
||||
def : Pat<(fmul (f128 (fpextend FP64:$src1)),
|
||||
(f128 (extloadf64 bdxaddr12only:$addr))),
|
||||
|
|
@ -470,29 +492,35 @@ let Predicates = [FeatureNoVectorEnhancements1] in
|
|||
bdxaddr12only:$addr)>;
|
||||
|
||||
// Fused multiply-add.
|
||||
def MAEBR : TernaryRRD<"maebr", 0xB30E, z_fma, FP32, FP32>;
|
||||
def MADBR : TernaryRRD<"madbr", 0xB31E, z_fma, FP64, FP64>;
|
||||
let Uses = [FPC] in {
|
||||
def MAEBR : TernaryRRD<"maebr", 0xB30E, z_fma, FP32, FP32>;
|
||||
def MADBR : TernaryRRD<"madbr", 0xB31E, z_fma, FP64, FP64>;
|
||||
|
||||
def MAEB : TernaryRXF<"maeb", 0xED0E, z_fma, FP32, FP32, load, 4>;
|
||||
def MADB : TernaryRXF<"madb", 0xED1E, z_fma, FP64, FP64, load, 8>;
|
||||
def MAEB : TernaryRXF<"maeb", 0xED0E, z_fma, FP32, FP32, load, 4>;
|
||||
def MADB : TernaryRXF<"madb", 0xED1E, z_fma, FP64, FP64, load, 8>;
|
||||
}
|
||||
|
||||
// Fused multiply-subtract.
|
||||
def MSEBR : TernaryRRD<"msebr", 0xB30F, z_fms, FP32, FP32>;
|
||||
def MSDBR : TernaryRRD<"msdbr", 0xB31F, z_fms, FP64, FP64>;
|
||||
let Uses = [FPC] in {
|
||||
def MSEBR : TernaryRRD<"msebr", 0xB30F, z_fms, FP32, FP32>;
|
||||
def MSDBR : TernaryRRD<"msdbr", 0xB31F, z_fms, FP64, FP64>;
|
||||
|
||||
def MSEB : TernaryRXF<"mseb", 0xED0F, z_fms, FP32, FP32, load, 4>;
|
||||
def MSDB : TernaryRXF<"msdb", 0xED1F, z_fms, FP64, FP64, load, 8>;
|
||||
def MSEB : TernaryRXF<"mseb", 0xED0F, z_fms, FP32, FP32, load, 4>;
|
||||
def MSDB : TernaryRXF<"msdb", 0xED1F, z_fms, FP64, FP64, load, 8>;
|
||||
}
|
||||
|
||||
// Division.
|
||||
def DEBR : BinaryRRE<"debr", 0xB30D, fdiv, FP32, FP32>;
|
||||
def DDBR : BinaryRRE<"ddbr", 0xB31D, fdiv, FP64, FP64>;
|
||||
def DXBR : BinaryRRE<"dxbr", 0xB34D, fdiv, FP128, FP128>;
|
||||
let Uses = [FPC] in {
|
||||
def DEBR : BinaryRRE<"debr", 0xB30D, fdiv, FP32, FP32>;
|
||||
def DDBR : BinaryRRE<"ddbr", 0xB31D, fdiv, FP64, FP64>;
|
||||
def DXBR : BinaryRRE<"dxbr", 0xB34D, fdiv, FP128, FP128>;
|
||||
|
||||
def DEB : BinaryRXE<"deb", 0xED0D, fdiv, FP32, load, 4>;
|
||||
def DDB : BinaryRXE<"ddb", 0xED1D, fdiv, FP64, load, 8>;
|
||||
def DEB : BinaryRXE<"deb", 0xED0D, fdiv, FP32, load, 4>;
|
||||
def DDB : BinaryRXE<"ddb", 0xED1D, fdiv, FP64, load, 8>;
|
||||
}
|
||||
|
||||
// Divide to integer.
|
||||
let Defs = [CC] in {
|
||||
let Uses = [FPC], Defs = [CC] in {
|
||||
def DIEBR : TernaryRRFb<"diebr", 0xB353, FP32, FP32, FP32>;
|
||||
def DIDBR : TernaryRRFb<"didbr", 0xB35B, FP64, FP64, FP64>;
|
||||
}
|
||||
|
|
@ -501,7 +529,7 @@ let Defs = [CC] in {
|
|||
// Comparisons
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let Defs = [CC], CCValues = 0xF in {
|
||||
let Uses = [FPC], Defs = [CC], CCValues = 0xF in {
|
||||
def CEBR : CompareRRE<"cebr", 0xB309, z_fcmp, FP32, FP32>;
|
||||
def CDBR : CompareRRE<"cdbr", 0xB319, z_fcmp, FP64, FP64>;
|
||||
def CXBR : CompareRRE<"cxbr", 0xB349, z_fcmp, FP128, FP128>;
|
||||
|
|
@ -531,20 +559,28 @@ let Defs = [CC], CCValues = 0xC in {
|
|||
let hasSideEffects = 1 in {
|
||||
let mayLoad = 1, mayStore = 1 in {
|
||||
// TODO: EFPC and SFPC do not touch memory at all
|
||||
let Uses = [FPC] in {
|
||||
def EFPC : InherentRRE<"efpc", 0xB38C, GR32, int_s390_efpc>;
|
||||
def STFPC : StoreInherentS<"stfpc", 0xB29C, storei<int_s390_efpc>, 4>;
|
||||
}
|
||||
|
||||
let Defs = [FPC] in {
|
||||
def SFPC : SideEffectUnaryRRE<"sfpc", 0xB384, GR32, int_s390_sfpc>;
|
||||
def LFPC : SideEffectUnaryS<"lfpc", 0xB29D, loadu<int_s390_sfpc>, 4>;
|
||||
}
|
||||
}
|
||||
|
||||
let Defs = [FPC] in {
|
||||
def SFASR : SideEffectUnaryRRE<"sfasr", 0xB385, GR32, null_frag>;
|
||||
def LFAS : SideEffectUnaryS<"lfas", 0xB2BD, null_frag, 4>;
|
||||
}
|
||||
|
||||
let Uses = [FPC], Defs = [FPC] in {
|
||||
def SRNMB : SideEffectAddressS<"srnmb", 0xB2B8, null_frag, shift12only>,
|
||||
Requires<[FeatureFPExtension]>;
|
||||
def SRNM : SideEffectAddressS<"srnm", 0xB299, null_frag, shift12only>;
|
||||
def SRNMT : SideEffectAddressS<"srnmt", 0xB2B9, null_frag, shift12only>;
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ let isCall = 1, Defs = [CC] in {
|
|||
}
|
||||
|
||||
// Regular calls.
|
||||
let isCall = 1, Defs = [R14D, CC] in {
|
||||
let isCall = 1, Defs = [R14D, CC], Uses = [FPC] in {
|
||||
def CallBRASL : Alias<6, (outs), (ins pcrel32:$I2, variable_ops),
|
||||
[(z_call pcrel32:$I2)]>;
|
||||
def CallBASR : Alias<2, (outs), (ins ADDR64:$R2, variable_ops),
|
||||
|
|
|
|||
|
|
@ -934,6 +934,7 @@ multiclass VectorRounding<Instruction insn, TypedReg tr> {
|
|||
|
||||
let Predicates = [FeatureVector] in {
|
||||
// Add.
|
||||
let Uses = [FPC] in {
|
||||
def VFA : BinaryVRRcFloatGeneric<"vfa", 0xE7E3>;
|
||||
def VFADB : BinaryVRRc<"vfadb", 0xE7E3, fadd, v128db, v128db, 3, 0>;
|
||||
def WFADB : BinaryVRRc<"wfadb", 0xE7E3, fadd, v64db, v64db, 3, 8>;
|
||||
|
|
@ -942,34 +943,44 @@ let Predicates = [FeatureVector] in {
|
|||
def WFASB : BinaryVRRc<"wfasb", 0xE7E3, fadd, v32sb, v32sb, 2, 8>;
|
||||
def WFAXB : BinaryVRRc<"wfaxb", 0xE7E3, fadd, v128xb, v128xb, 4, 8>;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert from fixed 64-bit.
|
||||
let Uses = [FPC] in {
|
||||
def VCDG : TernaryVRRaFloatGeneric<"vcdg", 0xE7C3>;
|
||||
def VCDGB : TernaryVRRa<"vcdgb", 0xE7C3, null_frag, v128db, v128g, 3, 0>;
|
||||
def WCDGB : TernaryVRRa<"wcdgb", 0xE7C3, null_frag, v64db, v64g, 3, 8>;
|
||||
}
|
||||
def : FPConversion<VCDGB, sint_to_fp, v128db, v128g, 0, 0>;
|
||||
|
||||
// Convert from logical 64-bit.
|
||||
let Uses = [FPC] in {
|
||||
def VCDLG : TernaryVRRaFloatGeneric<"vcdlg", 0xE7C1>;
|
||||
def VCDLGB : TernaryVRRa<"vcdlgb", 0xE7C1, null_frag, v128db, v128g, 3, 0>;
|
||||
def WCDLGB : TernaryVRRa<"wcdlgb", 0xE7C1, null_frag, v64db, v64g, 3, 8>;
|
||||
}
|
||||
def : FPConversion<VCDLGB, uint_to_fp, v128db, v128g, 0, 0>;
|
||||
|
||||
// Convert to fixed 64-bit.
|
||||
let Uses = [FPC] in {
|
||||
def VCGD : TernaryVRRaFloatGeneric<"vcgd", 0xE7C2>;
|
||||
def VCGDB : TernaryVRRa<"vcgdb", 0xE7C2, null_frag, v128g, v128db, 3, 0>;
|
||||
def WCGDB : TernaryVRRa<"wcgdb", 0xE7C2, null_frag, v64g, v64db, 3, 8>;
|
||||
}
|
||||
// Rounding mode should agree with SystemZInstrFP.td.
|
||||
def : FPConversion<VCGDB, fp_to_sint, v128g, v128db, 0, 5>;
|
||||
|
||||
// Convert to logical 64-bit.
|
||||
let Uses = [FPC] in {
|
||||
def VCLGD : TernaryVRRaFloatGeneric<"vclgd", 0xE7C0>;
|
||||
def VCLGDB : TernaryVRRa<"vclgdb", 0xE7C0, null_frag, v128g, v128db, 3, 0>;
|
||||
def WCLGDB : TernaryVRRa<"wclgdb", 0xE7C0, null_frag, v64g, v64db, 3, 8>;
|
||||
}
|
||||
// Rounding mode should agree with SystemZInstrFP.td.
|
||||
def : FPConversion<VCLGDB, fp_to_uint, v128g, v128db, 0, 5>;
|
||||
|
||||
// Divide.
|
||||
let Uses = [FPC] in {
|
||||
def VFD : BinaryVRRcFloatGeneric<"vfd", 0xE7E5>;
|
||||
def VFDDB : BinaryVRRc<"vfddb", 0xE7E5, fdiv, v128db, v128db, 3, 0>;
|
||||
def WFDDB : BinaryVRRc<"wfddb", 0xE7E5, fdiv, v64db, v64db, 3, 8>;
|
||||
|
|
@ -978,50 +989,63 @@ let Predicates = [FeatureVector] in {
|
|||
def WFDSB : BinaryVRRc<"wfdsb", 0xE7E5, fdiv, v32sb, v32sb, 2, 8>;
|
||||
def WFDXB : BinaryVRRc<"wfdxb", 0xE7E5, fdiv, v128xb, v128xb, 4, 8>;
|
||||
}
|
||||
}
|
||||
|
||||
// Load FP integer.
|
||||
let Uses = [FPC] in {
|
||||
def VFI : TernaryVRRaFloatGeneric<"vfi", 0xE7C7>;
|
||||
def VFIDB : TernaryVRRa<"vfidb", 0xE7C7, int_s390_vfidb, v128db, v128db, 3, 0>;
|
||||
def WFIDB : TernaryVRRa<"wfidb", 0xE7C7, null_frag, v64db, v64db, 3, 8>;
|
||||
}
|
||||
defm : VectorRounding<VFIDB, v128db>;
|
||||
defm : VectorRounding<WFIDB, v64db>;
|
||||
let Predicates = [FeatureVectorEnhancements1] in {
|
||||
let Uses = [FPC] in {
|
||||
def VFISB : TernaryVRRa<"vfisb", 0xE7C7, int_s390_vfisb, v128sb, v128sb, 2, 0>;
|
||||
def WFISB : TernaryVRRa<"wfisb", 0xE7C7, null_frag, v32sb, v32sb, 2, 8>;
|
||||
def WFIXB : TernaryVRRa<"wfixb", 0xE7C7, null_frag, v128xb, v128xb, 4, 8>;
|
||||
}
|
||||
defm : VectorRounding<VFISB, v128sb>;
|
||||
defm : VectorRounding<WFISB, v32sb>;
|
||||
defm : VectorRounding<WFIXB, v128xb>;
|
||||
}
|
||||
|
||||
// Load lengthened.
|
||||
let Uses = [FPC] in {
|
||||
def VLDE : UnaryVRRaFloatGeneric<"vlde", 0xE7C4>;
|
||||
def VLDEB : UnaryVRRa<"vldeb", 0xE7C4, z_vextend, v128db, v128sb, 2, 0>;
|
||||
def WLDEB : UnaryVRRa<"wldeb", 0xE7C4, fpextend, v64db, v32sb, 2, 8>;
|
||||
}
|
||||
let Predicates = [FeatureVectorEnhancements1] in {
|
||||
let Uses = [FPC] in {
|
||||
let isAsmParserOnly = 1 in {
|
||||
def VFLL : UnaryVRRaFloatGeneric<"vfll", 0xE7C4>;
|
||||
def VFLLS : UnaryVRRa<"vflls", 0xE7C4, null_frag, v128db, v128sb, 2, 0>;
|
||||
def WFLLS : UnaryVRRa<"wflls", 0xE7C4, null_frag, v64db, v32sb, 2, 8>;
|
||||
}
|
||||
def WFLLD : UnaryVRRa<"wflld", 0xE7C4, fpextend, v128xb, v64db, 3, 8>;
|
||||
}
|
||||
def : Pat<(f128 (fpextend (f32 VR32:$src))),
|
||||
(WFLLD (WLDEB VR32:$src))>;
|
||||
}
|
||||
|
||||
// Load rounded.
|
||||
let Uses = [FPC] in {
|
||||
def VLED : TernaryVRRaFloatGeneric<"vled", 0xE7C5>;
|
||||
def VLEDB : TernaryVRRa<"vledb", 0xE7C5, null_frag, v128sb, v128db, 3, 0>;
|
||||
def WLEDB : TernaryVRRa<"wledb", 0xE7C5, null_frag, v32sb, v64db, 3, 8>;
|
||||
}
|
||||
def : Pat<(v4f32 (z_vround (v2f64 VR128:$src))), (VLEDB VR128:$src, 0, 0)>;
|
||||
def : FPConversion<WLEDB, fpround, v32sb, v64db, 0, 0>;
|
||||
let Predicates = [FeatureVectorEnhancements1] in {
|
||||
let Uses = [FPC] in {
|
||||
let isAsmParserOnly = 1 in {
|
||||
def VFLR : TernaryVRRaFloatGeneric<"vflr", 0xE7C5>;
|
||||
def VFLRD : TernaryVRRa<"vflrd", 0xE7C5, null_frag, v128sb, v128db, 3, 0>;
|
||||
def WFLRD : TernaryVRRa<"wflrd", 0xE7C5, null_frag, v32sb, v64db, 3, 8>;
|
||||
}
|
||||
def WFLRX : TernaryVRRa<"wflrx", 0xE7C5, null_frag, v64db, v128xb, 4, 8>;
|
||||
}
|
||||
def : FPConversion<WFLRX, fpround, v64db, v128xb, 0, 0>;
|
||||
def : Pat<(f32 (fpround (f128 VR128:$src))),
|
||||
(WLEDB (WFLRX VR128:$src, 0, 3), 0, 0)>;
|
||||
|
|
@ -1033,6 +1057,7 @@ let Predicates = [FeatureVector] in {
|
|||
def : FPMinMax<insn, fmaximum, tr, 1>;
|
||||
}
|
||||
let Predicates = [FeatureVectorEnhancements1] in {
|
||||
let Uses = [FPC] in {
|
||||
def VFMAX : TernaryVRRcFloatGeneric<"vfmax", 0xE7EF>;
|
||||
def VFMAXDB : TernaryVRRcFloat<"vfmaxdb", 0xE7EF, int_s390_vfmaxdb,
|
||||
v128db, v128db, 3, 0>;
|
||||
|
|
@ -1044,6 +1069,7 @@ let Predicates = [FeatureVector] in {
|
|||
v32sb, v32sb, 2, 8>;
|
||||
def WFMAXXB : TernaryVRRcFloat<"wfmaxxb", 0xE7EF, null_frag,
|
||||
v128xb, v128xb, 4, 8>;
|
||||
}
|
||||
defm : VectorMax<VFMAXDB, v128db>;
|
||||
defm : VectorMax<WFMAXDB, v64db>;
|
||||
defm : VectorMax<VFMAXSB, v128sb>;
|
||||
|
|
@ -1057,6 +1083,7 @@ let Predicates = [FeatureVector] in {
|
|||
def : FPMinMax<insn, fminimum, tr, 1>;
|
||||
}
|
||||
let Predicates = [FeatureVectorEnhancements1] in {
|
||||
let Uses = [FPC] in {
|
||||
def VFMIN : TernaryVRRcFloatGeneric<"vfmin", 0xE7EE>;
|
||||
def VFMINDB : TernaryVRRcFloat<"vfmindb", 0xE7EE, int_s390_vfmindb,
|
||||
v128db, v128db, 3, 0>;
|
||||
|
|
@ -1068,6 +1095,7 @@ let Predicates = [FeatureVector] in {
|
|||
v32sb, v32sb, 2, 8>;
|
||||
def WFMINXB : TernaryVRRcFloat<"wfminxb", 0xE7EE, null_frag,
|
||||
v128xb, v128xb, 4, 8>;
|
||||
}
|
||||
defm : VectorMin<VFMINDB, v128db>;
|
||||
defm : VectorMin<WFMINDB, v64db>;
|
||||
defm : VectorMin<VFMINSB, v128sb>;
|
||||
|
|
@ -1076,6 +1104,7 @@ let Predicates = [FeatureVector] in {
|
|||
}
|
||||
|
||||
// Multiply.
|
||||
let Uses = [FPC] in {
|
||||
def VFM : BinaryVRRcFloatGeneric<"vfm", 0xE7E7>;
|
||||
def VFMDB : BinaryVRRc<"vfmdb", 0xE7E7, fmul, v128db, v128db, 3, 0>;
|
||||
def WFMDB : BinaryVRRc<"wfmdb", 0xE7E7, fmul, v64db, v64db, 3, 8>;
|
||||
|
|
@ -1084,8 +1113,10 @@ let Predicates = [FeatureVector] in {
|
|||
def WFMSB : BinaryVRRc<"wfmsb", 0xE7E7, fmul, v32sb, v32sb, 2, 8>;
|
||||
def WFMXB : BinaryVRRc<"wfmxb", 0xE7E7, fmul, v128xb, v128xb, 4, 8>;
|
||||
}
|
||||
}
|
||||
|
||||
// Multiply and add.
|
||||
let Uses = [FPC] in {
|
||||
def VFMA : TernaryVRReFloatGeneric<"vfma", 0xE78F>;
|
||||
def VFMADB : TernaryVRRe<"vfmadb", 0xE78F, fma, v128db, v128db, 0, 3>;
|
||||
def WFMADB : TernaryVRRe<"wfmadb", 0xE78F, fma, v64db, v64db, 8, 3>;
|
||||
|
|
@ -1094,8 +1125,10 @@ let Predicates = [FeatureVector] in {
|
|||
def WFMASB : TernaryVRRe<"wfmasb", 0xE78F, fma, v32sb, v32sb, 8, 2>;
|
||||
def WFMAXB : TernaryVRRe<"wfmaxb", 0xE78F, fma, v128xb, v128xb, 8, 4>;
|
||||
}
|
||||
}
|
||||
|
||||
// Multiply and subtract.
|
||||
let Uses = [FPC] in {
|
||||
def VFMS : TernaryVRReFloatGeneric<"vfms", 0xE78E>;
|
||||
def VFMSDB : TernaryVRRe<"vfmsdb", 0xE78E, fms, v128db, v128db, 0, 3>;
|
||||
def WFMSDB : TernaryVRRe<"wfmsdb", 0xE78E, fms, v64db, v64db, 8, 3>;
|
||||
|
|
@ -1104,9 +1137,10 @@ let Predicates = [FeatureVector] in {
|
|||
def WFMSSB : TernaryVRRe<"wfmssb", 0xE78E, fms, v32sb, v32sb, 8, 2>;
|
||||
def WFMSXB : TernaryVRRe<"wfmsxb", 0xE78E, fms, v128xb, v128xb, 8, 4>;
|
||||
}
|
||||
}
|
||||
|
||||
// Negative multiply and add.
|
||||
let Predicates = [FeatureVectorEnhancements1] in {
|
||||
let Uses = [FPC], 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>;
|
||||
|
|
@ -1116,7 +1150,7 @@ let Predicates = [FeatureVector] in {
|
|||
}
|
||||
|
||||
// Negative multiply and subtract.
|
||||
let Predicates = [FeatureVectorEnhancements1] in {
|
||||
let Uses = [FPC], 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>;
|
||||
|
|
@ -1163,6 +1197,7 @@ let Predicates = [FeatureVector] in {
|
|||
}
|
||||
|
||||
// Square root.
|
||||
let Uses = [FPC] in {
|
||||
def VFSQ : UnaryVRRaFloatGeneric<"vfsq", 0xE7CE>;
|
||||
def VFSQDB : UnaryVRRa<"vfsqdb", 0xE7CE, fsqrt, v128db, v128db, 3, 0>;
|
||||
def WFSQDB : UnaryVRRa<"wfsqdb", 0xE7CE, fsqrt, v64db, v64db, 3, 8>;
|
||||
|
|
@ -1171,8 +1206,10 @@ let Predicates = [FeatureVector] in {
|
|||
def WFSQSB : UnaryVRRa<"wfsqsb", 0xE7CE, fsqrt, v32sb, v32sb, 2, 8>;
|
||||
def WFSQXB : UnaryVRRa<"wfsqxb", 0xE7CE, fsqrt, v128xb, v128xb, 4, 8>;
|
||||
}
|
||||
}
|
||||
|
||||
// Subtract.
|
||||
let Uses = [FPC] in {
|
||||
def VFS : BinaryVRRcFloatGeneric<"vfs", 0xE7E2>;
|
||||
def VFSDB : BinaryVRRc<"vfsdb", 0xE7E2, fsub, v128db, v128db, 3, 0>;
|
||||
def WFSDB : BinaryVRRc<"wfsdb", 0xE7E2, fsub, v64db, v64db, 3, 8>;
|
||||
|
|
@ -1181,6 +1218,7 @@ let Predicates = [FeatureVector] in {
|
|||
def WFSSB : BinaryVRRc<"wfssb", 0xE7E2, fsub, v32sb, v32sb, 2, 8>;
|
||||
def WFSXB : BinaryVRRc<"wfsxb", 0xE7E2, fsub, v128xb, v128xb, 4, 8>;
|
||||
}
|
||||
}
|
||||
|
||||
// Test data class immediate.
|
||||
let Defs = [CC] in {
|
||||
|
|
@ -1201,7 +1239,7 @@ let Predicates = [FeatureVector] in {
|
|||
|
||||
let Predicates = [FeatureVector] in {
|
||||
// Compare scalar.
|
||||
let Defs = [CC] in {
|
||||
let Uses = [FPC], Defs = [CC] in {
|
||||
def WFC : CompareVRRaFloatGeneric<"wfc", 0xE7CB>;
|
||||
def WFCDB : CompareVRRa<"wfcdb", 0xE7CB, z_fcmp, v64db, 3>;
|
||||
let Predicates = [FeatureVectorEnhancements1] in {
|
||||
|
|
@ -1211,7 +1249,7 @@ let Predicates = [FeatureVector] in {
|
|||
}
|
||||
|
||||
// Compare and signal scalar.
|
||||
let Defs = [CC] in {
|
||||
let Uses = [FPC], Defs = [CC] in {
|
||||
def WFK : CompareVRRaFloatGeneric<"wfk", 0xE7CA>;
|
||||
def WFKDB : CompareVRRa<"wfkdb", 0xE7CA, null_frag, v64db, 3>;
|
||||
let Predicates = [FeatureVectorEnhancements1] in {
|
||||
|
|
@ -1221,6 +1259,7 @@ let Predicates = [FeatureVector] in {
|
|||
}
|
||||
|
||||
// Compare equal.
|
||||
let Uses = [FPC] in {
|
||||
def VFCE : BinaryVRRcSPairFloatGeneric<"vfce", 0xE7E8>;
|
||||
defm VFCEDB : BinaryVRRcSPair<"vfcedb", 0xE7E8, z_vfcmpe, z_vfcmpes,
|
||||
v128g, v128db, 3, 0>;
|
||||
|
|
@ -1234,9 +1273,10 @@ let Predicates = [FeatureVector] in {
|
|||
defm WFCEXB : BinaryVRRcSPair<"wfcexb", 0xE7E8, null_frag, null_frag,
|
||||
v128q, v128xb, 4, 8>;
|
||||
}
|
||||
}
|
||||
|
||||
// Compare and signal equal.
|
||||
let Predicates = [FeatureVectorEnhancements1] in {
|
||||
let Uses = [FPC], 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,
|
||||
|
|
@ -1250,6 +1290,7 @@ let Predicates = [FeatureVector] in {
|
|||
}
|
||||
|
||||
// Compare high.
|
||||
let Uses = [FPC] in {
|
||||
def VFCH : BinaryVRRcSPairFloatGeneric<"vfch", 0xE7EB>;
|
||||
defm VFCHDB : BinaryVRRcSPair<"vfchdb", 0xE7EB, z_vfcmph, z_vfcmphs,
|
||||
v128g, v128db, 3, 0>;
|
||||
|
|
@ -1263,9 +1304,10 @@ let Predicates = [FeatureVector] in {
|
|||
defm WFCHXB : BinaryVRRcSPair<"wfchxb", 0xE7EB, null_frag, null_frag,
|
||||
v128q, v128xb, 4, 8>;
|
||||
}
|
||||
}
|
||||
|
||||
// Compare and signal high.
|
||||
let Predicates = [FeatureVectorEnhancements1] in {
|
||||
let Uses = [FPC], 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,
|
||||
|
|
@ -1279,6 +1321,7 @@ let Predicates = [FeatureVector] in {
|
|||
}
|
||||
|
||||
// Compare high or equal.
|
||||
let Uses = [FPC] in {
|
||||
def VFCHE : BinaryVRRcSPairFloatGeneric<"vfche", 0xE7EA>;
|
||||
defm VFCHEDB : BinaryVRRcSPair<"vfchedb", 0xE7EA, z_vfcmphe, z_vfcmphes,
|
||||
v128g, v128db, 3, 0>;
|
||||
|
|
@ -1292,9 +1335,10 @@ let Predicates = [FeatureVector] in {
|
|||
defm WFCHEXB : BinaryVRRcSPair<"wfchexb", 0xE7EA, null_frag, null_frag,
|
||||
v128q, v128xb, 4, 8>;
|
||||
}
|
||||
}
|
||||
|
||||
// Compare and signal high or equal.
|
||||
let Predicates = [FeatureVectorEnhancements1] in {
|
||||
let Uses = [FPC], 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,
|
||||
|
|
|
|||
|
|
@ -191,6 +191,9 @@ SystemZRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
|||
Reserved.set(SystemZ::A0);
|
||||
Reserved.set(SystemZ::A1);
|
||||
|
||||
// FPC is the floating-point control register.
|
||||
Reserved.set(SystemZ::FPC);
|
||||
|
||||
return Reserved;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -295,6 +295,13 @@ def CC : SystemZReg<"cc">;
|
|||
let isAllocatable = 0, CopyCost = -1 in
|
||||
def CCR : RegisterClass<"SystemZ", [i32], 32, (add CC)>;
|
||||
|
||||
// The floating-point control register.
|
||||
// Note: We only model the current rounding modes and the IEEE masks.
|
||||
// IEEE flags and DXC are not modeled here.
|
||||
def FPC : SystemZReg<"fpc">;
|
||||
let isAllocatable = 0 in
|
||||
def FPCRegs : RegisterClass<"SystemZ", [i32], 32, (add FPC)>;
|
||||
|
||||
// Access registers.
|
||||
class ACR32<bits<16> num, string n> : SystemZReg<n> {
|
||||
let HWEncoding = num;
|
||||
|
|
|
|||
|
|
@ -181,11 +181,11 @@ body: |
|
|||
J %bb.3
|
||||
|
||||
bb.3:
|
||||
WFCDB undef %46, %45, implicit-def $cc
|
||||
WFCDB undef %46, %45, implicit-def $cc, implicit $fpc
|
||||
%48 = IPM implicit killed $cc
|
||||
%48 = AFIMux %48, 268435456, implicit-def dead $cc
|
||||
%6 = RISBMux undef %6, %48, 31, 159, 35
|
||||
WFCDB undef %50, %45, implicit-def $cc
|
||||
WFCDB undef %50, %45, implicit-def $cc, implicit $fpc
|
||||
BRC 15, 6, %bb.1, implicit killed $cc
|
||||
J %bb.4
|
||||
|
||||
|
|
|
|||
|
|
@ -401,7 +401,7 @@ body: |
|
|||
BRC 14, 6, %bb.29, implicit killed $cc
|
||||
|
||||
bb.28:
|
||||
%130 = CDFBR %60
|
||||
%130 = CDFBR %60, implicit $fpc
|
||||
J %bb.30
|
||||
|
||||
bb.29:
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ body: |
|
|||
|
||||
%47:fp32bit = VL32 %64, 4, $noreg :: (load 4 from %ir.scevgep5)
|
||||
%25:gr64bit = LA %64, 4, $noreg
|
||||
CEBR %47, undef %48:fp32bit, implicit-def $cc
|
||||
CEBR %47, undef %48:fp32bit, implicit-def $cc, implicit $fpc
|
||||
%62:grx32bit = LOCRMux %62, %65, 15, 4, implicit $cc
|
||||
%61:grx32bit = LOCRMux %61, %10.subreg_l32, 15, 4, implicit killed $cc
|
||||
%65:grx32bit = AHIMux %65, 1, implicit-def dead $cc
|
||||
|
|
|
|||
|
|
@ -85,8 +85,8 @@ body: |
|
|||
%6:fp32bit = SelectVR32 %3, %4, 15, 7, implicit $cc
|
||||
DBG_VALUE %6, $noreg, !7, !DIExpression(), debug-location !9
|
||||
%7:fp32bit = SelectVR32 %1, %4, 15, 7, implicit $cc
|
||||
%8:fp32bit = AEBR %5, killed %6, implicit-def dead $cc
|
||||
%9:fp32bit = AEBR %8, killed %7, implicit-def dead $cc
|
||||
%8:fp32bit = AEBR %5, killed %6, implicit-def dead $cc, implicit $fpc
|
||||
%9:fp32bit = AEBR %8, killed %7, implicit-def dead $cc, implicit $fpc
|
||||
$f0s = COPY %9
|
||||
Return implicit $f0s
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ body: |
|
|||
bb.0.entry:
|
||||
liveins: $f0s, $r2d
|
||||
|
||||
LTEBRCompare $f0s, $f0s, implicit-def $cc
|
||||
LTEBRCompare $f0s, $f0s, implicit-def $cc, implicit $fpc
|
||||
$f2s = LER $f0s
|
||||
INLINEASM &"blah $0", 1, 9, $f2s
|
||||
CondReturn 15, 4, implicit $f0s, implicit $cc
|
||||
|
|
|
|||
|
|
@ -163,39 +163,39 @@ body: |
|
|||
STE %16, %1, 0, $noreg :: (volatile store 4 into %ir.ptr2)
|
||||
STE %17, %1, 0, $noreg :: (volatile store 4 into %ir.ptr2)
|
||||
STE %18, %1, 0, $noreg :: (volatile store 4 into %ir.ptr2)
|
||||
%19 = LDEBR %2
|
||||
%19 = LDEBR %2, implicit $fpc
|
||||
STD %19, %0, 0, $noreg :: (volatile store 8 into %ir.ptr1)
|
||||
%20 = LDEBR %3
|
||||
%20 = LDEBR %3, implicit $fpc
|
||||
STD %20, %0, 0, $noreg :: (volatile store 8 into %ir.ptr1)
|
||||
%21 = LDEBR %4
|
||||
%21 = LDEBR %4, implicit $fpc
|
||||
STD %21, %0, 0, $noreg :: (volatile store 8 into %ir.ptr1)
|
||||
%22 = LDEBR %5
|
||||
%22 = LDEBR %5, implicit $fpc
|
||||
STD %22, %0, 0, $noreg :: (volatile store 8 into %ir.ptr1)
|
||||
%23 = LDEBR %6
|
||||
%23 = LDEBR %6, implicit $fpc
|
||||
STD %23, %0, 0, $noreg :: (volatile store 8 into %ir.ptr1)
|
||||
%24 = LDEBR %7
|
||||
%24 = LDEBR %7, implicit $fpc
|
||||
STD %24, %0, 0, $noreg :: (volatile store 8 into %ir.ptr1)
|
||||
%25 = LDEBR %8
|
||||
%25 = LDEBR %8, implicit $fpc
|
||||
STD %25, %0, 0, $noreg :: (volatile store 8 into %ir.ptr1)
|
||||
%26 = LDEBR %9
|
||||
%26 = LDEBR %9, implicit $fpc
|
||||
STD %26, %0, 0, $noreg :: (volatile store 8 into %ir.ptr1)
|
||||
%27 = LDEBR %10
|
||||
%27 = LDEBR %10, implicit $fpc
|
||||
STD %27, %0, 0, $noreg :: (volatile store 8 into %ir.ptr1)
|
||||
%28 = LDEBR %11
|
||||
%28 = LDEBR %11, implicit $fpc
|
||||
STD %28, %0, 0, $noreg :: (volatile store 8 into %ir.ptr1)
|
||||
%29 = LDEBR %12
|
||||
%29 = LDEBR %12, implicit $fpc
|
||||
STD %29, %0, 0, $noreg :: (volatile store 8 into %ir.ptr1)
|
||||
%30 = LDEBR %13
|
||||
%30 = LDEBR %13, implicit $fpc
|
||||
STD %30, %0, 0, $noreg :: (volatile store 8 into %ir.ptr1)
|
||||
%31 = LDEBR %14
|
||||
%31 = LDEBR %14, implicit $fpc
|
||||
STD %31, %0, 0, $noreg :: (volatile store 8 into %ir.ptr1)
|
||||
%32 = LDEBR %15
|
||||
%32 = LDEBR %15, implicit $fpc
|
||||
STD %32, %0, 0, $noreg :: (volatile store 8 into %ir.ptr1)
|
||||
%33 = LDEBR %16
|
||||
%33 = LDEBR %16, implicit $fpc
|
||||
STD %33, %0, 0, $noreg :: (volatile store 8 into %ir.ptr1)
|
||||
%34 = LDEBR %17
|
||||
%34 = LDEBR %17, implicit $fpc
|
||||
STD %34, %0, 0, $noreg :: (volatile store 8 into %ir.ptr1)
|
||||
%35 = LDEBR %18
|
||||
%35 = LDEBR %18, implicit $fpc
|
||||
STD %35, %0, 0, $noreg :: (volatile store 8 into %ir.ptr1)
|
||||
Return
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue