[Beignet] [PATCH] support saturated converting from 64-bit int
Yang, Rong R
rong.r.yang at intel.com
Wed Oct 16 23:07:12 PDT 2013
This is a build error:
/home/champson/source/beignet/utests/builtin_convert_sat.cpp:6:18: error: conflicting declaration �typedef uint64_t ulong’
In file included from /usr/include/stdlib.h:314:0,
from /usr/lib/gcc/i686-linux-gnu/4.7/include/mm_malloc.h:27,
from /usr/lib/gcc/i686-linux-gnu/4.7/include/xmmintrin.h:39,
from /home/champson/source/beignet/utests/../include/CL/cl_platform.h:299,
from /home/champson/source/beignet/utests/../include/CL/cl.h:32,
from /home/champson/source/beignet/utests/utest_helper.hpp:28,
from /home/champson/source/beignet/utests/builtin_convert_sat.cpp:2:
/usr/include/i386-linux-gnu/sys/types.h:150:27: error: �ulong’ has a previous declaration as �typedef long unsigned int ulong’
-----Original Message-----
From: beignet-bounces+rong.r.yang=intel.com at lists.freedesktop.org [mailto:beignet-bounces+rong.r.yang=intel.com at lists.freedesktop.org] On Behalf Of Homer Hsing
Sent: Friday, October 11, 2013 9:35 AM
To: beignet at lists.freedesktop.org
Subject: [Beignet] [PATCH] support saturated converting from 64-bit int
This patch supports saturated converting from 64-bit int to shorter int, and from 32-bit float to 64-bit int.
This patch also contains test case.
Signed-off-by: Homer Hsing <homer.xing at intel.com>
---
backend/src/backend/gen_context.cpp | 14 ++++++++++++
backend/src/backend/gen_insn_selection.cpp | 3 +++ backend/src/backend/gen_insn_selection.hxx | 1 +
backend/src/ocl_stdlib.tmpl.h | 35 ++++++++++++++++++++++++++++++
kernels/builtin_convert_sat.cl | 16 ++++++++++++++
utests/builtin_convert_sat.cpp | 13 +++++++++++
6 files changed, 82 insertions(+)
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 858105a..43b3bc7 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -189,6 +189,20 @@ namespace gbe
case SEL_OP_MOV_DF:
p->MOV_DF(dst, src, tmp);
break;
+ case SEL_OP_CONVF_TO_I64:
+ {
+ tmp.type = GEN_TYPE_F;
+ GenRegister d = GenRegister::retype(tmp, GEN_TYPE_D);
+ float c = (1.f / 65536.f) * (1.f / 65536.f);
+ p->MUL(tmp, src, GenRegister::immf(c));
+ p->RNDZ(tmp, tmp);
+ p->MOV(d, tmp);
+ storeTopHalf(dst, d);
+ d.type = GEN_TYPE_UD;
+ p->MOV(d, GenRegister::abs(src));
+ storeBottomHalf(dst, d);
+ break;
+ }
case SEL_OP_CONVI_TO_I64: {
GenRegister middle;
if (src.type == GEN_TYPE_B || src.type == GEN_TYPE_D) { diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index cddd76e..47cfeab 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -459,6 +459,7 @@ namespace gbe
ALU2(UPSAMPLE_INT)
ALU2(UPSAMPLE_LONG)
ALU1WithTemp(CONVI_TO_I64)
+ ALU1WithTemp(CONVF_TO_I64)
ALU1(CONVI64_TO_I)
I64Shift(I64SHL)
I64Shift(I64SHR)
@@ -2579,6 +2580,8 @@ namespace gbe
} else if (dst.isint64()) {
switch(src.type) {
case GEN_TYPE_F:
+ sel.CONVF_TO_I64(dst, src, sel.selReg(sel.reg(FAMILY_DWORD)));
+ break;
case GEN_TYPE_DF:
NOT_IMPLEMENTED;
default:
diff --git a/backend/src/backend/gen_insn_selection.hxx b/backend/src/backend/gen_insn_selection.hxx
index 21b0a43..4499006 100644
--- a/backend/src/backend/gen_insn_selection.hxx
+++ b/backend/src/backend/gen_insn_selection.hxx
@@ -73,6 +73,7 @@ DECL_SELECTION_IR(UPSAMPLE_SHORT, BinaryInstruction) DECL_SELECTION_IR(UPSAMPLE_INT, BinaryInstruction) DECL_SELECTION_IR(UPSAMPLE_LONG, BinaryInstruction) DECL_SELECTION_IR(CONVI_TO_I64, UnaryWithTempInstruction)
+DECL_SELECTION_IR(CONVF_TO_I64, UnaryWithTempInstruction)
DECL_SELECTION_IR(CONVI64_TO_I, UnaryInstruction) DECL_SELECTION_IR(CONVI64_TO_F, I64ToFloatInstruction) DECL_SELECTION_IR(I64MADSAT, I64MADSATInstruction) diff --git a/backend/src/ocl_stdlib.tmpl.h b/backend/src/ocl_stdlib.tmpl.h index 3359854..5793326 100644
--- a/backend/src/ocl_stdlib.tmpl.h
+++ b/backend/src/ocl_stdlib.tmpl.h
@@ -246,6 +246,41 @@ DEF(uint, int);
DEF(uint, float);
#undef DEF
+#define DEF(DSTTYPE, SRCTYPE, MIN, MAX) \
+ INLINE_OVERLOADABLE DSTTYPE convert_ ## DSTTYPE ## _sat(SRCTYPE x) { \
+ return x > MAX ? (DSTTYPE)MAX : x < MIN ? (DSTTYPE)MIN : x; \
+ }
+DEF(char, long, -128, 127);
+DEF(uchar, long, 0, 255);
+DEF(short, long, -32768, 32767);
+DEF(ushort, long, 0, 65535);
+DEF(int, long, -0x7fffffff-1, 0x7fffffff); DEF(uint, long, 0,
+0xffffffffu); DEF(long, float, -9.223372036854776e+18f,
+9.223372036854776e+18f); DEF(ulong, float, 0, 1.8446744073709552e+19f);
+#undef DEF
+
+#define DEF(DSTTYPE, SRCTYPE, MAX) \
+ INLINE_OVERLOADABLE DSTTYPE convert_ ## DSTTYPE ## _sat(SRCTYPE x) { \
+ return x > MAX ? (DSTTYPE)MAX : x; \
+ }
+DEF(char, ulong, 127);
+DEF(uchar, ulong, 255);
+DEF(short, ulong, 32767);
+DEF(ushort, ulong, 65535);
+DEF(int, ulong, 0x7fffffff);
+DEF(uint, ulong, 0xffffffffu);
+#undef DEF
+
+INLINE_OVERLOADABLE long convert_long_sat(ulong x) {
+ ulong MAX = 0x7ffffffffffffffful;
+ return x > MAX ? MAX : x;
+}
+
+INLINE_OVERLOADABLE ulong convert_ulong_sat(long x) {
+ return x < 0 ? 0 : x;
+}
+
INLINE_OVERLOADABLE int isfinite(float x) { return __builtin_isfinite(x); } INLINE_OVERLOADABLE int isinf(float x) { return __builtin_isinf(x); } INLINE_OVERLOADABLE int isnan(float x) { diff --git a/kernels/builtin_convert_sat.cl b/kernels/builtin_convert_sat.cl index 281c890..1485f1d 100644
--- a/kernels/builtin_convert_sat.cl
+++ b/kernels/builtin_convert_sat.cl
@@ -9,24 +9,40 @@ DEF(char, short);
DEF(char, ushort);
DEF(char, int);
DEF(char, uint);
+DEF(char, long);
+DEF(char, ulong);
DEF(char, float);
DEF(uchar, char);
DEF(uchar, short);
DEF(uchar, ushort);
DEF(uchar, int);
DEF(uchar, uint);
+DEF(uchar, long);
+DEF(uchar, ulong);
DEF(uchar, float);
DEF(short, ushort);
DEF(short, int);
DEF(short, uint);
+DEF(short, long);
+DEF(short, ulong);
DEF(short, float);
DEF(ushort, short);
DEF(ushort, int);
DEF(ushort, uint);
+DEF(ushort, long);
+DEF(ushort, ulong);
DEF(ushort, float);
DEF(int, uint);
+DEF(int, long);
+DEF(int, ulong);
DEF(int, float);
DEF(uint, int);
+DEF(uint, long);
+DEF(uint, ulong);
DEF(uint, float);
+DEF(long, ulong);
+DEF(long, float);
+DEF(ulong, long);
+DEF(ulong, float);
#undef DEF
diff --git a/utests/builtin_convert_sat.cpp b/utests/builtin_convert_sat.cpp index e16ce16..fa64cb9 100644
--- a/utests/builtin_convert_sat.cpp
+++ b/utests/builtin_convert_sat.cpp
@@ -3,6 +3,7 @@
typedef unsigned char uchar;
typedef unsigned short ushort;
+typedef uint64_t ulong;
int64_t my_rand(void) {
int64_t x = rand() - RAND_MAX/2;
@@ -49,23 +50,35 @@ DEF(char, short, -128, 127); DEF(char, ushort, -128, 127); DEF(char, int, -128, 127); DEF(char, uint, -128, 127);
+DEF(char, long, -128, 127);
+DEF(char, ulong, -128, 127);
DEF(char, float, -128, 127);
DEF(uchar, char, 0, 255);
DEF(uchar, short, 0, 255);
DEF(uchar, ushort, 0, 255);
DEF(uchar, int, 0, 255);
DEF(uchar, uint, 0, 255);
+DEF(uchar, long, 0, 255);
+DEF(uchar, ulong, 0, 255);
DEF(uchar, float, 0, 255);
DEF(short, ushort, -32768, 32767);
DEF(short, int, -32768, 32767);
DEF(short, uint, -32768, 32767);
+DEF(short, long, -32768, 32767);
+DEF(short, ulong, -32768, 32767);
DEF(short, float, -32768, 32767);
DEF(ushort, short, 0, 65535);
DEF(ushort, int, 0, 65535);
DEF(ushort, uint, 0, 65535);
+DEF(ushort, long, 0, 65535);
+DEF(ushort, ulong, 0, 65535);
DEF(ushort, float, 0, 65535);
DEF(int, uint, -0x7FFFFFFF-1, 0x7FFFFFFF);
+DEF(int, long, -0x7FFFFFFF-1, 0x7FFFFFFF); DEF(int, ulong,
+-0x7FFFFFFF-1, 0x7FFFFFFF);
DEF(int, float, -0x7FFFFFFF-1, 0x7FFFFFFF); DEF(uint, int, 0, 0xffffffffu);
+DEF(uint, long, 0, 0xffffffffu);
+DEF(uint, ulong, 0, 0xffffffffu);
DEF(uint, float, 0, 0xffffffffu);
#undef DEF
--
1.8.1.2
_______________________________________________
Beignet mailing list
Beignet at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/beignet
More information about the Beignet
mailing list