diff options
| author | Oliver Stannard <oliver.stannard@arm.com> | 2018-09-27 13:32:06 +0000 | 
|---|---|---|
| committer | Oliver Stannard <oliver.stannard@arm.com> | 2018-09-27 13:32:06 +0000 | 
| commit | ddb7d46aa53c2eeff3b07427f9c1e776332b8837 (patch) | |
| tree | c848869243f7dda615fcf38209a94e43dd079e57 /llvm/lib | |
| parent | 30183093abf2b7d563c1c233a89aa3e115e4109c (diff) | |
| download | bcm5719-llvm-ddb7d46aa53c2eeff3b07427f9c1e776332b8837.tar.gz bcm5719-llvm-ddb7d46aa53c2eeff3b07427f9c1e776332b8837.zip  | |
[AArch64][v8.5A] Add FRINT[32,64][Z,X] instructions
These are some new variants of the "Floating-point Round to Integral"
family of instructions, which round to the nearest floating-point value
which fits in a 32- or 64-bit integer.
Patch by Pablo Barrio!
Differential revision: https://reviews.llvm.org/D52475
llvm-svn: 343209
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64.td | 10 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrFormats.td | 37 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrInfo.td | 17 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64Subtarget.h | 2 | 
4 files changed, 63 insertions, 3 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td index 592c7e07b94..67b475de65a 100644 --- a/llvm/lib/Target/AArch64/AArch64.td +++ b/llvm/lib/Target/AArch64/AArch64.td @@ -207,6 +207,10 @@ def FeatureAggressiveFMA :  def FeatureAltFPCmp : SubtargetFeature<"altnzcv", "HasAlternativeNZCV", "true",    "Enable alternative NZCV format for floating point comparisons">; +def FeatureFRInt3264 : SubtargetFeature<"fptoint", "HasFRInt3264", "true", +  "Enable FRInt[32|64][Z|X] instructions that round a floating-point number to " +  "an integer (in FP format) forcing it to fit into a 32- or 64-bit int" >; +  //===----------------------------------------------------------------------===//  // Architectures.  // @@ -223,8 +227,10 @@ def HasV8_3aOps : SubtargetFeature<"v8.3a", "HasV8_3aOps", "true",  def HasV8_4aOps : SubtargetFeature<"v8.4a", "HasV8_4aOps", "true",    "Support ARM v8.4a instructions", [HasV8_3aOps, FeatureDotProd]>; -def HasV8_5aOps : SubtargetFeature<"v8.5a", "HasV8_5aOps", "true", -  "Support ARM v8.5a instructions", [HasV8_4aOps, FeatureAltFPCmp]>; +def HasV8_5aOps : SubtargetFeature< +  "v8.5a", "HasV8_5aOps", "true", "Support ARM v8.5a instructions", +  [HasV8_4aOps, FeatureAltFPCmp, FeatureFRInt3264] +>;  //===----------------------------------------------------------------------===//  // Register File Description diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td index 1ad87558b63..8a24650610e 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -4433,6 +4433,22 @@ multiclass SingleOperandFPData<bits<4> opcode, string asm,    }  } +multiclass SingleOperandFPNo16<bits<6> opcode, string asm, +                  SDPatternOperator node = null_frag>{ + +  def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { +    let Inst{23-22} = 0b00; // 32-bit registers +  } + +  def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { +    let Inst{23-22} = 0b01; // 64-bit registers +  } +} + +// FRInt[32|64][Z|N] instructions +multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> : +      SingleOperandFPNo16<{0b0100,opcode}, asm, node>; +  //---  // Two operand floating point data processing  //--- @@ -5308,7 +5324,7 @@ multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,                      [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;  } -// Supports only S and D element sizes, uses high bit of the size field +// Supports H, S and D element sizes, uses high bit of the size field  // as an extra opcode bit.  multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,                             SDPatternOperator OpNode> { @@ -5331,6 +5347,25 @@ multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,                            [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;  } +// Supports only S and D element sizes +multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm, +                           SDPatternOperator OpNode = null_frag> { + +  def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64, +                                asm, ".2s", ".2s", +                          [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; +  def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128, +                                asm, ".4s", ".4s", +                          [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; +  def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128, +                                asm, ".2d", ".2d", +                          [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; +} + +multiclass FRIntNNTVector<bit U, bit op, string asm, +                          SDPatternOperator OpNode = null_frag> : +           SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>; +  // Supports only S element size.  multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,                             SDPatternOperator OpNode> { diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 83bec32da79..d1daf6d7f76 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -64,6 +64,8 @@ def HasRCPC          : Predicate<"Subtarget->hasRCPC()">,                                   AssemblerPredicate<"FeatureRCPC", "rcpc">;  def HasAltNZCV       : Predicate<"Subtarget->hasAlternativeNZCV()">,                         AssemblerPredicate<"FeatureAltFPCmp", "altnzcv">; +def HasFRInt3264     : Predicate<"Subtarget->hasFRInt3264()">, +                       AssemblerPredicate<"FeatureFRInt3264", "frint3264">;  def IsLE             : Predicate<"Subtarget->isLittleEndian()">;  def IsBE             : Predicate<"!Subtarget->isLittleEndian()">;  def UseAlternateSExtLoadCVTF32 @@ -2939,6 +2941,13 @@ let SchedRW = [WriteFDiv] in {  defm FSQRT  : SingleOperandFPData<0b0011, "fsqrt", fsqrt>;  } +let Predicates = [HasFRInt3264] in { +  defm FRINT32Z : FRIntNNT<0b00, "frint32z">; +  defm FRINT64Z : FRIntNNT<0b10, "frint64z">; +  defm FRINT32X : FRIntNNT<0b01, "frint32x">; +  defm FRINT64X : FRIntNNT<0b11, "frint64x">; +} // HasFRInt3264 +  //===----------------------------------------------------------------------===//  // Floating point two operand instructions.  //===----------------------------------------------------------------------===// @@ -3157,6 +3166,14 @@ defm FRINTN : SIMDTwoVectorFP<0, 0, 0b11000, "frintn", int_aarch64_neon_frintn>;  defm FRINTP : SIMDTwoVectorFP<0, 1, 0b11000, "frintp", fceil>;  defm FRINTX : SIMDTwoVectorFP<1, 0, 0b11001, "frintx", frint>;  defm FRINTZ : SIMDTwoVectorFP<0, 1, 0b11001, "frintz", ftrunc>; + +let Predicates = [HasFRInt3264] in { +  defm FRINT32Z : FRIntNNTVector<0, 0, "frint32z">; +  defm FRINT64Z : FRIntNNTVector<0, 1, "frint64z">; +  defm FRINT32X : FRIntNNTVector<1, 0, "frint32x">; +  defm FRINT64X : FRIntNNTVector<1, 1, "frint64x">; +} // HasFRInt3264 +  defm FRSQRTE: SIMDTwoVectorFP<1, 1, 0b11101, "frsqrte", int_aarch64_neon_frsqrte>;  defm FSQRT  : SIMDTwoVectorFP<1, 1, 0b11111, "fsqrt", fsqrt>;  defm NEG    : SIMDTwoVectorBHSD<1, 0b01011, "neg", diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h index bf60a0fd269..fec338c1ab3 100644 --- a/llvm/lib/Target/AArch64/AArch64Subtarget.h +++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h @@ -96,6 +96,7 @@ protected:    // Armv8.5-A Extensions    bool HasAlternativeNZCV = false; +  bool HasFRInt3264 = false;    // HasZeroCycleRegMove - Has zero-cycle register mov instructions.    bool HasZeroCycleRegMove = false; @@ -310,6 +311,7 @@ public:    bool hasRCPC() const { return HasRCPC; }    bool hasAggressiveFMA() const { return HasAggressiveFMA; }    bool hasAlternativeNZCV() const { return HasAlternativeNZCV; } +  bool hasFRInt3264() const { return HasFRInt3264; }    bool isLittleEndian() const { return IsLittle; }  | 

