xref: /freebsd/contrib/llvm-project/compiler-rt/lib/builtins/avr/divmodhi4.S (revision 9f23cbd6cae82fd77edfad7173432fa8dccd0a95)
1//===------------- divmodhi4.S - sint16 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 {sint16, sint16}  __divmodhi4(sint16, sint16)`.
12// The sint16 quotient is returned via R23:R22, and the sint16 remainder is
13// returned via R25:R24, while registers R21/R26/27/Rtmp and bit T in SREG
14// are clobbered.
15//
16//===----------------------------------------------------------------------===//
17
18	.text
19	.align 2
20
21#ifdef __AVR_TINY__
22	.set __tmp_reg__, 16
23#else
24	.set __tmp_reg__, 0
25#endif
26
27	.globl __divmodhi4
28	.type  __divmodhi4, @function
29
30__divmodhi4:
31	bst     r25, 7
32	mov     __tmp_reg__, r23
33	brtc    __divmodhi4_a
34	com     __tmp_reg__
35	rcall   __divmodhi4_b
36
37__divmodhi4_a:
38	sbrc    r23, 7
39	rcall   __divmodhi4_c
40	rcall   __udivmodhi4 ; Call __udivmodhi4 to do real calculation.
41	sbrc    __tmp_reg__, 7
42	rcall   __divmodhi4_c
43	brtc    __divmodhi4_exit
44
45__divmodhi4_b:
46	com     r25
47	neg     r24
48	sbci    r25, 255
49	ret                  ; Return quotient via R23:R22 and remainder via R25:R24.
50
51__divmodhi4_c:
52	com     r23
53	neg     r22
54	sbci    r23, 255
55
56__divmodhi4_exit:
57	ret                  ; Return quotient via R23:R22 and remainder via R25:r24.
58