idct32x32_1_add_neon.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Copyright (c) 2014 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. #include <arm_neon.h>
  11. #include "./vpx_config.h"
  12. #include "vpx_dsp/inv_txfm.h"
  13. #include "vpx_ports/mem.h"
  14. static INLINE void LD_16x8(
  15. uint8_t *d,
  16. int d_stride,
  17. uint8x16_t *q8u8,
  18. uint8x16_t *q9u8,
  19. uint8x16_t *q10u8,
  20. uint8x16_t *q11u8,
  21. uint8x16_t *q12u8,
  22. uint8x16_t *q13u8,
  23. uint8x16_t *q14u8,
  24. uint8x16_t *q15u8) {
  25. *q8u8 = vld1q_u8(d);
  26. d += d_stride;
  27. *q9u8 = vld1q_u8(d);
  28. d += d_stride;
  29. *q10u8 = vld1q_u8(d);
  30. d += d_stride;
  31. *q11u8 = vld1q_u8(d);
  32. d += d_stride;
  33. *q12u8 = vld1q_u8(d);
  34. d += d_stride;
  35. *q13u8 = vld1q_u8(d);
  36. d += d_stride;
  37. *q14u8 = vld1q_u8(d);
  38. d += d_stride;
  39. *q15u8 = vld1q_u8(d);
  40. return;
  41. }
  42. static INLINE void ADD_DIFF_16x8(
  43. uint8x16_t qdiffu8,
  44. uint8x16_t *q8u8,
  45. uint8x16_t *q9u8,
  46. uint8x16_t *q10u8,
  47. uint8x16_t *q11u8,
  48. uint8x16_t *q12u8,
  49. uint8x16_t *q13u8,
  50. uint8x16_t *q14u8,
  51. uint8x16_t *q15u8) {
  52. *q8u8 = vqaddq_u8(*q8u8, qdiffu8);
  53. *q9u8 = vqaddq_u8(*q9u8, qdiffu8);
  54. *q10u8 = vqaddq_u8(*q10u8, qdiffu8);
  55. *q11u8 = vqaddq_u8(*q11u8, qdiffu8);
  56. *q12u8 = vqaddq_u8(*q12u8, qdiffu8);
  57. *q13u8 = vqaddq_u8(*q13u8, qdiffu8);
  58. *q14u8 = vqaddq_u8(*q14u8, qdiffu8);
  59. *q15u8 = vqaddq_u8(*q15u8, qdiffu8);
  60. return;
  61. }
  62. static INLINE void SUB_DIFF_16x8(
  63. uint8x16_t qdiffu8,
  64. uint8x16_t *q8u8,
  65. uint8x16_t *q9u8,
  66. uint8x16_t *q10u8,
  67. uint8x16_t *q11u8,
  68. uint8x16_t *q12u8,
  69. uint8x16_t *q13u8,
  70. uint8x16_t *q14u8,
  71. uint8x16_t *q15u8) {
  72. *q8u8 = vqsubq_u8(*q8u8, qdiffu8);
  73. *q9u8 = vqsubq_u8(*q9u8, qdiffu8);
  74. *q10u8 = vqsubq_u8(*q10u8, qdiffu8);
  75. *q11u8 = vqsubq_u8(*q11u8, qdiffu8);
  76. *q12u8 = vqsubq_u8(*q12u8, qdiffu8);
  77. *q13u8 = vqsubq_u8(*q13u8, qdiffu8);
  78. *q14u8 = vqsubq_u8(*q14u8, qdiffu8);
  79. *q15u8 = vqsubq_u8(*q15u8, qdiffu8);
  80. return;
  81. }
  82. static INLINE void ST_16x8(
  83. uint8_t *d,
  84. int d_stride,
  85. uint8x16_t *q8u8,
  86. uint8x16_t *q9u8,
  87. uint8x16_t *q10u8,
  88. uint8x16_t *q11u8,
  89. uint8x16_t *q12u8,
  90. uint8x16_t *q13u8,
  91. uint8x16_t *q14u8,
  92. uint8x16_t *q15u8) {
  93. vst1q_u8(d, *q8u8);
  94. d += d_stride;
  95. vst1q_u8(d, *q9u8);
  96. d += d_stride;
  97. vst1q_u8(d, *q10u8);
  98. d += d_stride;
  99. vst1q_u8(d, *q11u8);
  100. d += d_stride;
  101. vst1q_u8(d, *q12u8);
  102. d += d_stride;
  103. vst1q_u8(d, *q13u8);
  104. d += d_stride;
  105. vst1q_u8(d, *q14u8);
  106. d += d_stride;
  107. vst1q_u8(d, *q15u8);
  108. return;
  109. }
  110. void vpx_idct32x32_1_add_neon(
  111. int16_t *input,
  112. uint8_t *dest,
  113. int dest_stride) {
  114. uint8x16_t q0u8, q8u8, q9u8, q10u8, q11u8, q12u8, q13u8, q14u8, q15u8;
  115. int i, j, dest_stride8;
  116. uint8_t *d;
  117. int16_t a1, cospi_16_64 = 11585;
  118. int16_t out = dct_const_round_shift(input[0] * cospi_16_64);
  119. out = dct_const_round_shift(out * cospi_16_64);
  120. a1 = ROUND_POWER_OF_TWO(out, 6);
  121. dest_stride8 = dest_stride * 8;
  122. if (a1 >= 0) { // diff_positive_32_32
  123. a1 = a1 < 0 ? 0 : a1 > 255 ? 255 : a1;
  124. q0u8 = vdupq_n_u8(a1);
  125. for (i = 0; i < 2; i++, dest += 16) { // diff_positive_32_32_loop
  126. d = dest;
  127. for (j = 0; j < 4; j++) {
  128. LD_16x8(d, dest_stride, &q8u8, &q9u8, &q10u8, &q11u8,
  129. &q12u8, &q13u8, &q14u8, &q15u8);
  130. ADD_DIFF_16x8(q0u8, &q8u8, &q9u8, &q10u8, &q11u8,
  131. &q12u8, &q13u8, &q14u8, &q15u8);
  132. ST_16x8(d, dest_stride, &q8u8, &q9u8, &q10u8, &q11u8,
  133. &q12u8, &q13u8, &q14u8, &q15u8);
  134. d += dest_stride8;
  135. }
  136. }
  137. } else { // diff_negative_32_32
  138. a1 = -a1;
  139. a1 = a1 < 0 ? 0 : a1 > 255 ? 255 : a1;
  140. q0u8 = vdupq_n_u8(a1);
  141. for (i = 0; i < 2; i++, dest += 16) { // diff_negative_32_32_loop
  142. d = dest;
  143. for (j = 0; j < 4; j++) {
  144. LD_16x8(d, dest_stride, &q8u8, &q9u8, &q10u8, &q11u8,
  145. &q12u8, &q13u8, &q14u8, &q15u8);
  146. SUB_DIFF_16x8(q0u8, &q8u8, &q9u8, &q10u8, &q11u8,
  147. &q12u8, &q13u8, &q14u8, &q15u8);
  148. ST_16x8(d, dest_stride, &q8u8, &q9u8, &q10u8, &q11u8,
  149. &q12u8, &q13u8, &q14u8, &q15u8);
  150. d += dest_stride8;
  151. }
  152. }
  153. }
  154. return;
  155. }