udivmodqi4.S 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. //===------------ udivmodqi4.S - uint8 div & mod --------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // As described at
  10. // https://gcc.gnu.org/wiki/avr-gcc#Exceptions_to_the_Calling_Convention, the
  11. // prototype is `struct {uint8, uint8} __udivmodqi4(uint8, uint8)`.
  12. // The uint8 quotient is returned via R24, and the uint8 remainder is returned
  13. // via R25, while R23 is clobbered.
  14. //
  15. //===----------------------------------------------------------------------===//
  16. .text
  17. .align 2
  18. .globl __udivmodqi4
  19. .type __udivmodqi4, @function
  20. __udivmodqi4:
  21. sub r25, r25 ; Initialize the remainder to zero.
  22. ldi r23, 9 ; Only loop 8 rounds for uint8.
  23. __udivmodqi4_loop:
  24. adc r24, r24
  25. dec r23
  26. breq __udivmodqi4_end
  27. adc r25, r25
  28. cp r25, r22 ; Compare with the divisor.
  29. brcs __udivmodqi4_loop
  30. sub r25, r22 ; Subtract the divisor.
  31. rjmp __udivmodqi4_loop
  32. __udivmodqi4_end:
  33. com r24 ; The uint8 quotient is returned via R24.
  34. ret ; The uint8 remainder is returned via R25.