summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Turner <mattst88@gmail.com>2012-02-24 17:39:39 -0500
committerMatt Turner <mattst88@gmail.com>2012-04-27 13:35:25 -0400
commitee750034252fb8f44c871e84a5057bc114699ae7 (patch)
tree9d131fc17ab38cf51dad93cca39757193d45b172
parent10c77b339f40fc027b682ef16edec234508d327b (diff)
mmx: introduce is_equal, is_opaque, and is_zero functions
To be used by the next commit.
-rw-r--r--pixman/pixman-mmx.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index eedef8ea..1290fc4d 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -67,6 +67,19 @@ _mm_empty (void)
/* We have to compile with -msse to use xmmintrin.h, but that causes SSE
* instructions to be generated that we don't want. Just duplicate the
* functions we want to use. */
+extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_movemask_pi8 (__m64 __A)
+{
+ int ret;
+
+ asm ("pmovmskb %1, %0\n\t"
+ : "=r" (ret)
+ : "y" (__A)
+ );
+
+ return ret;
+}
+
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_mulhi_pu16 (__m64 __A, __m64 __B)
{
@@ -427,6 +440,34 @@ store8888 (uint32_t *dest, __m64 v)
store (dest, v);
}
+static force_inline pixman_bool_t
+is_equal (__m64 a, __m64 b)
+{
+#ifdef USE_LOONGSON_MMI
+ /* __m64 is double, we can compare directly. */
+ return a == b;
+#else
+ return _mm_movemask_pi8 (_mm_cmpeq_pi8 (a, b)) == 0xff;
+#endif
+}
+
+static force_inline pixman_bool_t
+is_opaque (__m64 v)
+{
+#ifdef USE_LOONGSON_MMI
+ return is_equal (_mm_and_si64 (v, MC (full_alpha)), MC (full_alpha));
+#else
+ __m64 ffs = _mm_cmpeq_pi8 (v, v);
+ return (_mm_movemask_pi8 (_mm_cmpeq_pi8 (v, ffs)) & 0x40);
+#endif
+}
+
+static force_inline pixman_bool_t
+is_zero (__m64 v)
+{
+ return is_equal (v, _mm_setzero_si64 ());
+}
+
/* Expand 16 bits positioned at @pos (0-3) of a mmx register into
*
* 00RR00GG00BB