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