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.

ConvDwInt8PostAlign4PerChannel.S 3.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #ifdef __arm__
  2. #ifndef __aarch64__
  3. .text
  4. .align 5
  5. .global ConvDwInt8PostAlign4PerChannel
  6. #ifndef __APPLE__
  7. .type ConvDwInt8PostAlign4PerChannel, %function
  8. #endif
  9. // void ConvDwInt8PostAlign4PerChannel(int8_t *dst, int32_t *buffer, int channel4, 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. ConvDwInt8PostAlign4PerChannel:
  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. ldr r5, [sp, #4] // left_shift
  25. ldr r6, [sp, #8] // right_shift
  26. ldr r7, [sp, #12] // acc_min
  27. vdup.32 q11, r7
  28. ldr r8, [sp, #16] // acc_max
  29. vdup.32 q10, r8
  30. mov r10, r0
  31. LoopDepth8:
  32. cmp r2, #8
  33. blt End
  34. vld1.32 {q0}, [r1]!
  35. vld1.32 {q13}, [r5]!
  36. vshl.s32 q0, q0, q13
  37. vld1.32 {q14}, [r4]!
  38. vqrdmulh.s32 q0, q0, q14
  39. vld1.32 {q12}, [r6]!
  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. vld1.32 {q13}, [r5]!
  50. vshl.s32 q1, q1, q13
  51. vld1.32 {q14}, [r4]!
  52. vqrdmulh.s32 q1, q1, q14
  53. vld1.32 {q12}, [r6]!
  54. vand q4, q1, q12
  55. vshr.s32 q4, q4, #31
  56. vqadd.s32 q1, q1, q4
  57. vrshl.s32 q1, q1, q12
  58. vadd.i32 q1, q1, q15
  59. vmax.s32 q1, q1, q11
  60. vmin.s32 q1, q1, q10
  61. vqmovn.s32 d5, q1
  62. vqmovn.s16 d4, q2
  63. vst1.8 {d4}, [r10]!
  64. sub r2, r2, #8
  65. b LoopDepth8
  66. LoopDepth4:
  67. cmp r2, #4
  68. blt End
  69. vld1.32 {q0}, [r1]!
  70. vld1.32 {q13}, [r5]!
  71. vshl.s32 q0, q0, q13
  72. vld1.32 {q14}, [r4]!
  73. vqrdmulh.s32 q0, q0, q14
  74. vld1.32 {q12}, [r6]!
  75. vand q4, q0, q12
  76. vshr.s32 q4, q4, #31
  77. vqadd.s32 q0, q0, q4
  78. vrshl.s32 q0, q0, q12
  79. vadd.i32 q0, q0, q15
  80. vmax.s32 q0, q0, q11
  81. vmin.s32 q0, q0, q10
  82. vqmovn.s32 d0, q0
  83. vqmovn.s16 d0, q0
  84. vst1.8 {d0[0]}, [r10]!
  85. vst1.8 {d0[1]}, [r10]!
  86. vst1.8 {d0[2]}, [r10]!
  87. vst1.8 {d0[3]}, [r10]!
  88. sub r2, r2, #4
  89. b LoopDepth4
  90. End:
  91. sub sp, sp, #88
  92. vpop {q4-q7}
  93. pop {r4-r8, r10}
  94. bx lr
  95. #endif
  96. #endif