You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

ConvDwInt8PostAlign4.S 2.8 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #ifdef __arm__
  2. #ifndef __aarch64__
  3. .text
  4. .align 5
  5. .global ConvDwInt8PostAlign4
  6. #ifndef __APPLE__
  7. .type ConvDwInt8PostAlign4, %function
  8. #endif
  9. // void ConvDwInt8PostAlign4(int8_t *dst, int32_t *buffer, int num_pixels, int32_t output_zp, int32_t out_multiplier,
  10. // int32_t left_shift, int32_t right_shift, int32_t acc_min, int32_t acc_max);
  11. // r0: dst, r1: buffer, r2: num_pixels, r3: output_zp, r4: out_multiplier,
  12. // r5: left_shift, r6: right_shift, r7: acc_min, r8: acc_max
  13. ConvDwInt8PostAlign4:
  14. // at return, clang generates "push {lr}, pop {pc}"" while gcc will generate "bx lr"
  15. // according to https://stackoverflow.com/questions/53625807
  16. // even if we jump to link register instead of saving it, we still have to save it in subroutine calls anyway
  17. // clang's rule seems more simple, though there are no subroutine calls here
  18. // r4-r8 and q4-q7 must be saved according to https://static.docs.arm.com/ihi0042/i/aapcs32.pdf
  19. push {r4-r8, r10}
  20. vpush {q4-q7}
  21. add sp, sp, #88
  22. vdup.32 q15, r3 // output_zp
  23. ldr r4, [sp] // out_multiplier
  24. vdup.32 q14, r4
  25. ldr r5, [sp, #4] // left_shift
  26. vdup.32 q13, r5
  27. ldr r6, [sp, #8] // right_shift
  28. vdup.32 q12, r6
  29. ldr r7, [sp, #12] // acc_min
  30. vdup.32 q11, r7
  31. ldr r8, [sp, #16] // acc_max
  32. vdup.32 q10, r8
  33. mov r10, r0
  34. LoopDepth8:
  35. cmp r2, #8
  36. blt End
  37. vld1.32 {q0}, [r1]!
  38. vshl.s32 q0, q0, q13
  39. vqrdmulh.s32 q0, q0, q14
  40. vand q4, q0, q12
  41. vshr.s32 q4, q4, #31
  42. vqadd.s32 q0, q0, q4
  43. vrshl.s32 q0, q0, q12
  44. vadd.i32 q0, q0, q15
  45. vmax.s32 q0, q0, q11
  46. vmin.s32 q0, q0, q10
  47. vqmovn.s32 d4, q0
  48. vld1.32 {q1}, [r1]!
  49. vshl.s32 q1, q1, q13
  50. vqrdmulh.s32 q1, q1, q14
  51. vand q4, q1, q12
  52. vshr.s32 q4, q4, #31
  53. vqadd.s32 q1, q1, q4
  54. vrshl.s32 q1, q1, q12
  55. vadd.i32 q1, q1, q15
  56. vmax.s32 q1, q1, q11
  57. vmin.s32 q1, q1, q10
  58. vqmovn.s32 d5, q1
  59. vqmovn.s16 d4, q2
  60. vst1.8 {d4}, [r10]!
  61. sub r2, r2, #8
  62. b LoopDepth8
  63. LoopDepth4:
  64. cmp r2, #4
  65. blt End
  66. vld1.32 {q0}, [r1]!
  67. vshl.s32 q0, q0, q13
  68. vqrdmulh.s32 q0, q0, q14
  69. vand q4, q0, q12
  70. vshr.s32 q4, q4, #31
  71. vqadd.s32 q0, q0, q4
  72. vrshl.s32 q0, q0, q12
  73. vadd.i32 q0, q0, q15
  74. vmax.s32 q0, q0, q11
  75. vmin.s32 q0, q0, q10
  76. vqmovn.s32 d0, q0
  77. vqmovn.s16 d0, q0
  78. vst1.8 {d0[0]}, [r10]!
  79. vst1.8 {d0[1]}, [r10]!
  80. vst1.8 {d0[2]}, [r10]!
  81. vst1.8 {d0[3]}, [r10]!
  82. sub r2, r2, #4
  83. b LoopDepth4
  84. End:
  85. sub sp, sp, #88
  86. vpop {q4-q7}
  87. pop {r4-r8, r10}
  88. bx lr
  89. #endif
  90. #endif