diff --git a/configure.ac b/configure.ac
index 0f52b87..3b73d7f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -229,6 +229,41 @@ dnl ========================================================
 AC_SUBST(MMX_CFLAGS)
 AC_SUBST(SSE_CFLAGS)
 
+dnl Check for VMX/Altivec
+if test -n "`$CC -v 2>&1 | grep version | grep Apple`"; then
+    VMX_CFLAGS="-faltivec"
+else
+    VMX_CFLAGS="-maltivec -mabi=altivec"
+fi
+
+have_vmx_intrinsics=no
+AC_MSG_CHECKING(whether to use VMX/Altivec intrinsics)
+xserver_save_CFLAGS=$CFLAGS
+CFLAGS="$CFLAGS $VMX_CFLAGS"
+AC_COMPILE_IFELSE([
+#if defined(__GNUC__) && (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4))
+#error "Need GCC >= 3.4 for sane altivec support"
+#endif
+#include <altivec.h>
+int main () {
+    vector unsigned int v = vec_splat_u32 (1);
+    v = vec_sub (v, v);
+    return 0;
+}], have_vmx_intrinsics=yes)
+CFLAGS=$xserver_save_CFLAGS
+AC_MSG_RESULT($have_vmx_intrinsics)
+
+if test $have_vmx_intrinsics = yes ; then
+   AC_DEFINE(USE_VMX, 1, [use VMX compiler intrinsics])
+else
+   VMX_CFLAGS=
+fi
+AC_SUBST(VMX_CFLAGS)
+
+AM_CONDITIONAL(USE_VMX, test $have_vmx_intrinsics = yes)
+
+dnl ===========================================================================
+
 PKG_CHECK_MODULES(GTK, [gtk+-2.0], [HAVE_GTK=yes], [HAVE_GTK=no])
 AM_CONDITIONAL(HAVE_GTK, [test "x$HAVE_GTK" = xyes])
 
diff --git a/pixman/Makefile.am b/pixman/Makefile.am
index 74c6102..b25fd41 100644
--- a/pixman/Makefile.am
+++ b/pixman/Makefile.am
@@ -48,6 +48,16 @@ libpixman_mmx_la_LIBADD = $(DEP_LIBS)
 libpixman_1_la_LIBADD += libpixman-mmx.la
 endif
 
+# vmx code
+if USE_VMX
+noinst_LTLIBRARIES += libpixman-vmx.la
+libpixman_vmx_la_SOURCES = \
+	pixman-vmx.c		\
+	pixman-vmx.h
+libpixman_vmx_la_CFLAGS = $(DEP_CFLAGS) $(VMX_CFLAGS)
+libpixman_vmx_la_LIBADD = $(DEP_LIBS)
+libpixman_1_la_LIBADD += libpixman-vmx.la
+endif
 
 # sse2 code
 if USE_SSE2
diff --git a/pixman/pixman-pict.c b/pixman/pixman-pict.c
index f01a643..c758823 100644
--- a/pixman/pixman-pict.c
+++ b/pixman/pixman-pict.c
@@ -30,9 +30,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-
 #include "pixman-private.h"
 #include "pixman-mmx.h"
+#include "pixman-vmx.h"
 #include "pixman-sse.h"
 
 #define FbFullMask(n)   ((n) == 32 ? (uint32_t)-1 : ((((uint32_t) 1) << n) - 1))
@@ -1415,6 +1415,14 @@ static const FastPathInfo sse_fast_paths[] =
 };
 #endif
 
+#ifdef USE_VMX
+static const FastPathInfo vmx_fast_paths[] =
+{
+    { PIXMAN_OP_NONE },
+};
+#endif
+
+
 static const FastPathInfo c_fast_paths[] =
 {
     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_r5g6b5,   fbCompositeSolidMask_nx8x0565, 0 },
@@ -1671,6 +1679,10 @@ pixman_image_composite (pixman_op_t      op,
     fbComposeSetupMMX();
 #endif
 
+#ifdef USE_VMX
+    fbComposeSetupVMX();
+#endif
+
     if (srcRepeat && srcTransform &&
 	pSrc->bits.width == 1 &&
 	pSrc->bits.height == 1)
@@ -1739,6 +1751,14 @@ pixman_image_composite (pixman_op_t      op,
 	    info = get_fast_path (mmx_fast_paths, op, pSrc, pMask, pDst, pixbuf);
 	if (!info)
 #endif
+
+#ifdef USE_VMX
+
+	if (pixman_have_vmx())
+	    info = get_fast_path (vmx_fast_paths, op, pSrc, pMask, pDst, pixbuf);
+	if (!info)
+#endif
+
 	    info = get_fast_path (c_fast_paths, op, pSrc, pMask, pDst, pixbuf);
 
 	if (info)
@@ -1805,6 +1825,52 @@ pixman_image_composite (pixman_op_t      op,
 }
 
 
+#ifdef USE_VMX
+/* The CPU detection code needs to be in a file not compiled with
+ * "-maltivec -mabi=altivec", as gcc would try to save vector register
+ * across function calls causing SIGILL on cpus without Altivec/vmx.
+ */
+#ifdef __APPLE__
+#include <sys/sysctl.h>
+
+pixman_bool_t pixman_have_vmx (void) {
+    int hasVMX = 0;
+    size_t length = sizeof ( hasVMX );
+    int error = sysctlbyname ("hw.optional.altivec", &hasVMX, &length, NULL, 0);
+    if ( 0 != error ) return 0;
+    return hasVMX;
+}
+
+#else
+#include <signal.h>
+#include <setjmp.h>
+
+static sigjmp_buf jmp;
+static volatile sig_atomic_t in_test = 0;
+
+static void vmx_test (int sig) {
+    if (! in_test) {
+        signal (sig, SIG_DFL);
+        raise (sig);
+    }
+    in_test = 0;
+    siglongjmp (jmp, 1);
+}
+
+pixman_bool_t pixman_have_vmx (void) {
+    signal (SIGILL, vmx_test);
+    if (sigsetjmp (jmp, 1)) {
+        signal (SIGILL, SIG_DFL);
+    } else {
+        in_test = 1;
+        asm volatile ( "vor 0, 0, 0" );
+        signal (SIGILL, SIG_DFL);
+        return 1;
+    }
+    return 0;
+}
+#endif /* __APPLE__ */
+#endif /* USE_VMX */
 
 #ifdef USE_MMX
 /* The CPU detection code needs to be in a file not compiled with
@@ -1822,6 +1888,7 @@ enum CPUFeatures {
     NoFeatures = 0,
     MMX = 0x1,
     MMX_Extensions = 0x2,
+    VMX = 0x4,
     SSE = 0x6,
     SSE2 = 0x8,
     CMOV = 0x10
diff --git a/pixman/pixman-vmx.c b/pixman/pixman-vmx.c
new file mode 100644
index 0000000..6d275ee
--- /dev/null
+++ b/pixman/pixman-vmx.c
@@ -0,0 +1,1226 @@
+/*
+ * Copyright © 2007 Luca Barbato
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Luca Barbato not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Luca Barbato makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Author:  Luca Barbato (lu_zero@gentoo.org)
+ *
+ * Based on fbmmx.c by Owen Taylor, Søren Sandmann and Nicholas Miell
+ */
+
+#include <config.h>
+#include "pixman-vmx.h"
+#include <altivec.h>
+
+/*
+  x_c = (x_c * a) / 255
+*/
+#define FbByteMul(x, a) do {					    \
+        uint32_t t = ((x & 0xff00ff) * a) + 0x800080;               \
+        t = (t + ((t >> 8) & 0xff00ff)) >> 8;			    \
+        t &= 0xff00ff;						    \
+								    \
+        x = (((x >> 8) & 0xff00ff) * a) + 0x800080;		    \
+        x = (x + ((x >> 8) & 0xff00ff));			    \
+        x &= 0xff00ff00;					    \
+        x += t;							    \
+    } while (0)
+
+/*
+  x_c = (x_c * a) / 255 + y
+*/
+#define FbByteMulAdd(x, a, y) do {				    \
+        uint32_t t = ((x & 0xff00ff) * a) + 0x800080;               \
+        t = (t + ((t >> 8) & 0xff00ff)) >> 8;			    \
+        t &= 0xff00ff;						    \
+        t += y & 0xff00ff;					    \
+        t |= 0x1000100 - ((t >> 8) & 0xff00ff);			    \
+        t &= 0xff00ff;						    \
+								    \
+        x = (((x >> 8) & 0xff00ff) * a) + 0x800080;                 \
+        x = (x + ((x >> 8) & 0xff00ff)) >> 8;                       \
+        x &= 0xff00ff;                                              \
+        x += (y >> 8) & 0xff00ff;                                   \
+        x |= 0x1000100 - ((x >> 8) & 0xff00ff);                     \
+        x &= 0xff00ff;                                              \
+        x <<= 8;                                                    \
+        x += t;                                                     \
+    } while (0)
+
+/*
+  x_c = (x_c * a + y_c * b) / 255
+*/
+#define FbByteAddMul(x, a, y, b) do {                                   \
+        uint32_t t;							\
+        uint32_t r = (x >> 24) * a + (y >> 24) * b + 0x80;		\
+        r += (r >> 8);                                                  \
+        r >>= 8;                                                        \
+									\
+        t = (x & 0xff00) * a + (y & 0xff00) * b;                        \
+        t += (t >> 8) + 0x8000;                                         \
+        t >>= 16;                                                       \
+									\
+        t |= r << 16;                                                   \
+        t |= 0x1000100 - ((t >> 8) & 0xff00ff);                         \
+        t &= 0xff00ff;                                                  \
+        t <<= 8;                                                        \
+									\
+        r = ((x >> 16) & 0xff) * a + ((y >> 16) & 0xff) * b + 0x80;     \
+        r += (r >> 8);                                                  \
+        r >>= 8;                                                        \
+									\
+        x = (x & 0xff) * a + (y & 0xff) * b + 0x80;                     \
+        x += (x >> 8);                                                  \
+        x >>= 8;                                                        \
+        x |= r << 16;                                                   \
+        x |= 0x1000100 - ((x >> 8) & 0xff00ff);                         \
+        x &= 0xff00ff;                                                  \
+        x |= t;                                                         \
+    } while (0)
+
+/*
+  x_c = (x_c * a_c) / 255
+*/
+#define FbByteMulC(x, a) do {				  \
+        uint32_t t;                                       \
+        uint32_t r = (x & 0xff) * (a & 0xff);             \
+        r |= (x & 0xff0000) * ((a >> 16) & 0xff);	  \
+	r += 0x800080;					  \
+        r = (r + ((r >> 8) & 0xff00ff)) >> 8;		  \
+        r &= 0xff00ff;					  \
+							  \
+        x >>= 8;					  \
+        t = (x & 0xff) * ((a >> 8) & 0xff);		  \
+        t |= (x & 0xff0000) * (a >> 24);		  \
+        t += 0x800080;					  \
+        t = t + ((t >> 8) & 0xff00ff);			  \
+        x = r | (t & 0xff00ff00);			  \
+							  \
+    } while (0)
+
+/*
+  x_c = (x_c * a) / 255 + y
+*/
+#define FbByteMulAddC(x, a, y) do {				      \
+        uint32_t t;                                                   \
+        uint32_t r = (x & 0xff) * (a & 0xff);                         \
+        r |= (x & 0xff0000) * ((a >> 16) & 0xff);		      \
+	r += 0x800080;						      \
+	r = (r + ((r >> 8) & 0xff00ff)) >> 8;			      \
+        r &= 0xff00ff;						      \
+        r += y & 0xff00ff;					      \
+        r |= 0x1000100 - ((r >> 8) & 0xff00ff);			      \
+        r &= 0xff00ff;						      \
+								      \
+        x >>= 8;                                                       \
+        t = (x & 0xff) * ((a >> 8) & 0xff);                            \
+        t |= (x & 0xff0000) * (a >> 24);                               \
+	t += 0x800080;                                                 \
+        t = (t + ((t >> 8) & 0xff00ff)) >> 8;			       \
+        t &= 0xff00ff;                                                 \
+        t += (y >> 8) & 0xff00ff;                                      \
+        t |= 0x1000100 - ((t >> 8) & 0xff00ff);                        \
+        t &= 0xff00ff;                                                 \
+        x = r | (t << 8);                                              \
+    } while (0)
+
+/*
+  x_c = (x_c * a_c + y_c * b) / 255
+*/
+#define FbByteAddMulC(x, a, y, b) do {                                  \
+        uint32_t t;							\
+        uint32_t r = (x >> 24) * (a >> 24) + (y >> 24) * b;		\
+        r += (r >> 8) + 0x80;                                           \
+        r >>= 8;                                                        \
+									\
+        t = (x & 0xff00) * ((a >> 8) & 0xff) + (y & 0xff00) * b;        \
+        t += (t >> 8) + 0x8000;                                         \
+        t >>= 16;                                                       \
+									\
+        t |= r << 16;                                                   \
+        t |= 0x1000100 - ((t >> 8) & 0xff00ff);                         \
+        t &= 0xff00ff;                                                  \
+        t <<= 8;                                                        \
+									\
+        r = ((x >> 16) & 0xff) * ((a >> 16) & 0xff) + ((y >> 16) & 0xff) * b + 0x80; \
+        r += (r >> 8);                                                  \
+        r >>= 8;                                                        \
+									\
+        x = (x & 0xff) * (a & 0xff) + (y & 0xff) * b + 0x80;            \
+        x += (x >> 8);                                                  \
+        x >>= 8;                                                        \
+        x |= r << 16;                                                   \
+        x |= 0x1000100 - ((x >> 8) & 0xff00ff);                         \
+        x &= 0xff00ff;                                                  \
+        x |= t;                                                         \
+    } while (0)
+
+/*
+  x_c = min(x_c + y_c, 255)
+*/
+#define FbByteAdd(x, y) do {                                            \
+        uint32_t t;							\
+        uint32_t r = (x & 0xff00ff) + (y & 0xff00ff);			\
+        r |= 0x1000100 - ((r >> 8) & 0xff00ff);                         \
+        r &= 0xff00ff;                                                  \
+									\
+        t = ((x >> 8) & 0xff00ff) + ((y >> 8) & 0xff00ff);              \
+        t |= 0x1000100 - ((t >> 8) & 0xff00ff);                         \
+        r |= (t & 0xff00ff) << 8;                                       \
+        x = r;                                                          \
+    } while (0)
+
+static inline vector unsigned int
+splat_alpha (vector unsigned int pix) {
+    return vec_perm (pix, pix,
+    (vector unsigned char)AVV(0x00,0x00,0x00,0x00, 0x04,0x04,0x04,0x04,
+                               0x08,0x08,0x08,0x08, 0x0C,0x0C,0x0C,0x0C));
+}
+
+static inline vector unsigned int
+pix_multiply (vector unsigned int p, vector unsigned int a)
+{
+    vector unsigned short hi, lo, mod;
+    /* unpack to short */
+    hi = (vector unsigned short)
+                    vec_mergeh ((vector unsigned char)AVV(0),
+                                (vector unsigned char)p);
+    mod = (vector unsigned short)
+                    vec_mergeh ((vector unsigned char)AVV(0),
+                                (vector unsigned char)a);
+
+    hi = vec_mladd (hi, mod, (vector unsigned short)
+                            AVV(0x0080,0x0080,0x0080,0x0080,
+                                 0x0080,0x0080,0x0080,0x0080));
+
+    hi = vec_adds (hi, vec_sr (hi, vec_splat_u16 (8)));
+
+    hi = vec_sr (hi, vec_splat_u16 (8));
+
+    /* unpack to short */
+    lo = (vector unsigned short)
+                    vec_mergel ((vector unsigned char)AVV(0),
+                                (vector unsigned char)p);
+    mod = (vector unsigned short)
+                    vec_mergel ((vector unsigned char)AVV(0),
+                                (vector unsigned char)a);
+
+    lo = vec_mladd (lo, mod, (vector unsigned short)
+                            AVV(0x0080,0x0080,0x0080,0x0080,
+                                 0x0080,0x0080,0x0080,0x0080));
+
+    lo = vec_adds (lo, vec_sr (lo, vec_splat_u16 (8)));
+
+    lo = vec_sr (lo, vec_splat_u16 (8));
+
+    return (vector unsigned int)vec_packsu (hi, lo);
+}
+
+static inline vector unsigned int
+pix_add (vector unsigned int a, vector unsigned int b)
+{
+    return (vector unsigned int)vec_adds ((vector unsigned char)a,
+                     (vector unsigned char)b);
+}
+
+static inline vector unsigned int
+pix_add_mul (vector unsigned int x, vector unsigned int a,
+             vector unsigned int y, vector unsigned int b)
+{
+    vector unsigned short hi, lo, mod, hiy, loy, mody;
+
+    hi = (vector unsigned short)
+                    vec_mergeh ((vector unsigned char)AVV(0),
+                                (vector unsigned char)x);
+    mod = (vector unsigned short)
+                    vec_mergeh ((vector unsigned char)AVV(0),
+                                (vector unsigned char)a);
+    hiy = (vector unsigned short)
+                    vec_mergeh ((vector unsigned char)AVV(0),
+                                (vector unsigned char)y);
+    mody = (vector unsigned short)
+                    vec_mergeh ((vector unsigned char)AVV(0),
+                                (vector unsigned char)b);
+
+    hi = vec_mladd (hi, mod, (vector unsigned short)
+                             AVV(0x0080,0x0080,0x0080,0x0080,
+                                  0x0080,0x0080,0x0080,0x0080));
+
+    hi = vec_mladd (hiy, mody, hi);
+
+    hi = vec_adds (hi, vec_sr (hi, vec_splat_u16 (8)));
+
+    hi = vec_sr (hi, vec_splat_u16 (8));
+
+    lo = (vector unsigned short)
+                    vec_mergel ((vector unsigned char)AVV(0),
+                                (vector unsigned char)x);
+    mod = (vector unsigned short)
+                    vec_mergel ((vector unsigned char)AVV(0),
+                                (vector unsigned char)a);
+
+    loy = (vector unsigned short)
+                    vec_mergel ((vector unsigned char)AVV(0),
+                                (vector unsigned char)y);
+    mody = (vector unsigned short)
+                    vec_mergel ((vector unsigned char)AVV(0),
+                                (vector unsigned char)b);
+
+    lo = vec_mladd (lo, mod, (vector unsigned short)
+                             AVV(0x0080,0x0080,0x0080,0x0080,
+                                  0x0080,0x0080,0x0080,0x0080));
+
+    lo = vec_mladd (loy, mody, lo);
+
+    lo = vec_adds (lo, vec_sr (lo, vec_splat_u16 (8)));
+
+    lo = vec_sr (lo, vec_splat_u16 (8));
+
+    return (vector unsigned int)vec_packsu (hi, lo);
+}
+
+static inline vector unsigned int
+negate (vector unsigned int src)
+{
+    return vec_nor (src, src);
+}
+/* dest*~srca + src */
+static inline vector unsigned int
+over (vector unsigned int src, vector unsigned int srca,
+      vector unsigned int dest)
+{
+    vector unsigned char tmp = (vector unsigned char)
+                                pix_multiply (dest, negate (srca));
+    tmp = vec_adds ((vector unsigned char)src, tmp);
+    return (vector unsigned int)tmp;
+}
+
+/* in == pix_multiply */
+#define in_over(src, srca, mask, dest) over (pix_multiply (src, mask),\
+                                             pix_multiply (srca, mask), dest)
+
+
+#define COMPUTE_SHIFT_MASK(source) \
+    source ## _mask = vec_lvsl (0, source);
+
+#define COMPUTE_SHIFT_MASKS(dest, source) \
+    dest ## _mask = vec_lvsl (0, dest); \
+    source ## _mask = vec_lvsl (0, source); \
+    store_mask = vec_lvsr (0, dest);
+
+#define COMPUTE_SHIFT_MASKC(dest, source, mask) \
+    mask ## _mask = vec_lvsl (0, mask); \
+    dest ## _mask = vec_lvsl (0, dest); \
+    source ## _mask = vec_lvsl (0, source); \
+    store_mask = vec_lvsr (0, dest);
+
+/* notice you have to declare temp vars...
+ * Note: tmp3 and tmp4 must remain untouched!
+ */
+#define LOAD_VECTOR (source) \
+        tmp1 = (typeof(v ## source))vec_ld(0, source); \
+        tmp2 = (typeof(v ## source))vec_ld(15, source); \
+        v ## source = (typeof(v ## source)) \
+                       vec_perm(tmp1, tmp2, source ## _mask);
+
+#define LOAD_VECTORS(dest, source) \
+        tmp1 = (typeof(tmp1))vec_ld(0, source); \
+        tmp2 = (typeof(tmp2))vec_ld(15, source); \
+        tmp3 = (typeof(tmp3))vec_ld(0, dest); \
+        v ## source = (typeof(v ## source)) \
+                       vec_perm(tmp1, tmp2, source ## _mask); \
+        tmp4 = (typeof(tmp4))vec_ld(15, dest); \
+        v ## dest = (typeof(v ## dest)) \
+                     vec_perm(tmp3, tmp4, dest ## _mask);
+
+#define LOAD_VECTORSC(dest, source, mask) \
+        tmp1 = (typeof(tmp1))vec_ld(0, source); \
+        tmp2 = (typeof(tmp2))vec_ld(15, source); \
+        tmp3 = (typeof(tmp3))vec_ld(0, dest); \
+        v ## source = (typeof(v ## source)) \
+                       vec_perm(tmp1, tmp2, source ## _mask); \
+        tmp4 = (typeof(tmp4))vec_ld(15, dest); \
+        tmp1 = (typeof(tmp1))vec_ld(0, mask); \
+        v ## dest = (typeof(v ## dest)) \
+                     vec_perm(tmp3, tmp4, dest ## _mask); \
+        tmp2 = (typeof(tmp2))vec_ld(15, mask); \
+        v ## mask = (typeof(v ## mask)) \
+                     vec_perm(tmp1, tmp2, mask ## _mask);
+#define STORE_VECTOR(dest) \
+        edges = vec_perm (tmp4, tmp3, dest ## _mask); \
+        tmp3 = vec_perm ((vector unsigned char)v ## dest, edges, store_mask); \
+        tmp1 = vec_perm (edges, (vector unsigned char)v ## dest, store_mask); \
+        vec_st ((vector unsigned int) tmp3, 15, dest ); \
+        vec_st ((vector unsigned int) tmp1, 0, dest );
+
+static FASTCALL void
+vmxCombineMaskU (uint32_t *src, const uint32_t *msk, int width)
+{
+    int i;
+    vector unsigned int  vsrc, vmsk;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         src_mask, msk_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKS(src, msk)
+
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORS(src, msk)
+
+        vsrc = pix_multiply (vsrc, splat_alpha (vmsk));
+
+        STORE_VECTOR(src)
+
+        msk+=4;
+        src+=4;
+    }
+
+    for (i = width%4; --i >= 0;) {
+        uint32_t a = msk[i] >> 24;
+        uint32_t s = src[i];
+        FbByteMul (s, a);
+        src[i] = s;
+    }
+}
+
+static FASTCALL void
+vmxCombineOverU (uint32_t *dest, const uint32_t *src, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKS(dest, src)
+
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORS(dest, src)
+
+        vdest = over (vsrc, splat_alpha (vsrc), vdest);
+
+        STORE_VECTOR(dest)
+
+        src+=4;
+        dest+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t s = src[i];
+        uint32_t d = dest[i];
+        uint32_t ia = Alpha (~s);
+
+        FbByteMulAdd (d, ia, s);
+        dest[i] = d;
+    }
+}
+
+
+static FASTCALL void
+vmxCombineOverReverseU (uint32_t *dest, const uint32_t *src, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKS(dest, src)
+
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORS(dest, src)
+
+        vdest = over (vdest, splat_alpha (vdest) , vsrc);
+
+        STORE_VECTOR(dest)
+
+        src+=4;
+        dest+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t s = src[i];
+        uint32_t d = dest[i];
+        uint32_t ia = Alpha (~dest[i]);
+
+        FbByteMulAdd (s, ia, d);
+        dest[i] = s;
+    }
+}
+
+static FASTCALL void
+vmxCombineInU (uint32_t *dest, const uint32_t *src, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKS(dest, src)
+
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORS(dest, src)
+
+        vdest = pix_multiply (vsrc, splat_alpha (vdest));
+
+        STORE_VECTOR(dest)
+
+        src+=4;
+        dest+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+
+        uint32_t s = src[i];
+        uint32_t a = Alpha (dest[i]);
+        FbByteMul (s, a);
+        dest[i] = s;
+    }
+}
+
+static FASTCALL void
+vmxCombineInReverseU (uint32_t *dest, const uint32_t *src, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKS(dest, src)
+
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORS(dest, src)
+
+        vdest = pix_multiply (vdest, splat_alpha (vsrc));
+
+        STORE_VECTOR(dest)
+
+        src+=4;
+        dest+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t d = dest[i];
+        uint32_t a = Alpha (src[i]);
+        FbByteMul (d, a);
+        dest[i] = d;
+    }
+}
+
+static FASTCALL void
+vmxCombineOutU (uint32_t *dest, const uint32_t *src, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKS(dest, src)
+
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORS(dest, src)
+
+        vdest = pix_multiply (vsrc, splat_alpha (negate (vdest)));
+
+        STORE_VECTOR(dest)
+
+        src+=4;
+        dest+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t s = src[i];
+        uint32_t a = Alpha (~dest[i]);
+        FbByteMul (s, a);
+        dest[i] = s;
+    }
+}
+
+static FASTCALL void
+vmxCombineOutReverseU (uint32_t *dest, const uint32_t *src, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKS(dest, src)
+
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORS(dest, src)
+
+        vdest = pix_multiply (vdest, splat_alpha (negate (vsrc)));
+
+        STORE_VECTOR(dest)
+
+        src+=4;
+        dest+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t d = dest[i];
+        uint32_t a = Alpha (~src[i]);
+        FbByteMul (d, a);
+        dest[i] = d;
+    }
+}
+
+static FASTCALL void
+vmxCombineAtopU (uint32_t *dest, const uint32_t *src, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKS(dest, src)
+
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORS(dest, src)
+
+        vdest = pix_add_mul (vsrc, splat_alpha (vdest),
+                            vdest, splat_alpha (negate (vsrc)));
+
+        STORE_VECTOR(dest)
+
+        src+=4;
+        dest+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t s = src[i];
+        uint32_t d = dest[i];
+        uint32_t dest_a = Alpha (d);
+        uint32_t src_ia = Alpha (~s);
+
+        FbByteAddMul (s, dest_a, d, src_ia);
+        dest[i] = s;
+    }
+}
+
+static FASTCALL void
+vmxCombineAtopReverseU (uint32_t *dest, const uint32_t *src, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKS(dest, src)
+
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORS(dest, src)
+
+        vdest = pix_add_mul (vdest, splat_alpha (vsrc),
+                            vsrc, splat_alpha (negate (vdest)));
+
+        STORE_VECTOR(dest)
+
+        src+=4;
+        dest+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t s = src[i];
+        uint32_t d = dest[i];
+        uint32_t src_a = Alpha (s);
+        uint32_t dest_ia = Alpha (~d);
+
+        FbByteAddMul (s, dest_ia, d, src_a);
+        dest[i] = s;
+    }
+}
+
+static FASTCALL void
+vmxCombineXorU (uint32_t *dest, const uint32_t *src, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKS(dest, src)
+
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORS (dest, src)
+
+        vdest = pix_add_mul (vsrc, splat_alpha (negate (vdest)),
+                            vdest, splat_alpha (negate (vsrc)));
+
+        STORE_VECTOR(dest)
+
+        src+=4;
+        dest+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t s = src[i];
+        uint32_t d = dest[i];
+        uint32_t src_ia = Alpha (~s);
+        uint32_t dest_ia = Alpha (~d);
+
+        FbByteAddMul (s, dest_ia, d, src_ia);
+        dest[i] = s;
+    }
+}
+
+static FASTCALL void
+vmxCombineAddU (uint32_t *dest, const uint32_t *src, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKS(dest, src)
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORS(dest, src)
+
+        vdest = pix_add (vsrc, vdest);
+
+        STORE_VECTOR(dest)
+
+        src+=4;
+        dest+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t s = src[i];
+        uint32_t d = dest[i];
+        FbByteAdd (d, s);
+        dest[i] = d;
+    }
+}
+
+static FASTCALL void
+vmxCombineSrcC (uint32_t *dest, uint32_t *src, uint32_t *mask, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc, vmask;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, mask_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKC(dest, src, mask);
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORSC(dest, src, mask)
+
+        vdest = pix_multiply (vsrc, vmask);
+
+        STORE_VECTOR(dest)
+
+        mask+=4;
+        src+=4;
+        dest+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t a = mask[i];
+        uint32_t s = src[i];
+        FbByteMulC (s, a);
+        dest[i] = s;
+    }
+}
+
+static FASTCALL void
+vmxCombineOverC (uint32_t *dest, uint32_t *src, uint32_t *mask, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc, vmask;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, mask_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKC(dest, src, mask);
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORSC(dest, src, mask)
+
+        vdest = in_over (vsrc, splat_alpha (vsrc), vmask, vdest);
+
+        STORE_VECTOR(dest)
+
+        mask+=4;
+        src+=4;
+        dest+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t a = mask[i];
+        uint32_t s = src[i];
+        uint32_t d = dest[i];
+        FbByteMulC (s, a);
+        FbByteMulAddC (d, ~a, s);
+        dest[i] = d;
+    }
+}
+
+static FASTCALL void
+vmxCombineOverReverseC (uint32_t *dest, uint32_t *src, uint32_t *mask, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc, vmask;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, mask_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKC(dest, src, mask);
+    /* printf("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORSC (dest, src, mask)
+
+        vdest = over (vdest, splat_alpha (vdest), pix_multiply (vsrc, vmask));
+
+        STORE_VECTOR(dest)
+
+        mask+=4;
+        src+=4;
+        dest+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t a = mask[i];
+        uint32_t s = src[i];
+        uint32_t d = dest[i];
+        uint32_t da = Alpha (d);
+        FbByteMulC (s, a);
+        FbByteMulAddC (s, ~da, d);
+        dest[i] = s;
+    }
+}
+
+static FASTCALL void
+vmxCombineInC (uint32_t *dest, uint32_t *src, uint32_t *mask, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc, vmask;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, mask_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKC(dest, src, mask)
+
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORSC(dest, src, mask)
+
+        vdest = pix_multiply (pix_multiply (vsrc, vmask), splat_alpha (vdest));
+
+        STORE_VECTOR(dest)
+
+        src+=4;
+        dest+=4;
+        mask+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t a = mask[i];
+        uint32_t s = src[i];
+        uint32_t da = Alpha (dest[i]);
+        FbByteMul (s, a);
+        FbByteMul (s, da);
+        dest[i] = s;
+    }
+}
+
+static FASTCALL void
+vmxCombineInReverseC (uint32_t *dest, uint32_t *src, uint32_t *mask, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc, vmask;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, mask_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKC(dest, src, mask)
+
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORSC(dest, src, mask)
+
+        vdest = pix_multiply (vdest, pix_multiply (vmask, splat_alpha (vsrc)));
+
+        STORE_VECTOR(dest)
+
+        src+=4;
+        dest+=4;
+        mask+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t a = mask[i];
+        uint32_t d = dest[i];
+        uint32_t sa = Alpha (src[i]);
+        FbByteMul (a, sa);
+        FbByteMulC (d, a);
+        dest[i] = d;
+    }
+}
+
+static FASTCALL void
+vmxCombineOutC (uint32_t *dest, uint32_t *src, uint32_t *mask, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc, vmask;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, mask_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKC(dest, src, mask)
+
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORSC(dest, src, mask)
+
+        vdest = pix_multiply (pix_multiply (vsrc, vmask), splat_alpha (vdest));
+
+        STORE_VECTOR(dest)
+
+        src+=4;
+        dest+=4;
+        mask+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t a = mask[i];
+        uint32_t s = src[i];
+        uint32_t d = dest[i];
+        uint32_t da = Alpha (~d);
+        FbByteMulC (s, a);
+        FbByteMulC (s, da);
+        dest[i] = s;
+    }
+}
+
+static FASTCALL void
+vmxCombineOutReverseC (uint32_t *dest, uint32_t *src, uint32_t *mask, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc, vmask;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, mask_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKC(dest, src, mask)
+
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORSC(dest, src, mask)
+
+        vdest = pix_multiply (vdest,
+                             negate (pix_multiply (vmask, splat_alpha (vsrc))));
+
+        STORE_VECTOR(dest)
+
+        src+=4;
+        dest+=4;
+        mask+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t a = mask[i];
+        uint32_t s = src[i];
+        uint32_t d = dest[i];
+        uint32_t sa = Alpha (s);
+        FbByteMulC (a, sa);
+        FbByteMulC (d, ~a);
+        dest[i] = d;
+    }
+}
+
+static FASTCALL void
+vmxCombineAtopC (uint32_t *dest, uint32_t *src, uint32_t *mask, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc, vmask;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, mask_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKC(dest, src, mask)
+
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORSC(dest, src, mask)
+
+        vdest = pix_add_mul (pix_multiply (vsrc, vmask), splat_alpha (vdest),
+                            vdest,
+                            negate (pix_multiply (vmask,
+                                                splat_alpha (vmask))));
+
+        STORE_VECTOR(dest)
+
+        src+=4;
+        dest+=4;
+        mask+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t a = mask[i];
+        uint32_t s = src[i];
+        uint32_t d = dest[i];
+        uint32_t sa = Alpha (s);
+        uint32_t da = Alpha (d);
+
+        FbByteMulC (s, a);
+        FbByteMul (a, sa);
+        FbByteAddMulC (d, ~a, s, da);
+        dest[i] = d;
+    }
+}
+
+static FASTCALL void
+vmxCombineAtopReverseC (uint32_t *dest, uint32_t *src, uint32_t *mask, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc, vmask;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, mask_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKC(dest, src, mask)
+
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORSC(dest, src, mask)
+
+        vdest = pix_add_mul (vdest,
+                            pix_multiply (vmask, splat_alpha (vsrc)),
+                            pix_multiply (vsrc, vmask),
+                            negate (splat_alpha (vdest)));
+
+        STORE_VECTOR(dest)
+
+        src+=4;
+        dest+=4;
+        mask+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t a = mask[i];
+        uint32_t s = src[i];
+        uint32_t d = dest[i];
+        uint32_t sa = Alpha (s);
+        uint32_t da = Alpha (d);
+
+        FbByteMulC (s, a);
+        FbByteMul (a, sa);
+        FbByteAddMulC (d, a, s, ~da);
+        dest[i] = d;
+    }
+}
+
+static FASTCALL void
+vmxCombineXorC (uint32_t *dest, uint32_t *src, uint32_t *mask, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc, vmask;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, mask_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKC(dest, src, mask)
+
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORSC(dest, src, mask)
+
+        vdest = pix_add_mul (vdest,
+                            negate (pix_multiply (vmask, splat_alpha (vsrc))),
+                            pix_multiply (vsrc, vmask),
+                            negate (splat_alpha (vdest)));
+
+        STORE_VECTOR(dest)
+
+        src+=4;
+        dest+=4;
+        mask+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t a = mask[i];
+        uint32_t s = src[i];
+        uint32_t d = dest[i];
+        uint32_t sa = Alpha (s);
+        uint32_t da = Alpha (d);
+
+        FbByteMulC (s, a);
+        FbByteMul (a, sa);
+        FbByteAddMulC (d, ~a, s, ~da);
+        dest[i] = d;
+    }
+}
+
+static FASTCALL void
+vmxCombineAddC (uint32_t *dest, uint32_t *src, uint32_t *mask, int width)
+{
+    int i;
+    vector unsigned int  vdest, vsrc, vmask;
+    vector unsigned char tmp1, tmp2, tmp3, tmp4, edges,
+                         dest_mask, mask_mask, src_mask, store_mask;
+
+    COMPUTE_SHIFT_MASKC(dest, src, mask)
+
+    /* printf ("%s\n",__PRETTY_FUNCTION__); */
+    for (i = width/4; i > 0; i--) {
+
+        LOAD_VECTORSC(dest, src, mask)
+
+        vdest = pix_add (pix_multiply (vsrc, vmask), vdest);
+
+        STORE_VECTOR(dest)
+
+        src+=4;
+        dest+=4;
+        mask+=4;
+    }
+
+    for (i = width%4; --i >=0;) {
+        uint32_t a = mask[i];
+        uint32_t s = src[i];
+        uint32_t d = dest[i];
+
+        FbByteMulC (s, a);
+        FbByteAdd (s, d);
+        dest[i] = s;
+    }
+}
+
+
+#if 0
+void
+fbCompositeSolid_nx8888vmx (pixman_operator_t	op,
+			    pixman_image_t * pSrc,
+			    pixman_image_t * pMask,
+			    pixman_image_t * pDst,
+			    int16_t	xSrc,
+			    int16_t	ySrc,
+			    int16_t	xMask,
+			    int16_t	yMask,
+			    int16_t	xDst,
+			    int16_t	yDst,
+			    uint16_t	width,
+			    uint16_t	height)
+{
+    uint32_t	src;
+    uint32_t	*dstLine, *dst;
+    int	dstStride;
+
+    fbComposeGetSolid (pSrc, pDst, src);
+
+    if (src >> 24 == 0)
+	return;
+
+    fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	/* XXX vmxCombineOverU (dst, src, width); */
+    }
+}
+
+void
+fbCompositeSolid_nx0565vmx (pixman_operator_t	op,
+			    pixman_image_t * pSrc,
+			    pixman_image_t * pMask,
+			    pixman_image_t * pDst,
+			    int16_t	xSrc,
+			    int16_t	ySrc,
+			    int16_t	xMask,
+			    int16_t	yMask,
+			    int16_t	xDst,
+			    int16_t	yDst,
+			    uint16_t	width,
+			    uint16_t	height)
+{
+    uint32_t	src;
+    uint16_t	*dstLine, *dst;
+    uint16_t	w;
+    int	dstStride;
+
+    fbComposeGetSolid (pSrc, pDst, src);
+
+    if (src >> 24 == 0)
+	return;
+
+    fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+       vmxCombineOverU565(dst, src, width);
+    }
+}
+
+#endif
+
+void fbComposeSetupVMX (void)
+{
+    /* check if we have VMX support and initialize accordingly */
+    if (pixman_have_vmx ()) {
+        pixman_composeFunctions.combineU[PIXMAN_OP_OVER] = vmxCombineOverU;
+        pixman_composeFunctions.combineU[PIXMAN_OP_OVER_REVERSE] = vmxCombineOverReverseU;
+        pixman_composeFunctions.combineU[PIXMAN_OP_IN] = vmxCombineInU;
+        pixman_composeFunctions.combineU[PIXMAN_OP_IN_REVERSE] = vmxCombineInReverseU;
+        pixman_composeFunctions.combineU[PIXMAN_OP_OUT] = vmxCombineOutU;
+        pixman_composeFunctions.combineU[PIXMAN_OP_OUT_REVERSE] = vmxCombineOutReverseU;
+        pixman_composeFunctions.combineU[PIXMAN_OP_ATOP] = vmxCombineAtopU;
+        pixman_composeFunctions.combineU[PIXMAN_OP_ATOP_REVERSE] = vmxCombineAtopReverseU;
+        pixman_composeFunctions.combineU[PIXMAN_OP_XOR] = vmxCombineXorU;
+        pixman_composeFunctions.combineU[PIXMAN_OP_ADD] = vmxCombineAddU;
+
+        pixman_composeFunctions.combineC[PIXMAN_OP_SRC] = vmxCombineSrcC;
+        pixman_composeFunctions.combineC[PIXMAN_OP_OVER] = vmxCombineOverC;
+        pixman_composeFunctions.combineC[PIXMAN_OP_OVER_REVERSE] = vmxCombineOverReverseC;
+        pixman_composeFunctions.combineC[PIXMAN_OP_IN] = vmxCombineInC;
+        pixman_composeFunctions.combineC[PIXMAN_OP_IN_REVERSE] = vmxCombineInReverseC;
+        pixman_composeFunctions.combineC[PIXMAN_OP_OUT] = vmxCombineOutC;
+        pixman_composeFunctions.combineC[PIXMAN_OP_OUT_REVERSE] = vmxCombineOutReverseC;
+        pixman_composeFunctions.combineC[PIXMAN_OP_ATOP] = vmxCombineAtopC;
+        pixman_composeFunctions.combineC[PIXMAN_OP_ATOP_REVERSE] = vmxCombineAtopReverseC;
+        pixman_composeFunctions.combineC[PIXMAN_OP_XOR] = vmxCombineXorC;
+        pixman_composeFunctions.combineC[PIXMAN_OP_ADD] = vmxCombineAddC;
+
+        pixman_composeFunctions.combineMaskU = vmxCombineMaskU;
+    }
+}
diff --git a/pixman/pixman-vmx.h b/pixman/pixman-vmx.h
new file mode 100644
index 0000000..70cb53a
--- /dev/null
+++ b/pixman/pixman-vmx.h
@@ -0,0 +1,308 @@
+/*
+ * Copyright Â© 2007 Luca Barbato
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Luca Barbato not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Luca Barbato makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Author:  Luca Barbato (lu_zero@gentoo.org)
+ *
+ * Based on work by Owen Taylor, Søren Sandmann and Lars Knoll
+ */
+
+#include "pixman-private.h"
+
+#ifdef USE_VMX
+
+pixman_bool_t pixman_have_vmx(void);
+
+#else
+#define pixman_have_vmx() FALSE
+#endif
+
+#ifdef USE_VMX
+
+#define AVV(x...) {x}
+
+void fbComposeSetupVMX (void);
+
+#if 0
+void fbCompositeIn_nx8x8vmx (pixman_operator_t	op,
+			     pixman_image_t * pSrc,
+			     pixman_image_t * pMask,
+			     pixman_image_t * pDst,
+			     INT16      xSrc,
+			     INT16      ySrc,
+			     INT16      xMask,
+			     INT16      yMask,
+			     INT16      xDst,
+			     INT16      yDst,
+			     CARD16     width,
+			     CARD16     height);
+
+void fbCompositeSolidMask_nx8888x0565Cvmx (pixman_operator_t      op,
+					   pixman_image_t * pSrc,
+					   pixman_image_t * pMask,
+					   pixman_image_t * pDst,
+					   INT16      xSrc,
+					   INT16      ySrc,
+					   INT16      xMask,
+					   INT16      yMask,
+					   INT16      xDst,
+					   INT16      yDst,
+					   CARD16     width,
+					   CARD16     height);
+
+void fbCompositeSrcAdd_8888x8888vmx (pixman_operator_t	op,
+				     pixman_image_t *	pSrc,
+				     pixman_image_t *	pMask,
+				     pixman_image_t *	pDst,
+				     INT16	xSrc,
+				     INT16      ySrc,
+				     INT16      xMask,
+				     INT16      yMask,
+				     INT16      xDst,
+				     INT16      yDst,
+				     CARD16     width,
+				     CARD16     height);
+
+void fbCompositeSolidMask_nx8888x8888Cvmx (pixman_operator_t	op,
+					   pixman_image_t *	pSrc,
+					   pixman_image_t *	pMask,
+					   pixman_image_t *	pDst,
+					   INT16	xSrc,
+					   INT16	ySrc,
+					   INT16	xMask,
+					   INT16	yMask,
+					   INT16	xDst,
+					   INT16	yDst,
+					   CARD16	width,
+					   CARD16	height);
+
+void fbCompositeSolidMask_nx8x8888vmx (pixman_operator_t      op,
+				       pixman_image_t * pSrc,
+				       pixman_image_t * pMask,
+				       pixman_image_t * pDst,
+				       INT16      xSrc,
+				       INT16      ySrc,
+				       INT16      xMask,
+				       INT16      yMask,
+				       INT16      xDst,
+				       INT16      yDst,
+				       CARD16     width,
+				       CARD16     height);
+
+void fbCompositeSolidMaskSrc_nx8x8888vmx (pixman_operator_t      op,
+					  pixman_image_t * pSrc,
+					  pixman_image_t * pMask,
+					  pixman_image_t * pDst,
+					  INT16      xSrc,
+					  INT16      ySrc,
+					  INT16      xMask,
+					  INT16      yMask,
+					  INT16      xDst,
+					  INT16      yDst,
+					  CARD16     width,
+					  CARD16     height);
+
+void fbCompositeSrcAdd_8888x8x8vmx (pixman_operator_t   op,
+				    pixman_image_t * pSrc,
+				    pixman_image_t * pMask,
+				    pixman_image_t * pDst,
+				    INT16      xSrc,
+				    INT16      ySrc,
+				    INT16      xMask,
+				    INT16      yMask,
+				    INT16      xDst,
+				    INT16      yDst,
+				    CARD16     width,
+				    CARD16     height);
+
+void fbCompositeIn_8x8vmx (pixman_operator_t	op,
+			   pixman_image_t * pSrc,
+			   pixman_image_t * pMask,
+			   pixman_image_t * pDst,
+			   INT16      xSrc,
+			   INT16      ySrc,
+			   INT16      xMask,
+			   INT16      yMask,
+			   INT16      xDst,
+			   INT16      yDst,
+			   CARD16     width,
+			   CARD16     height);
+
+void fbCompositeSrcAdd_8000x8000vmx (pixman_operator_t	op,
+				     pixman_image_t * pSrc,
+				     pixman_image_t * pMask,
+				     pixman_image_t * pDst,
+				     INT16      xSrc,
+				     INT16      ySrc,
+				     INT16      xMask,
+				     INT16      yMask,
+				     INT16      xDst,
+				     INT16      yDst,
+				     CARD16     width,
+				     CARD16     height);
+
+void fbCompositeSrc_8888RevNPx8888vmx (pixman_operator_t      op,
+				       pixman_image_t * pSrc,
+				       pixman_image_t * pMask,
+				       pixman_image_t * pDst,
+				       INT16      xSrc,
+				       INT16      ySrc,
+				       INT16      xMask,
+				       INT16      yMask,
+				       INT16      xDst,
+				       INT16      yDst,
+				       CARD16     width,
+				       CARD16     height);
+
+void fbCompositeSrc_8888x0565vmx (pixman_operator_t      op,
+				  pixman_image_t * pSrc,
+				  pixman_image_t * pMask,
+				  pixman_image_t * pDst,
+				  INT16      xSrc,
+				  INT16      ySrc,
+				  INT16      xMask,
+				  INT16      yMask,
+				  INT16      xDst,
+				  INT16      yDst,
+				  CARD16     width,
+				  CARD16     height);
+
+void fbCompositeSrc_8888RevNPx0565vmx (pixman_operator_t      op,
+				       pixman_image_t * pSrc,
+				       pixman_image_t * pMask,
+				       pixman_image_t * pDst,
+				       INT16      xSrc,
+				       INT16      ySrc,
+				       INT16      xMask,
+				       INT16      yMask,
+				       INT16      xDst,
+				       INT16      yDst,
+				       CARD16     width,
+				       CARD16     height);
+
+void fbCompositeSolid_nx8888vmx (pixman_operator_t		op,
+				 pixman_image_t *	pSrc,
+				 pixman_image_t *	pMask,
+				 pixman_image_t *	pDst,
+				 INT16		xSrc,
+				 INT16		ySrc,
+				 INT16		xMask,
+				 INT16		yMask,
+				 INT16		xDst,
+				 INT16		yDst,
+				 CARD16		width,
+				 CARD16		height);
+
+void fbCompositeSolid_nx0565vmx (pixman_operator_t		op,
+				 pixman_image_t *	pSrc,
+				 pixman_image_t *	pMask,
+				 pixman_image_t *	pDst,
+				 INT16		xSrc,
+				 INT16		ySrc,
+				 INT16		xMask,
+				 INT16		yMask,
+				 INT16		xDst,
+				 INT16		yDst,
+				 CARD16		width,
+				 CARD16		height);
+
+void fbCompositeSolidMask_nx8x0565vmx (pixman_operator_t      op,
+				       pixman_image_t * pSrc,
+				       pixman_image_t * pMask,
+				       pixman_image_t * pDst,
+				       INT16      xSrc,
+				       INT16      ySrc,
+				       INT16      xMask,
+				       INT16      yMask,
+				       INT16      xDst,
+				       INT16      yDst,
+				       CARD16     width,
+				       CARD16     height);
+
+void fbCompositeSrc_x888x8x8888vmx (pixman_operator_t	op,
+				    pixman_image_t *  pSrc,
+				    pixman_image_t *  pMask,
+				    pixman_image_t *  pDst,
+				    INT16	xSrc,
+				    INT16	ySrc,
+				    INT16       xMask,
+				    INT16       yMask,
+				    INT16       xDst,
+				    INT16       yDst,
+				    CARD16      width,
+				    CARD16      height);
+
+void fbCompositeSrc_8888x8x8888vmx (pixman_operator_t	op,
+				    pixman_image_t *  pSrc,
+				    pixman_image_t *  pMask,
+				    pixman_image_t *  pDst,
+				    INT16	xSrc,
+				    INT16	ySrc,
+				    INT16       xMask,
+				    INT16       yMask,
+				    INT16       xDst,
+				    INT16       yDst,
+				    CARD16      width,
+				    CARD16      height);
+
+void fbCompositeSrc_8888x8888vmx (pixman_operator_t      op,
+				  pixman_image_t * pSrc,
+				  pixman_image_t * pMask,
+				  pixman_image_t * pDst,
+				  INT16      xSrc,
+				  INT16      ySrc,
+				  INT16      xMask,
+				  INT16      yMask,
+				  INT16      xDst,
+				  INT16      yDst,
+				  CARD16     width,
+				  CARD16     height);
+
+pixman_bool_t fbCopyAreavmx (FbPixels	*pSrc,
+		    FbPixels	*pDst,
+		    int		src_x,
+		    int		src_y,
+		    int		dst_x,
+		    int		dst_y,
+		    int		width,
+		    int		height);
+
+void fbCompositeCopyAreavmx (pixman_operator_t	op,
+			     pixman_image_t *	pSrc,
+			     pixman_image_t *	pMask,
+			     pixman_image_t *	pDst,
+			     INT16	xSrc,
+			     INT16      ySrc,
+			     INT16      xMask,
+			     INT16      yMask,
+			     INT16      xDst,
+			     INT16      yDst,
+			     CARD16     width,
+			     CARD16     height);
+
+pixman_bool_t fbSolidFillvmx (FbPixels	*pDraw,
+		     int		x,
+		     int		y,
+		     int		width,
+		     int		height,
+		     FbBits		xor);
+#endif
+#endif /* USE_VMX */