From 7c46fcfee4d13c5fa43334faa2713afc788f059d Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Wed, 27 Oct 2010 19:25:54 +0000 Subject: [PATCH] Provide correct NEON encodings for vdup. llvm-svn: 117475 --- lib/Target/ARM/ARMInstrFormats.td | 18 +++++ lib/Target/ARM/ARMInstrNEON.td | 32 ++++++--- test/MC/ARM/neon-dup-encoding.ll | 115 ++++++++++++++++++++++++++++++ 3 files changed, 157 insertions(+), 8 deletions(-) create mode 100644 test/MC/ARM/neon-dup-encoding.ll diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index 2350e400f47..73efdeb1756 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -1867,6 +1867,15 @@ class NVLaneOp opcod1, bits<4> opcod2, bits<2> opcod3, let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm); let Pattern = pattern; list Predicates = [HasNEON]; + + bits<5> Vd; + bits<4> Rt; + bits<4> p; + + let Inst{31-28} = p{3-0}; + let Inst{7} = Vd{4}; + let Inst{19-16} = Vd{3-0}; + let Inst{15-12} = Rt{3-0}; } class NVGetLane opcod1, bits<4> opcod2, bits<2> opcod3, dag oops, dag iops, InstrItinClass itin, @@ -1895,6 +1904,15 @@ class NVDupLane op19_16, bit op6, dag oops, dag iops, let Inst{11-7} = 0b11000; let Inst{6} = op6; let Inst{4} = 0; + + bits<5> Vd; + bits<5> Vm; + bits<4> lane; + + let Inst{22} = Vd{4}; + let Inst{15-12} = Vd{3-0}; + let Inst{5} = Vm{4}; + let Inst{3-0} = Vm{3-0}; } // NEONFPPat - Same as Pat<>, but requires that the compiler be using NEON diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index 0e2473650ed..4e81265b19c 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -3679,14 +3679,30 @@ class VDUPLNQ op19_16, string OpcodeStr, string Dt, // Inst{19-16} is partially specified depending on the element size. -def VDUPLN8d : VDUPLND<{?,?,?,1}, "vdup", "8", v8i8>; -def VDUPLN16d : VDUPLND<{?,?,1,0}, "vdup", "16", v4i16>; -def VDUPLN32d : VDUPLND<{?,1,0,0}, "vdup", "32", v2i32>; -def VDUPLNfd : VDUPLND<{?,1,0,0}, "vdup", "32", v2f32>; -def VDUPLN8q : VDUPLNQ<{?,?,?,1}, "vdup", "8", v16i8, v8i8>; -def VDUPLN16q : VDUPLNQ<{?,?,1,0}, "vdup", "16", v8i16, v4i16>; -def VDUPLN32q : VDUPLNQ<{?,1,0,0}, "vdup", "32", v4i32, v2i32>; -def VDUPLNfq : VDUPLNQ<{?,1,0,0}, "vdup", "32", v4f32, v2f32>; +def VDUPLN8d : VDUPLND<{?,?,?,1}, "vdup", "8", v8i8> { + let Inst{19-17} = lane{2-0}; +} +def VDUPLN16d : VDUPLND<{?,?,1,0}, "vdup", "16", v4i16> { + let Inst{19-18} = lane{1-0}; +} +def VDUPLN32d : VDUPLND<{?,1,0,0}, "vdup", "32", v2i32> { + let Inst{19} = lane{0}; +} +def VDUPLNfd : VDUPLND<{?,1,0,0}, "vdup", "32", v2f32> { + let Inst{19} = lane{0}; +} +def VDUPLN8q : VDUPLNQ<{?,?,?,1}, "vdup", "8", v16i8, v8i8> { + let Inst{19-17} = lane{2-0}; +} +def VDUPLN16q : VDUPLNQ<{?,?,1,0}, "vdup", "16", v8i16, v4i16> { + let Inst{19-18} = lane{1-0}; +} +def VDUPLN32q : VDUPLNQ<{?,1,0,0}, "vdup", "32", v4i32, v2i32> { + let Inst{19} = lane{0}; +} +def VDUPLNfq : VDUPLNQ<{?,1,0,0}, "vdup", "32", v4f32, v2f32> { + let Inst{19} = lane{0}; +} def : Pat<(v16i8 (NEONvduplane (v16i8 QPR:$src), imm:$lane)), (v16i8 (VDUPLN8q (v8i8 (EXTRACT_SUBREG QPR:$src, diff --git a/test/MC/ARM/neon-dup-encoding.ll b/test/MC/ARM/neon-dup-encoding.ll new file mode 100644 index 00000000000..98da6d38db7 --- /dev/null +++ b/test/MC/ARM/neon-dup-encoding.ll @@ -0,0 +1,115 @@ +; RUN: llc -show-mc-encoding -march=arm -mcpu=cortex-a8 -mattr=+neon < %s | FileCheck %s + +define <8 x i8> @v_dup8(i8 %A) nounwind { +; CHECK: vdup.8 d16, r0 @ encoding: [0x90,0x0b,0xc0,0xee] + %tmp1 = insertelement <8 x i8> zeroinitializer, i8 %A, i32 0 + %tmp2 = insertelement <8 x i8> %tmp1, i8 %A, i32 1 + %tmp3 = insertelement <8 x i8> %tmp2, i8 %A, i32 2 + %tmp4 = insertelement <8 x i8> %tmp3, i8 %A, i32 3 + %tmp5 = insertelement <8 x i8> %tmp4, i8 %A, i32 4 + %tmp6 = insertelement <8 x i8> %tmp5, i8 %A, i32 5 + %tmp7 = insertelement <8 x i8> %tmp6, i8 %A, i32 6 + %tmp8 = insertelement <8 x i8> %tmp7, i8 %A, i32 7 + ret <8 x i8> %tmp8 +} + +define <4 x i16> @v_dup16(i16 %A) nounwind { +; CHECK: vdup.16 d16, r0 @ encoding: [0xb0,0x0b,0x80,0xee] + %tmp1 = insertelement <4 x i16> zeroinitializer, i16 %A, i32 0 + %tmp2 = insertelement <4 x i16> %tmp1, i16 %A, i32 1 + %tmp3 = insertelement <4 x i16> %tmp2, i16 %A, i32 2 + %tmp4 = insertelement <4 x i16> %tmp3, i16 %A, i32 3 + ret <4 x i16> %tmp4 +} + +define <2 x i32> @v_dup32(i32 %A) nounwind { +; CHECK: vdup.32 d16, r0 @ encoding: [0x90,0x0b,0x80,0xee] + %tmp1 = insertelement <2 x i32> zeroinitializer, i32 %A, i32 0 + %tmp2 = insertelement <2 x i32> %tmp1, i32 %A, i32 1 + ret <2 x i32> %tmp2 +} + +define <16 x i8> @v_dupQ8(i8 %A) nounwind { +; CHECK: vdup.8 q8, r0 @ encoding: [0x90,0x0b,0xe0,0xee] + %tmp1 = insertelement <16 x i8> zeroinitializer, i8 %A, i32 0 + %tmp2 = insertelement <16 x i8> %tmp1, i8 %A, i32 1 + %tmp3 = insertelement <16 x i8> %tmp2, i8 %A, i32 2 + %tmp4 = insertelement <16 x i8> %tmp3, i8 %A, i32 3 + %tmp5 = insertelement <16 x i8> %tmp4, i8 %A, i32 4 + %tmp6 = insertelement <16 x i8> %tmp5, i8 %A, i32 5 + %tmp7 = insertelement <16 x i8> %tmp6, i8 %A, i32 6 + %tmp8 = insertelement <16 x i8> %tmp7, i8 %A, i32 7 + %tmp9 = insertelement <16 x i8> %tmp8, i8 %A, i32 8 + %tmp10 = insertelement <16 x i8> %tmp9, i8 %A, i32 9 + %tmp11 = insertelement <16 x i8> %tmp10, i8 %A, i32 10 + %tmp12 = insertelement <16 x i8> %tmp11, i8 %A, i32 11 + %tmp13 = insertelement <16 x i8> %tmp12, i8 %A, i32 12 + %tmp14 = insertelement <16 x i8> %tmp13, i8 %A, i32 13 + %tmp15 = insertelement <16 x i8> %tmp14, i8 %A, i32 14 + %tmp16 = insertelement <16 x i8> %tmp15, i8 %A, i32 15 + ret <16 x i8> %tmp16 +} + +define <8 x i16> @v_dupQ16(i16 %A) nounwind { +; CHECK: vdup.16 q8, r0 @ encoding: [0xb0,0x0b,0xa0,0xee] + %tmp1 = insertelement <8 x i16> zeroinitializer, i16 %A, i32 0 + %tmp2 = insertelement <8 x i16> %tmp1, i16 %A, i32 1 + %tmp3 = insertelement <8 x i16> %tmp2, i16 %A, i32 2 + %tmp4 = insertelement <8 x i16> %tmp3, i16 %A, i32 3 + %tmp5 = insertelement <8 x i16> %tmp4, i16 %A, i32 4 + %tmp6 = insertelement <8 x i16> %tmp5, i16 %A, i32 5 + %tmp7 = insertelement <8 x i16> %tmp6, i16 %A, i32 6 + %tmp8 = insertelement <8 x i16> %tmp7, i16 %A, i32 7 + ret <8 x i16> %tmp8 +} + +define <4 x i32> @v_dupQ32(i32 %A) nounwind { +; CHECK: vdup.32 q8, r0 @ encoding: [0x90,0x0b,0xa0,0xee] + %tmp1 = insertelement <4 x i32> zeroinitializer, i32 %A, i32 0 + %tmp2 = insertelement <4 x i32> %tmp1, i32 %A, i32 1 + %tmp3 = insertelement <4 x i32> %tmp2, i32 %A, i32 2 + %tmp4 = insertelement <4 x i32> %tmp3, i32 %A, i32 3 + ret <4 x i32> %tmp4 +} + +define <8 x i8> @vduplane8(<8 x i8>* %A) nounwind { + %tmp1 = load <8 x i8>* %A +; CHECK: vdup.8 d16, d16[1] @ encoding: [0x20,0x0c,0xf3,0xf3] + %tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <8 x i32> < i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1 > + ret <8 x i8> %tmp2 +} + +define <4 x i16> @vduplane16(<4 x i16>* %A) nounwind { + %tmp1 = load <4 x i16>* %A +; CHECK: vdup.16 d16, d16[1] @ encoding: [0x20,0x0c,0xf6,0xf3] + %tmp2 = shufflevector <4 x i16> %tmp1, <4 x i16> undef, <4 x i32> < i32 1, i32 1, i32 1, i32 1 > + ret <4 x i16> %tmp2 +} + +define <2 x i32> @vduplane32(<2 x i32>* %A) nounwind { + %tmp1 = load <2 x i32>* %A +; CHECK: vdup.32 d16, d16[1] @ encoding: [0x20,0x0c,0xfc,0xf3] + %tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <2 x i32> < i32 1, i32 1 > + ret <2 x i32> %tmp2 +} + +define <16 x i8> @vduplaneQ8(<8 x i8>* %A) nounwind { + %tmp1 = load <8 x i8>* %A +; CHECK: vdup.8 q8, d16[1] @ encoding: [0x60,0x0c,0xf3,0xf3] + %tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <16 x i32> < i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1 > + ret <16 x i8> %tmp2 +} + +define <8 x i16> @vduplaneQ16(<4 x i16>* %A) nounwind { + %tmp1 = load <4 x i16>* %A +; CHECK: vdup.16 q8, d16[1] @ encoding: [0x60,0x0c,0xf6,0xf3] + %tmp2 = shufflevector <4 x i16> %tmp1, <4 x i16> undef, <8 x i32> < i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1 > + ret <8 x i16> %tmp2 +} + +define <4 x i32> @vduplaneQ32(<2 x i32>* %A) nounwind { + %tmp1 = load <2 x i32>* %A +; CHECK: vdup.32 q8, d16[1] @ encoding: [0x60,0x0c,0xfc,0xf3] + %tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <4 x i32> < i32 1, i32 1, i32 1, i32 1 > + ret <4 x i32> %tmp2 +}