diff options
-rw-r--r-- | include/llvm/IR/IntrinsicsAArch64.td | 12 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64InstrFormats.td | 16 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64InstrNEON.td | 36 | ||||
-rw-r--r-- | test/CodeGen/AArch64/neon-scalar-cvt.ll | 49 | ||||
-rw-r--r-- | test/MC/AArch64/neon-scalar-cvt.s | 23 | ||||
-rw-r--r-- | test/MC/Disassembler/AArch64/neon-instructions.txt | 16 |
6 files changed, 152 insertions, 0 deletions
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<bit q, bit u, bits<2> size, bits<5> opcode, // Inherit Rd in 4-0 } +// Format AdvSIMD scalar two registers miscellaneous +class NeonI_Scalar2SameMisc<bit u, bits<2> size, bits<5> opcode, dag outs, dag ins, + string asmstr, list<dag> patterns, InstrItinClass itin> + : A64InstRdn<outs, ins, asmstr, patterns, itin> { + 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<SDPatternOperator opnode, (INSTD FPR64:$Rn, FPR64:$Rm)>; } +// Scalar Two Registers Miscellaneous + +multiclass NeonI_Scalar2SameMisc_SD_size<bit u, bit size_high, bits<5> opcode, + string asmop> { + def ss : NeonI_Scalar2SameMisc<u, {size_high, 0b0}, opcode, + (outs FPR32:$Rd), (ins FPR32:$Rn), + !strconcat(asmop, " $Rd, $Rn"), + [], NoItinerary>; + def dd : NeonI_Scalar2SameMisc<u, {size_high, 0b1}, opcode, + (outs FPR64:$Rd), (ins FPR64:$Rn), + !strconcat(asmop, " $Rd, $Rn"), + [], NoItinerary>; +} + +multiclass Neon_Scalar2SameMisc_SD_size_patterns<SDPatternOperator Sopnode, + SDPatternOperator Dopnode, + Instruction INSTS, + Instruction INSTD> { + 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<int_aarch64_neon_vqrshlu, UQRSHLbbb, defm : Neon_Scalar3Same_D_size_patterns<int_arm_neon_vqrshifts, SQRSHLddd>; defm : Neon_Scalar3Same_D_size_patterns<int_arm_neon_vqrshiftu, UQRSHLddd>; +// Scalar Signed Integer Convert To Floating-point +defm SCVTF : NeonI_Scalar2SameMisc_SD_size<0b0, 0b0, 0b11101, "scvtf">; +defm : Neon_Scalar2SameMisc_SD_size_patterns<int_aarch64_neon_vcvtf32_s32, + int_aarch64_neon_vcvtf64_s64, + SCVTFss, SCVTFdd>; + +// Scalar Unsigned Integer Convert To Floating-point +defm UCVTF : NeonI_Scalar2SameMisc_SD_size<0b1, 0b0, 0b11101, "ucvtf">; +defm : Neon_Scalar2SameMisc_SD_size_patterns<int_aarch64_neon_vcvtf32_u32, + int_aarch64_neon_vcvtf64_u64, + UCVTFss, UCVTFdd>; + // Scalar Reduce Pairwise multiclass NeonI_ScalarPair_D_sizes<bit u, bit size, bits<5> 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 |