From 12059868a5c9192bb15aa08e8d25562d52d389dd Mon Sep 17 00:00:00 2001
From: kui zheng <kui.zheng@arm.com>
Date: Wed, 16 Nov 2011 17:08:45 +0800
Subject: [PATCH] generic: Add NEON version of Dacc_modulate_argb


Signed-off-by: kui zheng <kui.zheng@arm.com>
---
 src/gfx/generic/generic.c      |    5 ++
 src/gfx/generic/generic_neon.h |   93 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 98 insertions(+), 0 deletions(-)

diff --git a/src/gfx/generic/generic.c b/src/gfx/generic/generic.c
index 461da55..a697155 100644
--- a/src/gfx/generic/generic.c
+++ b/src/gfx/generic/generic.c
@@ -9668,6 +9668,11 @@ static void gInit_NEON( void )
 /********************************* Xacc_blend *********************************/
      Xacc_blend[DSBF_INVSRCALPHA-1] = Xacc_blend_invsrcalpha_NEON;
      Xacc_blend[DSBF_SRCALPHA-1] = Xacc_blend_srcalpha_NEON;
+/********************************* Dacc_modulation ****************************/
+     Dacc_modulation[DSBLIT_BLEND_ALPHACHANNEL |
+                     DSBLIT_BLEND_COLORALPHA |
+                     DSBLIT_COLORIZE] = Dacc_modulate_argb_NEON;
+
 }
 
 #endif
diff --git a/src/gfx/generic/generic_neon.h b/src/gfx/generic/generic_neon.h
index e601b8f..79088e6 100644
--- a/src/gfx/generic/generic_neon.h
+++ b/src/gfx/generic/generic_neon.h
@@ -884,3 +884,96 @@ static void Xacc_blend_srcalpha_NEON( GenefxState *gfxs )
      else
           Xacc_blend_srcalpha_Sacc0_NEON ( gfxs );  
 }
+
+/* 
+ * NEON version of Dacc_modulate_argb_NEON.
+ */
+static void Dacc_modulate_argb_NEON( GenefxState *gfxs )
+{
+     int                w = gfxs->length;
+     GenefxAccumulator *D = gfxs->Dacc;
+     GenefxAccumulator  Cacc = gfxs->Cacc;
+     unsigned int       loop = w >> 3;
+     unsigned int       single = w & 0x7;
+     u16                maska = 0xF000;
+
+     while (single){
+          if (!(D->RGB.a & 0xF000)) {
+               D->RGB.a = (Cacc.RGB.a * D->RGB.a) >> 8;
+               D->RGB.r = (Cacc.RGB.r * D->RGB.r) >> 8;
+               D->RGB.g = (Cacc.RGB.g * D->RGB.g) >> 8;
+               D->RGB.b = (Cacc.RGB.b * D->RGB.b) >> 8;
+          }
+          D++;
+          single--;
+     }
+
+     if (loop) {
+          __asm__ __volatile__ (
+               "mov             r4, %[D]        \n\t"
+               "mov             r5, %[D]        \n\t"
+               "vdup.16         q3, %[Cacc_a]   \n\t"
+               "vdup.16         q2, %[Cacc_r]   \n\t"
+               "vdup.16         q1, %[Cacc_g]   \n\t"
+               "vdup.16         q0, %[Cacc_b]   \n\t"
+               "vdup.16         q8, %[maska]    \n\t"
+               "1:                              \n\t"
+               "pld             [r4, #0xC0]     \n\t"
+               "pld             [r4, #0x100]     \n\t"
+               /* vload q4:b, q5:g, q6:r, q7:a */
+               "vld4.16         {d8, d10, d12, d14}, [r4]! \n\t"
+               "vld4.16         {d9, d11, d13, d15}, [r4]! \n\t"
+
+               "vand            q9, q7, q8      \n\t"
+               "vceq.i16        q9, q9, #0      \n\t"
+               /* b:q10  q0, q4 */
+               "vmull.u16       q14, d8, d0     \n\t"
+               "vshrn.i32       d20, q14, #8    \n\t"
+               "vmull.u16       q14, d9, d1     \n\t"
+               "vshrn.i32       d21, q14, #8    \n\t"
+               /* g:q11, q1, q5 */
+               "vmull.u16       q14, d10, d2    \n\t"
+               "vshrn.i32       d22, q14, #8    \n\t"
+               "vmull.u16       q14, d11, d3    \n\t"
+               "vshrn.i32       d23, q14, #8    \n\t"
+               /* r:q12, q2, q6 */
+               "vmull.u16       q14, d12, d4    \n\t"
+               "vshrn.i32       d24, q14, #8    \n\t"
+               "vmull.u16       q14, d13, d5    \n\t"
+               "vshrn.i32       d25, q14, #8    \n\t"
+               /* a:q13, q3, q7 */
+               "vmull.u16       q14, d14, d6    \n\t"
+               "vshrn.i32       d26, q14, #8    \n\t"
+               "vmull.u16       q14, d15, d7    \n\t"
+               "vshrn.i32       d27, q14, #8    \n\t"
+               /* if (!(D->RGB.a & 0xF000)) */
+               "vand            q10, q9, q10    \n\t"
+               "vand            q11, q9, q11    \n\t"
+               "vand            q12, q9, q12    \n\t"
+               "vand            q13, q9, q13    \n\t"
+               /* if ((D->RGB.a & 0xF000)) */
+               "vceq.i16        q9, q9, #0      \n\t"
+               "vand            q4, q9, q4      \n\t"
+               "vand            q5, q9, q5      \n\t"
+               "vand            q6, q9, q6      \n\t"
+               "vand            q7, q9, q7      \n\t"
+               /* Dacc: q4(b), q5(g), q6(r), q7(a) */
+               "vorr            q4, q4, q10     \n\t"
+               "vorr            q5, q5, q11     \n\t"
+               "vorr            q6, q6, q12     \n\t"
+               "vorr            q7, q7, q13     \n\t"
+               "vst4.16         {d8, d10, d12, d14}, [r5]! \n\t"
+               "vst4.16         {d9, d11, d13, d15}, [r5]! \n\t"
+               "subs            %[loop], %[loop], #1       \n\t"
+               "bne             1b                 "
+               :
+               : [Cacc_a] "r" (Cacc.RGB.a), [Cacc_r] "r" (Cacc.RGB.r),
+                 [Cacc_g] "r" (Cacc.RGB.g), [Cacc_b] "r" (Cacc.RGB.b),
+                 [D] "r" (D), [maska] "r" (maska), [loop] "r" (loop)
+               : "memory", "r4", "r5", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
+                 "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", "d16", "d17", "d18",
+                 "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29"
+          );
+     }
+
+}
-- 
1.7.1

