From 3dfe644f7b6a560e1991b03d8c419c973ac7ed8d Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Tue, 8 Oct 2013 20:43:30 +0000 Subject: [AArch64] Add support for NEON scalar signed/unsigned integer to floating-point convert instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192231 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/IntrinsicsAArch64.td | 12 ++++++ lib/Target/AArch64/AArch64InstrFormats.td | 16 +++++++ lib/Target/AArch64/AArch64InstrNEON.td | 36 ++++++++++++++++ test/CodeGen/AArch64/neon-scalar-cvt.ll | 49 ++++++++++++++++++++++ test/MC/AArch64/neon-scalar-cvt.s | 23 ++++++++++ test/MC/Disassembler/AArch64/neon-instructions.txt | 16 +++++++ 6 files changed, 152 insertions(+) create mode 100644 test/CodeGen/AArch64/neon-scalar-cvt.ll create mode 100644 test/MC/AArch64/neon-scalar-cvt.s diff --git a/include/llvm/IR/IntrinsicsAArch64.td b/include/llvm/IR/IntrinsicsAArch64.td index 526ebef..52810be 100644 --- a/include/llvm/IR/IntrinsicsAArch64.td +++ b/include/llvm/IR/IntrinsicsAArch64.td @@ -152,4 +152,16 @@ def int_aarch64_neon_vpfminnm : Intrinsic<[llvm_v1f32_ty], [llvm_v2f32_ty], [IntrNoMem]>; def int_aarch64_neon_vpfminnmq : Intrinsic<[llvm_v1f64_ty], [llvm_v2f64_ty], [IntrNoMem]>; + +// Scalar Signed Integer Convert To Floating-point +def int_aarch64_neon_vcvtf32_s32 : + Intrinsic<[llvm_v1f32_ty], [llvm_v1i32_ty], [IntrNoMem]>; +def int_aarch64_neon_vcvtf64_s64 : + Intrinsic<[llvm_v1f64_ty], [llvm_v1i64_ty], [IntrNoMem]>; + +// Scalar Unsigned Integer Convert To Floating-point +def int_aarch64_neon_vcvtf32_u32 : + Intrinsic<[llvm_v1f32_ty], [llvm_v1i32_ty], [IntrNoMem]>; +def int_aarch64_neon_vcvtf64_u64 : + Intrinsic<[llvm_v1f64_ty], [llvm_v1i64_ty], [IntrNoMem]>; } diff --git a/lib/Target/AArch64/AArch64InstrFormats.td b/lib/Target/AArch64/AArch64InstrFormats.td index fb87db6..5781578 100644 --- a/lib/Target/AArch64/AArch64InstrFormats.td +++ b/lib/Target/AArch64/AArch64InstrFormats.td @@ -1178,5 +1178,21 @@ class NeonI_2VAcross size, bits<5> opcode, // Inherit Rd in 4-0 } +// Format AdvSIMD scalar two registers miscellaneous +class NeonI_Scalar2SameMisc size, bits<5> opcode, dag outs, dag ins, + string asmstr, list patterns, InstrItinClass itin> + : A64InstRdn { + let Inst{31} = 0b0; + let Inst{30} = 0b1; + let Inst{29} = u; + let Inst{28-24} = 0b11110; + let Inst{23-22} = size; + let Inst{21-17} = 0b10000; + let Inst{16-12} = opcode; + let Inst{11-10} = 0b10; + // Inherit Rn in 9-5 + // Inherit Rd in 4-0 +} + } diff --git a/lib/Target/AArch64/AArch64InstrNEON.td b/lib/Target/AArch64/AArch64InstrNEON.td index e4c946b..b627171 100644 --- a/lib/Target/AArch64/AArch64InstrNEON.td +++ b/lib/Target/AArch64/AArch64InstrNEON.td @@ -3092,6 +3092,30 @@ multiclass Neon_Scalar3Same_SD_size_patterns; } +// Scalar Two Registers Miscellaneous + +multiclass NeonI_Scalar2SameMisc_SD_size opcode, + string asmop> { + def ss : NeonI_Scalar2SameMisc; + def dd : NeonI_Scalar2SameMisc; +} + +multiclass Neon_Scalar2SameMisc_SD_size_patterns { + def : Pat<(v1f32 (Sopnode (v1i32 FPR32:$Rn))), + (INSTS FPR32:$Rn)>; + def : Pat<(v1f64 (Dopnode (v1i64 FPR64:$Rn))), + (INSTD FPR64:$Rn)>; +} + // Scalar Integer Add let isCommutable = 1 in { def ADDddd : NeonI_Scalar3Same_D_size<0b0, 0b10000, "add">; @@ -3232,6 +3256,18 @@ defm : Neon_Scalar3Same_BHSD_size_patterns; defm : Neon_Scalar3Same_D_size_patterns; +// Scalar Signed Integer Convert To Floating-point +defm SCVTF : NeonI_Scalar2SameMisc_SD_size<0b0, 0b0, 0b11101, "scvtf">; +defm : Neon_Scalar2SameMisc_SD_size_patterns; + +// Scalar Unsigned Integer Convert To Floating-point +defm UCVTF : NeonI_Scalar2SameMisc_SD_size<0b1, 0b0, 0b11101, "ucvtf">; +defm : Neon_Scalar2SameMisc_SD_size_patterns; + // Scalar Reduce Pairwise multiclass NeonI_ScalarPair_D_sizes opcode, diff --git a/test/CodeGen/AArch64/neon-scalar-cvt.ll b/test/CodeGen/AArch64/neon-scalar-cvt.ll new file mode 100644 index 0000000..0d9fdf3 --- /dev/null +++ b/test/CodeGen/AArch64/neon-scalar-cvt.ll @@ -0,0 +1,49 @@ +; RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+neon < %s | FileCheck %s + +define float @test_vcvts_f32_s32(i32 %a) { +; CHECK: test_vcvts_f32_s32 +; CHECK: scvtf {{s[0-9]+}}, {{s[0-9]+}} +entry: + %vcvtf.i = insertelement <1 x i32> undef, i32 %a, i32 0 + %vcvtf1.i = tail call <1 x float> @llvm.aarch64.neon.vcvtf32.s32(<1 x i32> %vcvtf.i) + %0 = extractelement <1 x float> %vcvtf1.i, i32 0 + ret float %0 +} + +declare <1 x float> @llvm.aarch64.neon.vcvtf32.s32(<1 x i32>) + +define double @test_vcvtd_f64_s64(i64 %a) { +; CHECK: test_vcvtd_f64_s64 +; CHECK: scvtf {{d[0-9]+}}, {{d[0-9]+}} +entry: + %vcvtf.i = insertelement <1 x i64> undef, i64 %a, i32 0 + %vcvtf1.i = tail call <1 x double> @llvm.aarch64.neon.vcvtf64.s64(<1 x i64> %vcvtf.i) + %0 = extractelement <1 x double> %vcvtf1.i, i32 0 + ret double %0 +} + +declare <1 x double> @llvm.aarch64.neon.vcvtf64.s64(<1 x i64>) + +define float @test_vcvts_f32_u32(i32 %a) { +; CHECK: test_vcvts_f32_u32 +; CHECK: ucvtf {{s[0-9]+}}, {{s[0-9]+}} +entry: + %vcvtf.i = insertelement <1 x i32> undef, i32 %a, i32 0 + %vcvtf1.i = tail call <1 x float> @llvm.aarch64.neon.vcvtf32.u32(<1 x i32> %vcvtf.i) + %0 = extractelement <1 x float> %vcvtf1.i, i32 0 + ret float %0 +} + +declare <1 x float> @llvm.aarch64.neon.vcvtf32.u32(<1 x i32>) + +define double @test_vcvtd_f64_u64(i64 %a) { +; CHECK: test_vcvtd_f64_u64 +; CHECK: ucvtf {{d[0-9]+}}, {{d[0-9]+}} +entry: + %vcvtf.i = insertelement <1 x i64> undef, i64 %a, i32 0 + %vcvtf1.i = tail call <1 x double> @llvm.aarch64.neon.vcvtf64.u64(<1 x i64> %vcvtf.i) + %0 = extractelement <1 x double> %vcvtf1.i, i32 0 + ret double %0 +} + +declare <1 x double> @llvm.aarch64.neon.vcvtf64.u64(<1 x i64>) diff --git a/test/MC/AArch64/neon-scalar-cvt.s b/test/MC/AArch64/neon-scalar-cvt.s new file mode 100644 index 0000000..07faef7 --- /dev/null +++ b/test/MC/AArch64/neon-scalar-cvt.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 + +//---------------------------------------------------------------------- +// Scalar Signed Integer Convert To Floating-point +//---------------------------------------------------------------------- + + scvtf s22, s13 + scvtf d21, d12 + +// CHECK: scvtf s22, s13 // encoding: [0xb6,0xd9,0x21,0x5e] +// CHECK: scvtf d21, d12 // encoding: [0x95,0xd9,0x61,0x5e] + +//---------------------------------------------------------------------- +// Scalar Unsigned Integer Convert To Floating-point +//---------------------------------------------------------------------- + + ucvtf s22, s13 + ucvtf d21, d14 + +// CHECK: ucvtf s22, s13 // encoding: [0xb6,0xd9,0x21,0x7e] +// CHECK: ucvtf d21, d14 // encoding: [0xd5,0xd9,0x61,0x7e] diff --git a/test/MC/Disassembler/AArch64/neon-instructions.txt b/test/MC/Disassembler/AArch64/neon-instructions.txt index 5057ecd..7d7d795 100644 --- a/test/MC/Disassembler/AArch64/neon-instructions.txt +++ b/test/MC/Disassembler/AArch64/neon-instructions.txt @@ -1492,3 +1492,19 @@ # CHECK: frsqrts d8, d22, d18 0xb5,0xfc,0xac,0x5e 0xc8,0xfe,0xf2,0x5e + +#---------------------------------------------------------------------- +# Scalar Signed Integer Convert To Floating-point +#---------------------------------------------------------------------- +# CHECK: scvtf s22, s13 +# CHECK: scvtf d21, d12 +0xb6,0xd9,0x21,0x5e +0x95,0xd9,0x61,0x5e + +#---------------------------------------------------------------------- +# Scalar Unsigned Integer Convert To Floating-point +#---------------------------------------------------------------------- +# CHECK: ucvtf s22, s13 +# CHECK: ucvtf d21, d14 +0xb6,0xd9,0x21,0x7e +0xd5,0xd9,0x61,0x7e -- cgit v1.1