Home | History | Annotate | Download | only in cpu_ref
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define ENTRY(f) .text; .align 4; .globl f; .type f,#function; f: .fnstart
     18 #define END(f) .fnend; .size f, .-f;
     19 
     20 .eabi_attribute 25,1 @Tag_ABI_align8_preserved
     21 .arm
     22 
     23 .macro lanepair dst, src, xr0, xr1, yr0, yr1, zr0, zr1
     24 
     25             vmov        r6, r7, \src
     26 
     27             add         r6, r6, r3
     28             add         r7, r7, r3
     29 
     30             vld1.u8     d16, [r6], r4
     31             vld1.u8     d17, [r7], r4
     32 
     33             vld1.u8     d18, [r6], r5
     34             vld1.u8     d19, [r7], r5
     35 
     36             vdup.u8     d6, \yr0
     37             vdup.u8     d7, \yr1
     38             /* Y interpolate, front, lanes 0 and 1 -> q12 and q13 */
     39             vshll.u8    q12, d16, #8
     40             vshll.u8    q13, d17, #8
     41             vmlsl.u8    q12, d16, d6
     42             vmlsl.u8    q13, d17, d7
     43             vmlal.u8    q12, d18, d6
     44             vmlal.u8    q13, d19, d7
     45 
     46             vld1.u8     d18, [r6]
     47             vld1.u8     d19, [r7]
     48 
     49             sub         r6, r6, r4
     50             sub         r7, r7, r4
     51 
     52             vld1.u8     d16, [r6]
     53             vld1.u8     d17, [r7]
     54 
     55             /* Y interpolate, rear, lanes 0 and 1 -> q14 and q15 */
     56             vshll.u8    q14, d16, #8
     57             vshll.u8    q15, d17, #8
     58             vmlsl.u8    q14, d16, d6
     59             vmlsl.u8    q15, d17, d7
     60             vmlal.u8    q14, d18, d6
     61             vmlal.u8    q15, d19, d7
     62 
     63             /* Z interpolate, lane 0 q12/q14 -> q10 */
     64             vshll.u16   q8, d24, #8
     65             vshll.u16   q9, d25, #8
     66             vmlsl.u16   q8, d24, \zr0
     67             vmlsl.u16   q9, d25, \zr0
     68             vmlal.u16   q8, d28, \zr0
     69             vmlal.u16   q9, d29, \zr0
     70             vrshrn.u32  d20, q8, #8
     71             vrshrn.u32  d21, q9, #8
     72 
     73             /* Z interpolate, lane 1 q13/q15 -> q11 */
     74             vshll.u16   q8, d26, #8
     75             vshll.u16   q9, d27, #8
     76             vmlsl.u16   q8, d26, \zr1
     77             vmlsl.u16   q9, d27, \zr1
     78             vmlal.u16   q8, d30, \zr1
     79             vmlal.u16   q9, d31, \zr1
     80             vrshrn.u32  d22, q8, #8
     81             vrshrn.u32  d23, q9, #8
     82 
     83             /* X interpolate, lanes 0 and 1 q10,q11 -> q14 */
     84             vshll.u16   q8, d20, #8
     85             vshll.u16   q9, d22, #8
     86             vmlsl.u16   q8, d20, \xr0
     87             vmlsl.u16   q9, d22, \xr1
     88             vmlal.u16   q8, d21, \xr0
     89             vmlal.u16   q9, d23, \xr1
     90             vshrn.u32   d28, q8, #8
     91             vshrn.u32   d29, q9, #8
     92 
     93             /* pack lanes 0-1 -> d12 */
     94             vqrshrn.u16  \dst, q14, #8
     95 .endm
     96 
     97 /* void rsdIntrinsic3DLUT_K(
     98  *          void *dst,          // r0
     99  *          void const *in,     // r1
    100  *          size_t count,       // r2
    101  *          void const *lut,    // r3
    102  *          int32_t pitchy,     // [sp]
    103  *          int32_t pitchz,     // [sp+#4]
    104  *          int dimx,           // [sp+#8]
    105  *          int dimy,           // [sp+#12]
    106  *          int dimz);          // [sp+#16]
    107  */
    108 ENTRY(rsdIntrinsic3DLUT_K)
    109             push        {r4,r5,r6,r7}
    110             ldr         r4, [sp, #16]
    111             ldr         r5, [sp, #20]
    112             ldr         r6, [sp, #24]
    113             ldr         r7, [sp, #28]
    114             ldr         r12, [sp, #32]
    115             vpush       {d8-d15}
    116 
    117             vmov.u8     d8, #1
    118             vmov.u16    d8[0], r6
    119             vmov.u16    d8[1], r7
    120             vmov.u16    d8[2], r12
    121             vmov        d9, r4, r5
    122 
    123             subs        r2, #8
    124             bge         2f
    125             cmp         r2, #-8
    126             ble         9f
    127             b           4f
    128 
    129             .align 6
    130 1:          vst4.u8     {d12,d13,d14,d15}, [r0]!
    131 /* r0  = dst
    132  * r1  = src
    133  * r2  = count
    134  * r3  = lut
    135  * r4  = pitchy
    136  * r5  = pitchz
    137  * r6 = offset0
    138  * r7 = offset1
    139  */
    140 2:          vld4.u8     {d0,d2,d4,d6}, [r1]!
    141 3:          vmov        d10, d6
    142 /* q0,q1,q2,q5 source data
    143  * q4 dimensions and pitches
    144  * q3, scratch register for scalar access
    145  */
    146             vmov        q3, q4
    147             vmovl.u8    q0, d0
    148             vmovl.u8    q1, d2
    149             vmovl.u8    q2, d4
    150             vmul.u16    q0, q0, d6[0]
    151             vmul.u16    q1, q1, d6[1]
    152             vmul.u16    q2, q2, d6[2]
    153 
    154 /* vrsra.u16 below would be more accurate, but this can result in a dim.0 case
    155  * where we try to read from the limit of the array and the limit +1 to
    156  * interpolate, even though the fractional component is zero.  Strictly this is
    157  * correct, except for the llegal access problem.
    158  */
    159             vsra.u16    q0, q0, #8
    160             vsra.u16    q1, q1, #8
    161             vsra.u16    q2, q2, #8
    162 
    163             vshr.u16    q12, q0, #8
    164             vshr.u16    q13, q1, #8
    165             vshr.u16    q14, q2, #8
    166 
    167             vbic.u16    q0, #0xff00
    168             vmovn.u16   d2, q1
    169             vbic.u16    q2, #0xff00
    170 
    171 /* q0,d2,q2 fractional offset
    172  * q12,q13,q14 integer offset
    173  */
    174 
    175             vshll.u16   q6, d24, #2
    176             vshll.u16   q7, d25, #2
    177             vmovl.u16   q8, d26
    178             vmovl.u16   q9, d27
    179             vmovl.u16   q10, d28
    180             vmovl.u16   q11, d29
    181             vmla.s32    q6, q8,  d9[0]
    182             vmla.s32    q7, q9,  d9[0]
    183             vmla.s32    q6, q10, d9[1]
    184             vmla.s32    q7, q11, d9[1]
    185 
    186 /* q6,q7 list of table offsets */
    187 
    188         /* lanes 0 and 1 */
    189             lanepair dst=d12, src=d12, xr0=d0[0], xr1=d0[1], yr0=d2[0], yr1=d2[1], zr0=d4[0], zr1=d4[1]
    190 
    191         /* lanes 2 and 3 */
    192             lanepair dst=d13, src=d13, xr0=d0[2], xr1=d0[3], yr0=d2[2], yr1=d2[3], zr0=d4[2], zr1=d4[3]
    193 
    194         /* lanes 4 and 5 */
    195             lanepair dst=d14, src=d14, xr0=d1[0], xr1=d1[1], yr0=d2[4], yr1=d2[5], zr0=d5[0], zr1=d5[1]
    196 
    197         /* lanes 6 and 7 */
    198             lanepair dst=d15, src=d15, xr0=d1[2], xr1=d1[3], yr0=d2[6], yr1=d2[7], zr0=d5[2], zr1=d5[3]
    199 
    200             vuzp.u8     d12, d13
    201             vuzp.u8     d14, d15
    202             vuzp.u8     d12, d14
    203             vuzp.u8     d13, d15
    204 
    205             subs        r2, r2, #8
    206             vmov.u8     d15, d10
    207 
    208             bge         1b
    209 
    210             cmp         r2, #-8
    211             blt         1f
    212 
    213             vst4.u8     {d12,d13,d14,d15}, [r0]!
    214 
    215             beq         9f
    216 
    217             /* fill the vector with a safe value */
    218 4:          vld1.u32    {d0[]}, [r1]
    219             vmov        d2, d0
    220             vmov        d4, d0
    221             vmov        d6, d0
    222             tst         r2, #4
    223             beq         2f
    224             vld1.u32    {d0}, [r1]!
    225             vld1.u32    {d2}, [r1]!
    226 2:          tst         r2, #2
    227             beq         2f
    228             vld1.u32    {d4}, [r1]!
    229 2:          tst         r2, #1
    230             beq         2f
    231             vld1.u32    {d6[0]}, [r1]!
    232 2:          vuzp.8      d0, d2
    233             vuzp.8      d4, d6
    234             vuzp.8      d0, d4
    235             vuzp.8      d2, d6
    236             b           3b
    237 
    238 1:          vzip.8      d12, d14
    239             vzip.8      d13, d15
    240             vzip.8      d12, d13
    241             vzip.8      d14, d15
    242             tst         r2, #4
    243             beq         2f
    244             vst1.u32    {d12,d13}, [r0]!
    245 2:          tst         r2, #2
    246             beq         2f
    247             vst1.u32    {d14}, [r0]!
    248 2:          tst         r2, #1
    249             beq         9f
    250             vst1.u32    {d15[0]}, [r0]!
    251 
    252 9:          mov         r0, #0
    253             vpop        {d8-d15}
    254             pop         {r4,r5,r6,r7}
    255             bx lr
    256 END(rsdIntrinsic3DLUT_K)
    257