From 0d45f320009ca43619bfeba50d6e8f947a2dc363 Mon Sep 17 00:00:00 2001 From: Ana Pazos Date: Thu, 5 Dec 2013 21:13:24 +0000 Subject: [PATCH] Implemented vget/vset_lane_f16 intrinsics git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196535 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/arm_neon.td | 5 +++ test/CodeGen/aarch64-neon-copy.c | 73 ++++++++++++++++++++++++++++++++ utils/TableGen/NeonEmitter.cpp | 35 ++++++++++++++- 3 files changed, 111 insertions(+), 2 deletions(-) diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td index 9097edc4e6..b918459f4e 100644 --- a/include/clang/Basic/arm_neon.td +++ b/include/clang/Basic/arm_neon.td @@ -133,6 +133,8 @@ def OP_SCALAR_QDMULH_LN : Op; def OP_SCALAR_QDMULH_LNQ : Op; def OP_SCALAR_QRDMULH_LN : Op; def OP_SCALAR_QRDMULH_LNQ : Op; +def OP_SCALAR_GET_LN : Op; +def OP_SCALAR_SET_LN : Op; class Inst { string Name = n; @@ -1330,4 +1332,7 @@ def SCALAR_SQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "ssji", "SsSi", OP_SCALAR_ def SCALAR_VDUP_LANE : IInst<"vdup_lane", "sdi", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">; def SCALAR_VDUP_LANEQ : IInst<"vdup_laneq", "sji", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">; + +def SCALAR_GET_LANE : IOpInst<"vget_lane", "sdi", "hQh", OP_SCALAR_GET_LN>; +def SCALAR_SET_LANE : IOpInst<"vset_lane", "dsdi", "hQh", OP_SCALAR_SET_LN>; } diff --git a/test/CodeGen/aarch64-neon-copy.c b/test/CodeGen/aarch64-neon-copy.c index 077f7ce913..eb91bf9b5a 100644 --- a/test/CodeGen/aarch64-neon-copy.c +++ b/test/CodeGen/aarch64-neon-copy.c @@ -1244,3 +1244,76 @@ float64x2_t test_vcopyq_laneq_f64(float64x2_t a, float64x2_t c) { return vcopyq_laneq_f64(a, 1, c, 1); } +// CHECK: test_vget_lane_f16 +int test_vget_lane_f16(float16x4_t v1) { + float16_t a = vget_lane_f16(v1, 3); + return (int)a; +// CHECK: dup {{h[0-9]+}}, {{v[0-9]+}}.h[3] +} + +// CHECK: test_vgetq_lane_f16 +int test_vgetq_lane_f16(float16x8_t v1) { + float16_t a = vgetq_lane_f16(v1, 7); + return (int)a; +// CHECK: dup {{h[0-9]+}}, {{v[0-9]+}}.h[7] +} + +// CHECK: test_vget_lane_f16_2 +float test_vget_lane_f16_2(float16x4_t v1) { + float16_t a = vget_lane_f16(v1, 3); + return (float)a; +// CHECK: dup {{h[0-9]+}}, {{v[0-9]+}}.h[3] +} + +// CHECK: test_vgetq_lane_f16_2 +float test_vgetq_lane_f16_2(float16x8_t v1) { + float16_t a = vgetq_lane_f16(v1, 7); + return (float)a; +// CHECK: dup {{h[0-9]+}}, {{v[0-9]+}}.h[7] +} + +// CHECK: test_vset_lane_f16 +float16x4_t test_vset_lane_f16(float16x4_t v1) { + float16_t a; + return vset_lane_f16(a, v1, 3); +// CHECK: fmov {{s[0-9]+}}, wzr +// CHECK-NEXT: ins {{v[0-9]+}}.h[3], {{v[0-9]+}}.h[0] +} + +// CHECK: test_vsetq_lane_f16 +float16x8_t test_vsetq_lane_f16(float16x8_t v1) { + float16_t a; + return vsetq_lane_f16(a, v1, 7); +// CHECK: fmov {{s[0-9]+}}, wzr +// CHECK-NEXT: ins {{v[0-9]+}}.h[7], {{v[0-9]+}}.h[0] +} + +// CHECK: test_vset_lane_f16_2 +float16x4_t test_vset_lane_f16_2(float16x4_t v1) { + float16_t a = vget_lane_f16(v1, 0); + return vset_lane_f16(a, v1, 3); +// CHECK: ins {{v[0-9]+}}.h[3], {{v[0-9]+}}.h[0] +} + +// CHECK: test_vsetq_lane_f16_2 +float16x8_t test_vsetq_lane_f16_2(float16x8_t v1) { + float16_t a = vgetq_lane_f16(v1, 0); + return vsetq_lane_f16(a, v1, 7); +// CHECK: ins {{v[0-9]+}}.h[7], {{v[0-9]+}}.h[0] +} + + +// CHECK: test_vsetq_lane_f16_3 +float16x8_t test_vsetq_lane_f16_3(float16x8_t v1, float b, float c) { + float16_t a = (float16_t)b; + return vsetq_lane_f16(a, v1, 7); +// CHECK: ins {{v[0-9]+}}.h[7], {{w[0-9]+}} +} + +// CHECK: test_vsetq_lane_f16_4 +float16x8_t test_vsetq_lane_f16_4(float16x8_t v1, float b, float c) { + float16_t a = (float16_t)b + 1.0; + return vsetq_lane_f16(a, v1, 7); +// CHECK: ins {{v[0-9]+}}.h[7], {{w[0-9]+}} +} + diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp index c92daf6297..f9eb22e0e7 100644 --- a/utils/TableGen/NeonEmitter.cpp +++ b/utils/TableGen/NeonEmitter.cpp @@ -154,7 +154,9 @@ enum OpKind { OpScalarQDMulHiLane, OpScalarQDMulHiLaneQ, OpScalarQRDMulHiLane, - OpScalarQRDMulHiLaneQ + OpScalarQRDMulHiLaneQ, + OpScalarGetLane, + OpScalarSetLane }; enum ClassKind { @@ -335,7 +337,8 @@ public: OpMap["OP_SCALAR_QDMULH_LNQ"] = OpScalarQDMulHiLaneQ; OpMap["OP_SCALAR_QRDMULH_LN"] = OpScalarQRDMulHiLane; OpMap["OP_SCALAR_QRDMULH_LNQ"] = OpScalarQRDMulHiLaneQ; - + OpMap["OP_SCALAR_GET_LN"] = OpScalarGetLane; + OpMap["OP_SCALAR_SET_LN"] = OpScalarSetLane; Record *SI = R.getClass("SInst"); Record *II = R.getClass("IInst"); @@ -2208,6 +2211,34 @@ static std::string GenOpString(const std::string &name, OpKind op, "vgetq_lane_" + typeCode + "(__b, __c));"; break; } + case OpScalarGetLane:{ + std::string typeCode = ""; + InstructionTypeCode(typestr, ClassS, quad, typeCode); + if (quad) { + s += "int16x8_t __a1 = vreinterpretq_s16_f16(__a);\\\n"; + s += " vgetq_lane_s16(__a1, __b);"; + } else { + s += "int16x4_t __a1 = vreinterpret_s16_f16(__a);\\\n"; + s += " vget_lane_s16(__a1, __b);"; + } + break; + } + case OpScalarSetLane:{ + std::string typeCode = ""; + InstructionTypeCode(typestr, ClassS, quad, typeCode); + s += "int16_t __a1 = (int16_t)__a;\\\n"; + if (quad) { + s += " int16x8_t __b1 = vreinterpretq_s16_f16(b);\\\n"; + s += " int16x8_t __b2 = vsetq_lane_s16(__a1, __b1, __c);\\\n"; + s += " vreinterpretq_f16_s16(__b2);"; + } else { + s += " int16x4_t __b1 = vreinterpret_s16_f16(b);\\\n"; + s += " int16x4_t __b2 = vset_lane_s16(__a1, __b1, __c);\\\n"; + s += " vreinterpret_f16_s16(__b2);"; + } + break; + } + default: PrintFatalError("unknown OpKind!"); } -- 2.40.0