shithub: libvpx

Download patch

ref: 2a4b2a000c9c506d972798884e10c14fb2efedc9
parent: 35ce4eb01d2ef02e0ab930bf8327aabd95189a52
author: Tero Rintaluoma <teror@google.com>
date: Mon Sep 19 06:15:33 EDT 2011

NEON walsh transform updated to match C

Modified original patch If2f07220885c4c3a0cae0dace34ea0e36124f001
according to comments. Scheduled code a little bit to prevent some
interlocks.

Change-Id: I338f02b881098782f82af63d97f042b85e63e902

--- a/vp8/encoder/arm/neon/vp8_shortwalsh4x4_neon.asm
+++ b/vp8/encoder/arm/neon/vp8_shortwalsh4x4_neon.asm
@@ -16,58 +16,85 @@
     PRESERVE8
 
     AREA ||.text||, CODE, READONLY, ALIGN=2
-;void vp8_short_walsh4x4_c(short *input, short *output, int pitch)
-
+;void vp8_short_walsh4x4_neon(short *input, short *output, int pitch)
+; r0   short *input,
+; r1   short *output,
+; r2   int pitch
 |vp8_short_walsh4x4_neon| PROC
-    vld1.16         {d2}, [r0], r2              ;load input
-    vld1.16         {d3}, [r0], r2
-    vld1.16         {d4}, [r0], r2
-    vld1.16         {d5}, [r0], r2
 
+    vld1.16         {d0}, [r0@64], r2   ; load input
+    vld1.16         {d1}, [r0@64], r2
+    vld1.16         {d2}, [r0@64], r2
+    vld1.16         {d3}, [r0@64]
+
     ;First for-loop
-    ;transpose d2, d3, d4, d5. Then, d2=ip[0], d3=ip[1], d4=ip[2], d5=ip[3]
-    vtrn.32         d2, d4
-    vtrn.32         d3, d5
+    ;transpose d0, d1, d2, d3. Then, d0=ip[0], d1=ip[1], d2=ip[2], d3=ip[3]
+    vtrn.32         d0, d2
+    vtrn.32         d1, d3
+
+    vmov.s32        q15, #3             ; add 3 to all values
+
+    vtrn.16         d0, d1
     vtrn.16         d2, d3
-    vtrn.16         d4, d5
 
-    vadd.s16        d6, d2, d5              ;a1 = ip[0]+ip[3]
-    vadd.s16        d7, d3, d4              ;b1 = ip[1]+ip[2]
-    vsub.s16        d8, d3, d4              ;c1 = ip[1]-ip[2]
-    vsub.s16        d9, d2, d5              ;d1 = ip[0]-ip[3]
+    vadd.s16        d4, d0, d2          ; ip[0] + ip[2]
+    vadd.s16        d5, d1, d3          ; ip[1] + ip[3]
+    vsub.s16        d6, d1, d3          ; ip[1] - ip[3]
+    vsub.s16        d7, d0, d2          ; ip[0] - ip[2]
 
-    vadd.s16        d2, d6, d7             ;op[0] = a1 + b1
-    vsub.s16        d4, d6, d7             ;op[2] = a1 - b1
-    vadd.s16        d3, d8, d9             ;op[1] = c1 + d1
-    vsub.s16        d5, d9, d8             ;op[3] = d1 - c1
+    vshl.s16        d4, d4, #2          ; a1 = (ip[0] + ip[2]) << 2
+    vshl.s16        d5, d5, #2          ; d1 = (ip[1] + ip[3]) << 2
+    vshl.s16        d6, d6, #2          ; c1 = (ip[1] - ip[3]) << 2
+    vceq.s16        d16, d4, #0         ; a1 == 0
+    vshl.s16        d7, d7, #2          ; b1 = (ip[0] - ip[2]) << 2
 
+    vadd.s16        d0, d4, d5          ; a1 + d1
+    vmvn            d16, d16            ; a1 != 0
+    vsub.s16        d3, d4, d5          ; op[3] = a1 - d1
+    vadd.s16        d1, d7, d6          ; op[1] = b1 + c1
+    vsub.s16        d2, d7, d6          ; op[2] = b1 - c1
+    vsub.s16        d0, d0, d16         ; op[0] = a1 + d1 + (a1 != 0)
+
     ;Second for-loop
-    ;transpose d2, d3, d4, d5. Then, d2=ip[0], d3=ip[4], d4=ip[8], d5=ip[12]
-    vtrn.32         d2, d4
-    vtrn.32         d3, d5
+    ;transpose d0, d1, d2, d3, Then, d0=ip[0], d1=ip[4], d2=ip[8], d3=ip[12]
+    vtrn.32         d1, d3
+    vtrn.32         d0, d2
     vtrn.16         d2, d3
-    vtrn.16         d4, d5
+    vtrn.16         d0, d1
 
-    vadd.s16        d6, d2, d5              ;a1 = ip[0]+ip[12]
-    vadd.s16        d7, d3, d4              ;b1 = ip[4]+ip[8]
-    vsub.s16        d8, d3, d4              ;c1 = ip[4]-ip[8]
-    vsub.s16        d9, d2, d5              ;d1 = ip[0]-ip[12]
+    vaddl.s16       q8, d0, d2          ; a1 = ip[0]+ip[8]
+    vaddl.s16       q9, d1, d3          ; d1 = ip[4]+ip[12]
+    vsubl.s16       q10, d1, d3         ; c1 = ip[4]-ip[12]
+    vsubl.s16       q11, d0, d2         ; b1 = ip[0]-ip[8]
 
-    vadd.s16        d2, d6, d7              ;a2 = a1 + b1;
-    vsub.s16        d4, d6, d7              ;c2 = a1 - b1;
-    vadd.s16        d3, d8, d9              ;b2 = c1 + d1;
-    vsub.s16        d5, d9, d8              ;d2 = d1 - c1;
+    vadd.s32        q0, q8, q9          ; a2 = a1 + d1
+    vadd.s32        q1, q11, q10        ; b2 = b1 + c1
+    vsub.s32        q2, q11, q10        ; c2 = b1 - c1
+    vsub.s32        q3, q8, q9          ; d2 = a1 - d1
 
-    vcgt.s16        q3, q1, #0
-    vcgt.s16        q4, q2, #0
+    vclt.s32        q8, q0, #0
+    vclt.s32        q9, q1, #0
+    vclt.s32        q10, q2, #0
+    vclt.s32        q11, q3, #0
 
-    vsub.s16        q1, q1, q3
-    vsub.s16        q2, q2, q4
+    ; subtract -1 (or 0)
+    vsub.s32        q0, q0, q8          ; a2 += a2 < 0
+    vsub.s32        q1, q1, q9          ; b2 += b2 < 0
+    vsub.s32        q2, q2, q10         ; c2 += c2 < 0
+    vsub.s32        q3, q3, q11         ; d2 += d2 < 0
 
-    vshr.s16        q1, q1, #1
-    vshr.s16        q2, q2, #1
+    vadd.s32        q8, q0, q15         ; a2 + 3
+    vadd.s32        q9, q1, q15         ; b2 + 3
+    vadd.s32        q10, q2, q15        ; c2 + 3
+    vadd.s32        q11, q3, q15        ; d2 + 3
 
-    vst1.16         {q1, q2}, [r1]
+    ; vrshrn? would add 1 << 3-1 = 2
+    vshrn.s32       d0, q8, #3
+    vshrn.s32       d1, q9, #3
+    vshrn.s32       d2, q10, #3
+    vshrn.s32       d3, q11, #3
+
+    vst1.16         {q0, q1}, [r1@128]
 
     bx              lr