1//===------------ udivmodhi4.S - uint16 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 {uint16, uint16} __udivmodhi4(uint16, uint16)`.
12// The uint16 quotient is returned via R23:R22, and the uint16 remainder is
13// returned via R25:R24, while R21/R26/R27 are clobbered.
14//
15//===----------------------------------------------------------------------===//
16
17 .text
18 .align 2
19
20 .globl __udivmodhi4
21 .type __udivmodhi4, @function
22
23__udivmodhi4:
24 sub r26, r26
25 sub r27, r27 ; Initialize the remainder to zero.
26 ldi r21, 17 ; Only loop 16 rounds for uint16.
27
28__udivmodhi4_loop:
29 adc r24, r24
30 adc r25, r25
31 dec r21
32 breq __udivmodhi4_end
33 adc r26, r26
34 adc r27, r27
35 cp r26, r22
36 cpc r27, r23 ; Compare with the divisor.
37 brcs __udivmodhi4_loop
38 sub r26, r22
39 sbc r27, r23 ; Subtract the divisor.
40 rjmp __udivmodhi4_loop
41
42__udivmodhi4_end:
43 com r24
44 com r25
45 mov r22, r24
46 mov r23, r25 ; The quotient is returned in R23:R22.
47 mov r24, r26
48 mov r25, r27 ; The remainder is returned in in R25:R24.
49 ret
50

source code of compiler-rt/lib/builtins/avr/udivmodhi4.S