fixed_asm.S 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. /* libs/opengles/fixed_asm.S
  2. **
  3. ** Copyright 2006, The Android Open Source Project
  4. **
  5. ** Licensed under the Apache License, Version 2.0 (the "License");
  6. ** you may not use this file except in compliance with the License.
  7. ** You may obtain a copy of the License at
  8. **
  9. ** http://www.apache.org/licenses/LICENSE-2.0
  10. **
  11. ** Unless required by applicable law or agreed to in writing, software
  12. ** distributed under the License is distributed on an "AS IS" BASIS,
  13. ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. ** See the License for the specific language governing permissions and
  15. ** limitations under the License.
  16. */
  17. .text
  18. .align 2
  19. .global gglFloatToFixed
  20. .type gglFloatToFixed, %function
  21. .global gglFloatToFixedFast
  22. .type gglFloatToFixedFast, %function
  23. /*
  24. * Converts a float to a s15.16 fixed-point number.
  25. * this doesn't handle floats out of the [-32768, +32768[ range
  26. * and doesn't performs round-to-nearest.
  27. * however, it's very fast :-)
  28. */
  29. gglFloatToFixedFast:
  30. movs r1, r0, lsl #1 /* remove bit sign */
  31. mov r2, #0x8E /* 127 + 15 */
  32. sub r1, r2, r1, lsr #24 /* compute shift */
  33. mov r2, r0, lsl #8 /* mantissa<<8 */
  34. orr r2, r2, #0x80000000 /* add the missing 1 */
  35. mov r0, r2, lsr r1 /* scale to 16.16 */
  36. rsbcs r0, r0, #0 /* negate if needed */
  37. bx lr
  38. /*
  39. * this version rounds-to-nearest and saturates numbers
  40. * outside the range (but not NaNs).
  41. */
  42. gglFloatToFixed:
  43. mov r1, r0, lsl #1 /* remove bit sign */
  44. mov r2, #0x8E /* 127 + 15 */
  45. subs r1, r2, r1, lsr #24 /* compute shift */
  46. bls 0f /* too big */
  47. mov r2, r0, lsl #8 /* mantissa<<8 */
  48. orr r2, r2, #0x80000000 /* add the missing 1 */
  49. mov r3, r0
  50. movs r0, r2, lsr r1 /* scale to 16.16 */
  51. addcs r0, r0, #1 /* round-to-nearest */
  52. tst r3, #0x80000000 /* negative? */
  53. rsbne r0, r0, #0 /* negate if needed */
  54. bx lr
  55. 0: ands r0, r0, #0x80000000 /* keep only the sign bit */
  56. moveq r0, #0x7fffffff /* positive, maximum value */
  57. bx lr