1; 2; Copyright (c) 2011 The WebM project authors. All Rights Reserved. 3; 4; Use of this source code is governed by a BSD-style license 5; that can be found in the LICENSE file in the root of the source 6; tree. An additional intellectual property rights grant can be found 7; in the file PATENTS. All contributing project authors may 8; be found in the AUTHORS file in the root of the source tree. 9; 10 11 12 EXPORT |vp8_fast_quantize_b_neon| 13 EXPORT |vp8_fast_quantize_b_pair_neon| 14 15 INCLUDE vp8_asm_enc_offsets.asm 16 17 ARM 18 REQUIRE8 19 PRESERVE8 20 21 AREA ||.text||, CODE, READONLY, ALIGN=4 22 23;vp8_fast_quantize_b_pair_neon(BLOCK *b1, BLOCK *b2, BLOCKD *d1, BLOCKD *d2); 24|vp8_fast_quantize_b_pair_neon| PROC 25 26 stmfd sp!, {r4-r9} 27 vstmdb sp!, {q4-q7} 28 29 ldr r4, [r0, #vp8_block_coeff] 30 ldr r5, [r0, #vp8_block_quant_fast] 31 ldr r6, [r0, #vp8_block_round] 32 33 vld1.16 {q0, q1}, [r4@128] ; load z 34 35 ldr r7, [r2, #vp8_blockd_qcoeff] 36 37 vabs.s16 q4, q0 ; calculate x = abs(z) 38 vabs.s16 q5, q1 39 40 ;right shift 15 to get sign, all 0 if it is positive, all 1 if it is negative 41 vshr.s16 q2, q0, #15 ; sz 42 vshr.s16 q3, q1, #15 43 44 vld1.s16 {q6, q7}, [r6@128] ; load round_ptr [0-15] 45 vld1.s16 {q8, q9}, [r5@128] ; load quant_ptr [0-15] 46 47 ldr r4, [r1, #vp8_block_coeff] 48 49 vadd.s16 q4, q6 ; x + Round 50 vadd.s16 q5, q7 51 52 vld1.16 {q0, q1}, [r4@128] ; load z2 53 54 vqdmulh.s16 q4, q8 ; y = ((Round+abs(z)) * Quant) >> 16 55 vqdmulh.s16 q5, q9 56 57 vabs.s16 q10, q0 ; calculate x2 = abs(z_2) 58 vabs.s16 q11, q1 59 vshr.s16 q12, q0, #15 ; sz2 60 vshr.s16 q13, q1, #15 61 62 ;modify data to have its original sign 63 veor.s16 q4, q2 ; y^sz 64 veor.s16 q5, q3 65 66 vadd.s16 q10, q6 ; x2 + Round 67 vadd.s16 q11, q7 68 69 ldr r8, [r2, #vp8_blockd_dequant] 70 71 vqdmulh.s16 q10, q8 ; y2 = ((Round+abs(z)) * Quant) >> 16 72 vqdmulh.s16 q11, q9 73 74 vshr.s16 q4, #1 ; right shift 1 after vqdmulh 75 vshr.s16 q5, #1 76 77 vld1.s16 {q6, q7}, [r8@128] ;load dequant_ptr[i] 78 79 vsub.s16 q4, q2 ; x1=(y^sz)-sz = (y^sz)-(-1) (2's complement) 80 vsub.s16 q5, q3 81 82 vshr.s16 q10, #1 ; right shift 1 after vqdmulh 83 vshr.s16 q11, #1 84 85 ldr r9, [r2, #vp8_blockd_dqcoeff] 86 87 veor.s16 q10, q12 ; y2^sz2 88 veor.s16 q11, q13 89 90 vst1.s16 {q4, q5}, [r7] ; store: qcoeff = x1 91 92 93 vsub.s16 q10, q12 ; x2=(y^sz)-sz = (y^sz)-(-1) (2's complement) 94 vsub.s16 q11, q13 95 96 ldr r6, [r3, #vp8_blockd_qcoeff] 97 98 vmul.s16 q2, q6, q4 ; x * Dequant 99 vmul.s16 q3, q7, q5 100 101 adr r0, inv_zig_zag ; load ptr of inverse zigzag table 102 103 vceq.s16 q8, q8 ; set q8 to all 1 104 105 vst1.s16 {q10, q11}, [r6] ; store: qcoeff = x2 106 107 vmul.s16 q12, q6, q10 ; x2 * Dequant 108 vmul.s16 q13, q7, q11 109 110 vld1.16 {q6, q7}, [r0@128] ; load inverse scan order 111 112 vtst.16 q14, q4, q8 ; now find eob 113 vtst.16 q15, q5, q8 ; non-zero element is set to all 1 114 115 vst1.s16 {q2, q3}, [r9] ; store dqcoeff = x * Dequant 116 117 ldr r7, [r3, #vp8_blockd_dqcoeff] 118 119 vand q0, q6, q14 ; get all valid numbers from scan array 120 vand q1, q7, q15 121 122 vst1.s16 {q12, q13}, [r7] ; store dqcoeff = x * Dequant 123 124 vtst.16 q2, q10, q8 ; now find eob 125 vtst.16 q3, q11, q8 ; non-zero element is set to all 1 126 127 vmax.u16 q0, q0, q1 ; find maximum value in q0, q1 128 129 vand q10, q6, q2 ; get all valid numbers from scan array 130 vand q11, q7, q3 131 vmax.u16 q10, q10, q11 ; find maximum value in q10, q11 132 133 vmax.u16 d0, d0, d1 134 vmax.u16 d20, d20, d21 135 vmovl.u16 q0, d0 136 vmovl.u16 q10, d20 137 138 vmax.u32 d0, d0, d1 139 vmax.u32 d20, d20, d21 140 vpmax.u32 d0, d0, d0 141 vpmax.u32 d20, d20, d20 142 143 ldr r4, [r2, #vp8_blockd_eob] 144 ldr r5, [r3, #vp8_blockd_eob] 145 146 vst1.8 {d0[0]}, [r4] ; store eob 147 vst1.8 {d20[0]}, [r5] ; store eob 148 149 vldmia sp!, {q4-q7} 150 ldmfd sp!, {r4-r9} 151 bx lr 152 153 ENDP 154 155;void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d) 156|vp8_fast_quantize_b_neon| PROC 157 158 stmfd sp!, {r4-r7} 159 160 ldr r3, [r0, #vp8_block_coeff] 161 ldr r4, [r0, #vp8_block_quant_fast] 162 ldr r5, [r0, #vp8_block_round] 163 164 vld1.16 {q0, q1}, [r3@128] ; load z 165 vorr.s16 q14, q0, q1 ; check if all zero (step 1) 166 ldr r6, [r1, #vp8_blockd_qcoeff] 167 ldr r7, [r1, #vp8_blockd_dqcoeff] 168 vorr.s16 d28, d28, d29 ; check if all zero (step 2) 169 170 vabs.s16 q12, q0 ; calculate x = abs(z) 171 vabs.s16 q13, q1 172 173 ;right shift 15 to get sign, all 0 if it is positive, all 1 if it is negative 174 vshr.s16 q2, q0, #15 ; sz 175 vmov r2, r3, d28 ; check if all zero (step 3) 176 vshr.s16 q3, q1, #15 177 178 vld1.s16 {q14, q15}, [r5@128]; load round_ptr [0-15] 179 vld1.s16 {q8, q9}, [r4@128] ; load quant_ptr [0-15] 180 181 vadd.s16 q12, q14 ; x + Round 182 vadd.s16 q13, q15 183 184 adr r0, inv_zig_zag ; load ptr of inverse zigzag table 185 186 vqdmulh.s16 q12, q8 ; y = ((Round+abs(z)) * Quant) >> 16 187 vqdmulh.s16 q13, q9 188 189 vld1.16 {q10, q11}, [r0@128]; load inverse scan order 190 191 vceq.s16 q8, q8 ; set q8 to all 1 192 193 ldr r4, [r1, #vp8_blockd_dequant] 194 195 vshr.s16 q12, #1 ; right shift 1 after vqdmulh 196 vshr.s16 q13, #1 197 198 ldr r5, [r1, #vp8_blockd_eob] 199 200 orr r2, r2, r3 ; check if all zero (step 4) 201 cmp r2, #0 ; check if all zero (step 5) 202 beq zero_output ; check if all zero (step 6) 203 204 ;modify data to have its original sign 205 veor.s16 q12, q2 ; y^sz 206 veor.s16 q13, q3 207 208 vsub.s16 q12, q2 ; x1=(y^sz)-sz = (y^sz)-(-1) (2's complement) 209 vsub.s16 q13, q3 210 211 vld1.s16 {q2, q3}, [r4@128] ; load dequant_ptr[i] 212 213 vtst.16 q14, q12, q8 ; now find eob 214 vtst.16 q15, q13, q8 ; non-zero element is set to all 1 215 216 vst1.s16 {q12, q13}, [r6@128]; store: qcoeff = x1 217 218 vand q10, q10, q14 ; get all valid numbers from scan array 219 vand q11, q11, q15 220 221 222 vmax.u16 q0, q10, q11 ; find maximum value in q0, q1 223 vmax.u16 d0, d0, d1 224 vmovl.u16 q0, d0 225 226 vmul.s16 q2, q12 ; x * Dequant 227 vmul.s16 q3, q13 228 229 vmax.u32 d0, d0, d1 230 vpmax.u32 d0, d0, d0 231 232 vst1.s16 {q2, q3}, [r7@128] ; store dqcoeff = x * Dequant 233 234 vst1.8 {d0[0]}, [r5] ; store eob 235 236 ldmfd sp!, {r4-r7} 237 bx lr 238 239zero_output 240 strb r2, [r5] ; store eob 241 vst1.s16 {q0, q1}, [r6@128] ; qcoeff = 0 242 vst1.s16 {q0, q1}, [r7@128] ; dqcoeff = 0 243 244 ldmfd sp!, {r4-r7} 245 bx lr 246 247 ENDP 248 249; default inverse zigzag table is defined in vp8/common/entropy.c 250 ALIGN 16 ; enable use of @128 bit aligned loads 251inv_zig_zag 252 DCW 0x0001, 0x0002, 0x0006, 0x0007 253 DCW 0x0003, 0x0005, 0x0008, 0x000d 254 DCW 0x0004, 0x0009, 0x000c, 0x000e 255 DCW 0x000a, 0x000b, 0x000f, 0x0010 256 257 END 258 259