Guest User

Untitled

a guest
Dec 9th, 2018
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.95 KB | None | 0 0
  1. .macro BEGIN_FUNCTION
  2. .align 2 // Align the function code to a 4-byte (2^n) word boundary.
  3. .arm // Use ARM instructions instead of Thumb.
  4. .globl _$0 // Make the function globally accessible.
  5. .no_dead_strip _$0 // Stop the optimizer from ignoring this function!
  6. .private_extern _$0
  7. _$0: // Declare the function.
  8. .endmacro
  9.  
  10. .macro END_FUNCTION
  11. bx lr // Jump back to the caller.
  12. .endmacro
  13.  
  14.  
  15. BEGIN_FUNCTION asm_rgb_to_hsv
  16. //args:
  17. // r0 - image data in format "rgbrgb"
  18. // r1 - output in format "hsvhsv"
  19. // r2 - image size in pixels
  20.  
  21. // Function prolog that saves all important registers.
  22. push {r4, r5, r6, r7, lr} // Save registers r4-r6 if used and Frame Pointer (r7) and Link Register (r14).
  23. add r7, sp, #12 // Adjust FP to point to the saved FP (r7).
  24. push {r8, r10, r11, r14} // Save any general registers that should be preserved.
  25.  
  26. // If NEON instructions aren't available, don't execute anything.
  27. #if defined __ARM_NEON__
  28.  
  29. lsr r2, r2, #1 // divide size by 2 - we operate on two pixels at the same time
  30.  
  31. vmov.f32 d0, #1.0 // load 1 into two registers
  32.  
  33. vmov.f32 d1, #1.0e-15
  34.  
  35. vmov.f32 d10, #0.0
  36. vmov.f32 d7, #0.0 // v = 0
  37. vmov.f32 d6, #0.0 // s = 0
  38. vmov.f32 d5, #0.0 // h = 0
  39.  
  40. vmov.f32 d11, #2.0 // later add 2 to h
  41.  
  42. vmov.f32 d20, #6.0
  43. .loop_rh:
  44. vld3.32 {d2, d3, d4}, [r0]!
  45.  
  46. vmax.f32 d2, d2, d1 // dX > 1 => dX = 1
  47. vmin.f32 d2, d2, d0 // dX < 1e-15 => dX = 1e-15
  48.  
  49. vmax.f32 d3, d3, d1
  50. vmin.f32 d3, d3, d0
  51.  
  52. vmax.f32 d4, d4, d1
  53. vmin.f32 d4, d4, d1
  54.  
  55. vmax.f32 d7, d2, d3 // v = max(r,g,b)
  56. vmax.f32 d7, d7, d4
  57.  
  58. vmin.f32 d8, d2, d3 // m = min(r,g,b)
  59. vmin.f32 d8, d8, d4
  60. vsub.f32 d8, d7, d8 // gap = v - m
  61. vceq.f32 d9, d8, d10 // d10 = gap == 0
  62.  
  63. vand.f32 d12, d11, d9 // if v = m => v += 2
  64. vadd.f32 d7, d7, d12
  65.  
  66. vand.f32 d0, d0, d9 // set gap to 1 where sat = 0
  67. vorr.f32 d8, d8, d0
  68. vrecpe.f32 d13, d8 // gap_inv = 1.0 / gap
  69.  
  70. // if r == v
  71. vceq.f32 d14, d2, d7
  72.  
  73. vsub.f32 d15, d3, d4 // h = (g - b) / gap
  74. vmul.f32 d15, d13, d15
  75.  
  76. // fill h
  77. vand.f32 d16, d11, d14
  78. vadd.f32 d7, d7, d16
  79. vbit.f32 d5, d15, d14
  80.  
  81. // if g == v
  82. vceq.f32 d14, d3, d7
  83. vsub.f32 d15, d4, d2
  84. vmul.f32 d15, d15, d13
  85. vadd.f32 d15, d15, d11
  86.  
  87. vand.f32 d16, d11, d14
  88. vadd.f32 d7, d7, d16
  89. vbit.f32 d5, d15, d14
  90.  
  91. // if b == v
  92. vadd.f32 d17, d11, d11
  93. vceq.f32 d14, d4, d7
  94. vsub.f32 d16, d2, d3
  95. vmul.f32 d16, d16, d13
  96. vadd.f32 d15, d17, d16
  97.  
  98. vand.f32 d16, d11, d14
  99. vadd.f32 d7, d7, d16
  100. vbit.f32 d5, d15, d14
  101.  
  102. // fill s if gap > 0
  103. vsub.f32 d5, d5, d11
  104. vrecpe.f32 d16, d5
  105. vmul.f32 d15, d8, d16
  106. vorn d6, d9, d15
  107.  
  108. // check if h < 0
  109. vclt.f32 d14, d5, d10
  110. vand.f32 d16, d14, d20
  111. vadd.f32 d5, d5, d16
  112.  
  113. vst3.32 {d5, d6, d7}, [r1]!
  114.  
  115. subs r2, r2, #1 // decrease loop counter
  116. bne .loop_rh
  117. #endif //defined __ARM_NEON__
  118.  
  119. // Function epilog that restores all important registers.
  120. pop {r8, r10, r11, r14} // Restore any general registers that were saved.
  121. pop {r4, r5, r6, r7, pc} // Restore saved registers, the saved FP (r7), and return to the caller (saved LR as PC).
  122. END_FUNCTION
Add Comment
Please, Sign In to add comment