1/**************************************************************************** 2 * quant.S: arm quantization and level-run 3 ***************************************************************************** 4 * Copyright (C) 2009-2014 x264 project 5 * 6 * Authors: David Conrad <lessen42@gmail.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. 21 * 22 * This program is also available under a commercial proprietary license. 23 * For more information, contact us at licensing@x264.com. 24 *****************************************************************************/ 25 26#include "asm.S" 27 28.section .rodata 29.align 4 30pmovmskb_byte: 31.byte 1,2,4,8,16,32,64,128 32.byte 1,2,4,8,16,32,64,128 33 34.text 35 36.macro QUANT_TWO bias0 bias1 mf0 mf1 mf2 mf3 mask load_mf=no 37 vadd.u16 q8, q8, \bias0 38 vadd.u16 q9, q9, \bias1 39.ifc \load_mf, yes 40 vld1.64 {\mf0-\mf3}, [r1,:128]! 41.endif 42 vmull.u16 q10, d16, \mf0 43 vmull.u16 q11, d17, \mf1 44 vmull.u16 q12, d18, \mf2 45 vmull.u16 q13, d19, \mf3 46 vshr.s16 q14, q14, #15 47 vshr.s16 q15, q15, #15 48 vshrn.u32 d16, q10, #16 49 vshrn.u32 d17, q11, #16 50 vshrn.u32 d18, q12, #16 51 vshrn.u32 d19, q13, #16 52 veor q8, q8, q14 53 veor q9, q9, q15 54 vsub.s16 q8, q8, q14 55 vsub.s16 q9, q9, q15 56 vorr \mask, q8, q9 57 vst1.64 {d16-d19}, [r0,:128]! 58.endm 59 60.macro QUANT_END d 61 vmov r2, r3, \d 62 orrs r0, r2, r3 63 movne r0, #1 64 bx lr 65.endm 66 67// quant_2x2_dc( int16_t dct[4], int mf, int bias ) 68function x264_quant_2x2_dc_neon 69 vld1.64 {d0}, [r0,:64] 70 vabs.s16 d3, d0 71 vdup.16 d2, r2 72 vdup.16 d1, r1 73 vadd.u16 d3, d3, d2 74 vmull.u16 q3, d3, d1 75 vshr.s16 d0, d0, #15 76 vshrn.u32 d3, q3, #16 77 veor d3, d3, d0 78 vsub.s16 d3, d3, d0 79 vst1.64 {d3}, [r0,:64] 80 QUANT_END d3 81endfunc 82 83// quant_4x4_dc( int16_t dct[16], int mf, int bias ) 84function x264_quant_4x4_dc_neon 85 vld1.64 {d28-d31}, [r0,:128] 86 vabs.s16 q8, q14 87 vabs.s16 q9, q15 88 vdup.16 q0, r2 89 vdup.16 q2, r1 90 QUANT_TWO q0, q0, d4, d5, d4, d5, q0 91 vorr d0, d0, d1 92 QUANT_END d0 93endfunc 94 95// quant_4x4( int16_t dct[16], uint16_t mf[16], uint16_t bias[16] ) 96function x264_quant_4x4_neon 97 vld1.64 {d28-d31}, [r0,:128] 98 vabs.s16 q8, q14 99 vabs.s16 q9, q15 100 vld1.64 {d0-d3}, [r2,:128] 101 vld1.64 {d4-d7}, [r1,:128] 102 QUANT_TWO q0, q1, d4, d5, d6, d7, q0 103 vorr d0, d0, d1 104 QUANT_END d0 105endfunc 106 107// quant_4x4x4( int16_t dct[4][16], uint16_t mf[16], uint16_t bias[16] ) 108function x264_quant_4x4x4_neon 109 vpush {d8-d15} 110 vld1.64 {d28-d31}, [r0,:128] 111 vabs.s16 q8, q14 112 vabs.s16 q9, q15 113 vld1.64 {d0-d3}, [r2,:128] 114 vld1.64 {d4-d7}, [r1,:128] 115 QUANT_TWO q0, q1, d4, d5, d6, d7, q4 116 vld1.64 {d28-d31}, [r0,:128] 117 vabs.s16 q8, q14 118 vabs.s16 q9, q15 119 QUANT_TWO q0, q1, d4, d5, d6, d7, q5 120 vld1.64 {d28-d31}, [r0,:128] 121 vabs.s16 q8, q14 122 vabs.s16 q9, q15 123 QUANT_TWO q0, q1, d4, d5, d6, d7, q6 124 vld1.64 {d28-d31}, [r0,:128] 125 vabs.s16 q8, q14 126 vabs.s16 q9, q15 127 QUANT_TWO q0, q1, d4, d5, d6, d7, q7 128 vorr d8, d8, d9 129 vorr d10, d10, d11 130 vorr d12, d12, d13 131 vorr d14, d14, d15 132 vmov r0, r1, d8 133 vmov r2, r3, d10 134 orrs r0, r1 135 movne r0, #1 136 orrs r2, r3 137 orrne r0, #2 138 vmov r1, r2, d12 139 vmov r3, ip, d14 140 orrs r1, r2 141 orrne r0, #4 142 orrs r3, ip 143 orrne r0, #8 144 vpop {d8-d15} 145 bx lr 146endfunc 147 148// quant_8x8( int16_t dct[64], uint16_t mf[64], uint16_t bias[64] ) 149function x264_quant_8x8_neon 150 vld1.64 {d28-d31}, [r0,:128] 151 vabs.s16 q8, q14 152 vabs.s16 q9, q15 153 vld1.64 {d0-d3}, [r2,:128]! 154 vld1.64 {d4-d7}, [r1,:128]! 155 QUANT_TWO q0, q1, d4, d5, d6, d7, q0 156.rept 3 157 vld1.64 {d28-d31}, [r0,:128] 158 vabs.s16 q8, q14 159 vabs.s16 q9, q15 160 vld1.64 {d2-d5}, [r2,:128]! 161 QUANT_TWO q1, q2, d4, d5, d6, d7, q1, yes 162 vorr q0, q0, q1 163.endr 164 vorr d0, d0, d1 165 QUANT_END d0 166endfunc 167 168.macro DEQUANT_START mf_size offset dc=no 169 mov r3, #0x2b 170 mul r3, r3, r2 171 lsr r3, r3, #8 // i_qbits = i_qp / 6 172 add ip, r3, r3, lsl #1 173 sub r2, r2, ip, lsl #1 // i_mf = i_qp % 6 174.ifc \dc,no 175 add r1, r1, r2, lsl #\mf_size // dequant_mf[i_mf] 176.else 177 ldr r1, [r1, r2, lsl #\mf_size] // dequant_mf[i_mf][0][0] 178.endif 179 subs r3, r3, #\offset // 6 for 8x8 180.endm 181 182// dequant_4x4( int16_t dct[16], int dequant_mf[6][16], int i_qp ) 183.macro DEQUANT size bits 184function x264_dequant_\size\()_neon 185 DEQUANT_START \bits+2, \bits 186.ifc \size, 8x8 187 mov r2, #4 188.endif 189 blt dequant_\size\()_rshift 190 191 vdup.16 q15, r3 192dequant_\size\()_lshift_loop: 193.ifc \size, 8x8 194 subs r2, r2, #1 195.endif 196 vld1.32 {d16-d17}, [r1,:128]! 197 vld1.32 {d18-d19}, [r1,:128]! 198 vmovn.s32 d4, q8 199 vld1.32 {d20-d21}, [r1,:128]! 200 vmovn.s32 d5, q9 201 vld1.32 {d22-d23}, [r1,:128]! 202 vmovn.s32 d6, q10 203 vld1.16 {d0-d3}, [r0,:128] 204 vmovn.s32 d7, q11 205 vmul.s16 q0, q0, q2 206 vmul.s16 q1, q1, q3 207 vshl.s16 q0, q0, q15 208 vshl.s16 q1, q1, q15 209 vst1.16 {d0-d3}, [r0,:128]! 210.ifc \size, 8x8 211 bgt dequant_\size\()_lshift_loop 212.endif 213 bx lr 214 215dequant_\size\()_rshift: 216 vdup.32 q15, r3 217 rsb r3, r3, #0 218 mov ip, #1 219 sub r3, r3, #1 220 lsl ip, ip, r3 221 222.ifc \size, 8x8 223dequant_\size\()_rshift_loop: 224 subs r2, r2, #1 225.endif 226 vdup.32 q10, ip 227 vld1.32 {d16-d17}, [r1,:128]! 228 vdup.32 q11, ip 229 vld1.32 {d18-d19}, [r1,:128]! 230 vmovn.s32 d4, q8 231 vld1.32 {d16-d17}, [r1,:128]! 232 vmovn.s32 d5, q9 233 vld1.32 {d18-d19}, [r1,:128]! 234 vmovn.s32 d6, q8 235 vld1.16 {d0-d3}, [r0,:128] 236 vmovn.s32 d7, q9 237 vdup.32 q12, ip 238 vdup.32 q13, ip 239 240 vmlal.s16 q10, d0, d4 241 vmlal.s16 q11, d1, d5 242 vmlal.s16 q12, d2, d6 243 vmlal.s16 q13, d3, d7 244 vshl.s32 q10, q10, q15 245 vshl.s32 q11, q11, q15 246 vshl.s32 q12, q12, q15 247 vshl.s32 q13, q13, q15 248 249 vmovn.s32 d0, q10 250 vmovn.s32 d1, q11 251 vmovn.s32 d2, q12 252 vmovn.s32 d3, q13 253 vst1.16 {d0-d3}, [r0,:128]! 254.ifc \size, 8x8 255 bgt dequant_\size\()_rshift_loop 256.endif 257 bx lr 258endfunc 259.endm 260 261DEQUANT 4x4, 4 262DEQUANT 8x8, 6 263 264// dequant_4x4_dc( int16_t dct[16], int dequant_mf[6][16], int i_qp ) 265function x264_dequant_4x4_dc_neon 266 DEQUANT_START 6, 6, yes 267 blt dequant_4x4_dc_rshift 268 269 lsl r1, r1, r3 270 vdup.16 q2, r1 271 vld1.16 {d0-d3}, [r0,:128] 272 vdup.16 q15, r3 273 274 vmul.s16 q0, q0, q2 275 vmul.s16 q1, q1, q2 276 vst1.16 {d0-d3}, [r0,:128] 277 bx lr 278 279dequant_4x4_dc_rshift: 280 vdup.16 d4, r1 281 vdup.32 q15, r3 282 rsb r3, r3, #0 283 mov ip, #1 284 sub r3, r3, #1 285 lsl ip, ip, r3 286 287 vdup.32 q10, ip 288 vdup.32 q11, ip 289 vld1.16 {d0-d3}, [r0,:128] 290 vdup.32 q12, ip 291 vdup.32 q13, ip 292 293 vmlal.s16 q10, d0, d4 294 vmlal.s16 q11, d1, d4 295 vmlal.s16 q12, d2, d4 296 vmlal.s16 q13, d3, d4 297 vshl.s32 q10, q10, q15 298 vshl.s32 q11, q11, q15 299 vshl.s32 q12, q12, q15 300 vshl.s32 q13, q13, q15 301 302 vmovn.s32 d0, q10 303 vmovn.s32 d1, q11 304 vmovn.s32 d2, q12 305 vmovn.s32 d3, q13 306 vst1.16 {d0-d3}, [r0,:128] 307 bx lr 308endfunc 309 310 311// int coeff_last( int16_t *l ) 312function x264_coeff_last4_arm 313 ldrd r2, r3, [r0] 314 subs r0, r3, #0 315 movne r0, #2 316 movne r2, r3 317 lsrs r2, r2, #16 318 addne r0, r0, #1 319 bx lr 320endfunc 321 322function x264_coeff_last8_arm 323 ldrd r2, r3, [r0, #8] 324 orrs ip, r2, r3 325 movne r0, #4 326 ldrdeq r2, r3, [r0] 327 moveq r0, #0 328 tst r3, r3 329 addne r0, #2 330 movne r2, r3 331 lsrs r2, r2, #16 332 addne r0, r0, #1 333 bx lr 334endfunc 335 336.macro COEFF_LAST_1x size 337function x264_coeff_last\size\()_neon 338.if \size == 15 339 sub r0, r0, #2 340 vld1.64 {d0-d3}, [r0] 341.else 342 vld1.64 {d0-d3}, [r0,:128] 343.endif 344 vtst.16 q0, q0 345 vtst.16 q1, q1 346 vshrn.u16 d0, q0, #8 347 vshrn.u16 d1, q1, #8 348 vshrn.u16 d0, q0, #4 349 vclz.i32 d0, d0 350 mov ip, #7 351 mov r3, #\size - 9 352 vmov r0, r1, d0 353 354 subs r1, ip, r1, lsr #2 355 addge r0, r1, #\size - 8 356 subslt r0, r3, r0, lsr #2 357 movlt r0, #0 358 bx lr 359endfunc 360.endm 361 362COEFF_LAST_1x 15 363COEFF_LAST_1x 16 364 365function x264_coeff_last64_neon 366 vld1.64 {d16-d19}, [r0,:128]! 367 vqmovn.u16 d16, q8 368 vqmovn.u16 d17, q9 369 vld1.64 {d20-d23}, [r0,:128]! 370 vqmovn.u16 d18, q10 371 vqmovn.u16 d19, q11 372 vld1.64 {d24-d27}, [r0,:128]! 373 vqmovn.u16 d20, q12 374 vqmovn.u16 d21, q13 375 vld1.64 {d28-d31}, [r0,:128]! 376 vqmovn.u16 d22, q14 377 vqmovn.u16 d23, q15 378 379 movrel r1, pmovmskb_byte 380 vld1.64 {d0-d1}, [r1,:128] 381 382 vtst.8 q8, q8 383 vtst.8 q9, q9 384 vtst.8 q10, q10 385 vtst.8 q11, q11 386 387 vand q8, q8, q0 388 vand q9, q9, q0 389 vand q10, q10, q0 390 vand q11, q11, q0 391 392 vpadd.u8 d0, d16, d17 393 vpadd.u8 d1, d18, d19 394 vpadd.u8 d2, d20, d21 395 vpadd.u8 d3, d22, d23 396 vpadd.u8 d0, d0, d1 397 vpadd.u8 d1, d2, d3 398 vpadd.u8 d0, d0, d1 399 vclz.i32 d0, d0 400 mov ip, #31 401 vmov r0, r1, d0 402 403 subs r1, ip, r1 404 addge r0, r1, #32 405 subslt r0, ip, r0 406 movlt r0, #0 407 bx lr 408endfunc 409