From 2aeb4771a6ca0ee253e4836edbab5705203d9bb4 Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Mon, 7 Oct 2013 16:36:15 +0000 Subject: [AArch64] Add support for NEON scalar arithmetic instructions: SQDMULH, SQRDMULH, FMULX, FRECPS, and FRSQRTS. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192107 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/CodeGen/AArch64/neon-scalar-mul.ll | 70 ++++++++++++++++++++++ test/CodeGen/AArch64/neon-scalar-recip.ll | 47 +++++++++++++++ test/MC/AArch64/neon-diagnostics.s | 68 +++++++++++++++++++++ test/MC/AArch64/neon-scalar-mul.s | 33 ++++++++++ test/MC/AArch64/neon-scalar-recip.s | 23 +++++++ test/MC/Disassembler/AArch64/neon-instructions.txt | 40 +++++++++++++ 6 files changed, 281 insertions(+) create mode 100644 test/CodeGen/AArch64/neon-scalar-mul.ll create mode 100644 test/CodeGen/AArch64/neon-scalar-recip.ll create mode 100644 test/MC/AArch64/neon-scalar-mul.s create mode 100644 test/MC/AArch64/neon-scalar-recip.s (limited to 'test') diff --git a/test/CodeGen/AArch64/neon-scalar-mul.ll b/test/CodeGen/AArch64/neon-scalar-mul.ll new file mode 100644 index 0000000000..6914a08135 --- /dev/null +++ b/test/CodeGen/AArch64/neon-scalar-mul.ll @@ -0,0 +1,70 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+neon < %s | FileCheck %s + +define i16 @test_vqdmulhh_s16(i16 %a, i16 %b) { +; CHECK: test_vqdmulhh_s16 +; CHECK: sqdmulh {{h[0-9]+}}, {{h[0-9]+}}, {{h[0-9]+}} + %1 = insertelement <1 x i16> undef, i16 %a, i32 0 + %2 = insertelement <1 x i16> undef, i16 %b, i32 0 + %3 = call <1 x i16> @llvm.arm.neon.vqdmulh.v1i16(<1 x i16> %1, <1 x i16> %2) + %4 = extractelement <1 x i16> %3, i32 0 + ret i16 %4 +} + +define i32 @test_vqdmulhs_s32(i32 %a, i32 %b) { +; CHECK: test_vqdmulhs_s32 +; CHECK: sqdmulh {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} + %1 = insertelement <1 x i32> undef, i32 %a, i32 0 + %2 = insertelement <1 x i32> undef, i32 %b, i32 0 + %3 = call <1 x i32> @llvm.arm.neon.vqdmulh.v1i32(<1 x i32> %1, <1 x i32> %2) + %4 = extractelement <1 x i32> %3, i32 0 + ret i32 %4 +} + +declare <1 x i16> @llvm.arm.neon.vqdmulh.v1i16(<1 x i16>, <1 x i16>) +declare <1 x i32> @llvm.arm.neon.vqdmulh.v1i32(<1 x i32>, <1 x i32>) + +define i16 @test_vqrdmulhh_s16(i16 %a, i16 %b) { +; CHECK: test_vqrdmulhh_s16 +; CHECK: sqrdmulh {{h[0-9]+}}, {{h[0-9]+}}, {{h[0-9]+}} + %1 = insertelement <1 x i16> undef, i16 %a, i32 0 + %2 = insertelement <1 x i16> undef, i16 %b, i32 0 + %3 = call <1 x i16> @llvm.arm.neon.vqrdmulh.v1i16(<1 x i16> %1, <1 x i16> %2) + %4 = extractelement <1 x i16> %3, i32 0 + ret i16 %4 +} + +define i32 @test_vqrdmulhs_s32(i32 %a, i32 %b) { +; CHECK: test_vqrdmulhs_s32 +; CHECK: sqrdmulh {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} + %1 = insertelement <1 x i32> undef, i32 %a, i32 0 + %2 = insertelement <1 x i32> undef, i32 %b, i32 0 + %3 = call <1 x i32> @llvm.arm.neon.vqrdmulh.v1i32(<1 x i32> %1, <1 x i32> %2) + %4 = extractelement <1 x i32> %3, i32 0 + ret i32 %4 +} + +declare <1 x i16> @llvm.arm.neon.vqrdmulh.v1i16(<1 x i16>, <1 x i16>) +declare <1 x i32> @llvm.arm.neon.vqrdmulh.v1i32(<1 x i32>, <1 x i32>) + +define float @test_vmulxs_f32(float %a, float %b) { +; CHECK: test_vmulxs_f32 +; CHECK: fmulx {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} + %1 = insertelement <1 x float> undef, float %a, i32 0 + %2 = insertelement <1 x float> undef, float %b, i32 0 + %3 = call <1 x float> @llvm.aarch64.neon.vmulx.v1f32(<1 x float> %1, <1 x float> %2) + %4 = extractelement <1 x float> %3, i32 0 + ret float %4 +} + +define double @test_vmulxd_f64(double %a, double %b) { +; CHECK: test_vmulxd_f64 +; CHECK: fmulx {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} + %1 = insertelement <1 x double> undef, double %a, i32 0 + %2 = insertelement <1 x double> undef, double %b, i32 0 + %3 = call <1 x double> @llvm.aarch64.neon.vmulx.v1f64(<1 x double> %1, <1 x double> %2) + %4 = extractelement <1 x double> %3, i32 0 + ret double %4 +} + +declare <1 x float> @llvm.aarch64.neon.vmulx.v1f32(<1 x float>, <1 x float>) +declare <1 x double> @llvm.aarch64.neon.vmulx.v1f64(<1 x double>, <1 x double>) diff --git a/test/CodeGen/AArch64/neon-scalar-recip.ll b/test/CodeGen/AArch64/neon-scalar-recip.ll new file mode 100644 index 0000000000..91ee12c9fe --- /dev/null +++ b/test/CodeGen/AArch64/neon-scalar-recip.ll @@ -0,0 +1,47 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+neon < %s | FileCheck %s + +define float @test_vrecpss_f32(float %a, float %b) { +; CHECK: test_vrecpss_f32 +; CHECK: frecps {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} + %1 = insertelement <1 x float> undef, float %a, i32 0 + %2 = insertelement <1 x float> undef, float %b, i32 0 + %3 = call <1 x float> @llvm.arm.neon.vrecps.v1f32(<1 x float> %1, <1 x float> %2) + %4 = extractelement <1 x float> %3, i32 0 + ret float %4 +} + +define double @test_vrecpsd_f64(double %a, double %b) { +; CHECK: test_vrecpsd_f64 +; CHECK: frecps {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} + %1 = insertelement <1 x double> undef, double %a, i32 0 + %2 = insertelement <1 x double> undef, double %b, i32 0 + %3 = call <1 x double> @llvm.arm.neon.vrecps.v1f64(<1 x double> %1, <1 x double> %2) + %4 = extractelement <1 x double> %3, i32 0 + ret double %4 +} + +declare <1 x float> @llvm.arm.neon.vrecps.v1f32(<1 x float>, <1 x float>) +declare <1 x double> @llvm.arm.neon.vrecps.v1f64(<1 x double>, <1 x double>) + +define float @test_vrsqrtss_f32(float %a, float %b) { +; CHECK: test_vrsqrtss_f32 +; CHECK: frsqrts {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} + %1 = insertelement <1 x float> undef, float %a, i32 0 + %2 = insertelement <1 x float> undef, float %b, i32 0 + %3 = call <1 x float> @llvm.arm.neon.vrsqrts.v1f32(<1 x float> %1, <1 x float> %2) + %4 = extractelement <1 x float> %3, i32 0 + ret float %4 +} + +define double @test_vrsqrtsd_f64(double %a, double %b) { +; CHECK: test_vrsqrtsd_f64 +; CHECK: frsqrts {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} + %1 = insertelement <1 x double> undef, double %a, i32 0 + %2 = insertelement <1 x double> undef, double %b, i32 0 + %3 = call <1 x double> @llvm.arm.neon.vrsqrts.v1f64(<1 x double> %1, <1 x double> %2) + %4 = extractelement <1 x double> %3, i32 0 + ret double %4 +} + +declare <1 x float> @llvm.arm.neon.vrsqrts.v1f32(<1 x float>, <1 x float>) +declare <1 x double> @llvm.arm.neon.vrsqrts.v1f64(<1 x double>, <1 x double>) diff --git a/test/MC/AArch64/neon-diagnostics.s b/test/MC/AArch64/neon-diagnostics.s index a86796ff2a..be5a871c50 100644 --- a/test/MC/AArch64/neon-diagnostics.s +++ b/test/MC/AArch64/neon-diagnostics.s @@ -826,6 +826,33 @@ // CHECK-ERROR: uqsub h1, h2, d2 // CHECK-ERROR: ^ +//---------------------------------------------------------------------- +// Scalar Integer Saturating Doubling Multiply Half High (Signed) +//---------------------------------------------------------------------- + + sqdmulh h10, s11, h12 + sqdmulh s20, h21, s2 + +// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: sqdmulh h10, s11, h12 +// CHECK-ERROR: ^ +// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: sqdmulh s20, h21, s2 +// CHECK-ERROR: ^ + +//------------------------------------------------------------------------ +// Scalar Integer Saturating Rounding Doubling Multiply Half High (Signed) +//------------------------------------------------------------------------ + + sqrdmulh h10, s11, h12 + sqrdmulh s20, h21, s2 + +// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: sqrdmulh h10, s11, h12 +// CHECK-ERROR: ^ +// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: sqrdmulh s20, h21, s2 +// CHECK-ERROR: ^ //---------------------------------------------------------------------- // Vector Shift Left (Signed and Unsigned Integer) @@ -3771,3 +3798,44 @@ // CHECK-ERROR: fminv d0, v1.2d // CHECK-ERROR: ^ +//---------------------------------------------------------------------- +// Floating-point Multiply Extended +//---------------------------------------------------------------------- + + fmulx s20, h22, s15 + fmulx d23, d11, s1 + +// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: fmulx s20, h22, s15 +// CHECK-ERROR: ^ +// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: fmulx d23, d11, s1 +// CHECK-ERROR: ^ + +//---------------------------------------------------------------------- +// Floating-point Reciprocal Step +//---------------------------------------------------------------------- + + frecps s21, s16, h13 + frecps d22, s30, d21 + +// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: frecps s21, s16, h13 +// CHECK-ERROR: ^ +// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: frecps d22, s30, d21 +// CHECK-ERROR: ^ + +//---------------------------------------------------------------------- +// Floating-point Reciprocal Square Root Step +//---------------------------------------------------------------------- + + frsqrts s21, h5, s12 + frsqrts d8, s22, d18 + +// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: frsqrts s21, h5, s12 +// CHECK-ERROR: ^ +// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: frsqrts d8, s22, d18 +// CHECK-ERROR: ^ diff --git a/test/MC/AArch64/neon-scalar-mul.s b/test/MC/AArch64/neon-scalar-mul.s new file mode 100644 index 0000000000..8caddb4cc5 --- /dev/null +++ b/test/MC/AArch64/neon-scalar-mul.s @@ -0,0 +1,33 @@ +// RUN: llvm-mc -triple aarch64-none-linux-gnu -mattr=+neon -show-encoding < %s | FileCheck %s + +// Check that the assembler can handle the documented syntax for AArch64 + +//---------------------------------------------------------------------- +// Scalar Integer Saturating Doubling Multiply Half High +//---------------------------------------------------------------------- + + sqdmulh h10, h11, h12 + sqdmulh s20, s21, s2 + +// CHECK: sqdmulh h10, h11, h12 // encoding: [0x6a,0xb5,0x6c,0x5e] +// CHECK: sqdmulh s20, s21, s2 // encoding: [0xb4,0xb6,0xa2,0x5e] + +//---------------------------------------------------------------------- +// Scalar Integer Saturating Rounding Doubling Multiply Half High +//---------------------------------------------------------------------- + + sqrdmulh h10, h11, h12 + sqrdmulh s20, s21, s2 + +// CHECK: sqrdmulh h10, h11, h12 // encoding: [0x6a,0xb5,0x6c,0x7e] +// CHECK: sqrdmulh s20, s21, s2 // encoding: [0xb4,0xb6,0xa2,0x7e] + +//---------------------------------------------------------------------- +// Floating-point Multiply Extended +//---------------------------------------------------------------------- + + fmulx s20, s22, s15 + fmulx d23, d11, d1 + +// CHECK: fmulx s20, s22, s15 // encoding: [0xd4,0xde,0x2f,0x5e] +// CHECK: fmulx d23, d11, d1 // encoding: [0x77,0xdd,0x61,0x5e] diff --git a/test/MC/AArch64/neon-scalar-recip.s b/test/MC/AArch64/neon-scalar-recip.s new file mode 100644 index 0000000000..bb9c170607 --- /dev/null +++ b/test/MC/AArch64/neon-scalar-recip.s @@ -0,0 +1,23 @@ +// RUN: llvm-mc -triple aarch64-none-linux-gnu -mattr=+neon -show-encoding < %s | FileCheck %s + +// Check that the assembler can handle the documented syntax for AArch64 + +//---------------------------------------------------------------------- +// Floating-point Reciprocal Step +//---------------------------------------------------------------------- + + frecps s21, s16, s13 + frecps d22, d30, d21 + +// CHECK: frecps s21, s16, s13 // encoding: [0x15,0xfe,0x2d,0x5e] +// CHECK: frecps d22, d30, d21 // encoding: [0xd6,0xff,0x75,0x5e] + +//---------------------------------------------------------------------- +// Floating-point Reciprocal Square Root Step +//---------------------------------------------------------------------- + + frsqrts s21, s5, s12 + frsqrts d8, d22, d18 + +// CHECK: frsqrts s21, s5, s12 // encoding: [0xb5,0xfc,0xac,0x5e] +// CHECK: frsqrts d8, d22, d18 // encoding: [0xc8,0xfe,0xf2,0x5e] diff --git a/test/MC/Disassembler/AArch64/neon-instructions.txt b/test/MC/Disassembler/AArch64/neon-instructions.txt index ecb6249faf..5057ecdd50 100644 --- a/test/MC/Disassembler/AArch64/neon-instructions.txt +++ b/test/MC/Disassembler/AArch64/neon-instructions.txt @@ -1452,3 +1452,43 @@ 0x20 0x60 0x22 0x6e 0x20 0x60 0x62 0x6e 0x20 0x60 0xa2 0x6e + +#---------------------------------------------------------------------- +# Scalar Integer Saturating Doubling Multiply Half High +#---------------------------------------------------------------------- +# CHECK: sqdmulh h10, h11, h12 +# CHECK: sqdmulh s20, s21, s2 +0x6a,0xb5,0x6c,0x5e +0xb4,0xb6,0xa2,0x5e + +#---------------------------------------------------------------------- +# Scalar Integer Saturating Rounding Doubling Multiply Half High +#---------------------------------------------------------------------- +# CHECK: sqrdmulh h10, h11, h12 +# CHECK: sqrdmulh s20, s21, s2 +0x6a,0xb5,0x6c,0x7e +0xb4,0xb6,0xa2,0x7e + +#---------------------------------------------------------------------- +# Floating-point multiply extended +#---------------------------------------------------------------------- +# CHECK: fmulx s20, s22, s15 +# CHECK: fmulx d23, d11, d1 +0xd4,0xde,0x2f,0x5e +0x77,0xdd,0x61,0x5e + +#---------------------------------------------------------------------- +# Floating-point Reciprocal Step +#---------------------------------------------------------------------- +# CHECK: frecps s21, s16, s13 +# CHECK: frecps d22, d30, d21 +0x15,0xfe,0x2d,0x5e +0xd6,0xff,0x75,0x5e + +#---------------------------------------------------------------------- +# Floating-point Reciprocal Square Root Step +#---------------------------------------------------------------------- +# CHECK: frsqrts s21, s5, s12 +# CHECK: frsqrts d8, d22, d18 +0xb5,0xfc,0xac,0x5e +0xc8,0xfe,0xf2,0x5e -- cgit v1.2.3