xref: /openbsd-src/gnu/llvm/compiler-rt/lib/builtins/avr/divmodhi4.S (revision 810390e339a5425391477d5d41c78d7cab2424ac)
1*810390e3Srobert//===------------- divmodhi4.S - sint16 div & mod -------------------------===//
2*810390e3Srobert//
3*810390e3Srobert// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*810390e3Srobert// See https://llvm.org/LICENSE.txt for license information.
5*810390e3Srobert// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*810390e3Srobert//
7*810390e3Srobert//===----------------------------------------------------------------------===//
8*810390e3Srobert//
9*810390e3Srobert// As described at
10*810390e3Srobert// https://gcc.gnu.org/wiki/avr-gcc#Exceptions_to_the_Calling_Convention, the
11*810390e3Srobert// prototype is `struct {sint16, sint16}  __divmodhi4(sint16, sint16)`.
12*810390e3Srobert// The sint16 quotient is returned via R23:R22, and the sint16 remainder is
13*810390e3Srobert// returned via R25:R24, while registers R21/R26/27/Rtmp and bit T in SREG
14*810390e3Srobert// are clobbered.
15*810390e3Srobert//
16*810390e3Srobert//===----------------------------------------------------------------------===//
17*810390e3Srobert
18*810390e3Srobert	.text
19*810390e3Srobert	.align 2
20*810390e3Srobert
21*810390e3Srobert#ifdef __AVR_TINY__
22*810390e3Srobert	.set __tmp_reg__, 16
23*810390e3Srobert#else
24*810390e3Srobert	.set __tmp_reg__, 0
25*810390e3Srobert#endif
26*810390e3Srobert
27*810390e3Srobert	.globl __divmodhi4
28*810390e3Srobert	.type  __divmodhi4, @function
29*810390e3Srobert
30*810390e3Srobert__divmodhi4:
31*810390e3Srobert	bst     r25, 7
32*810390e3Srobert	mov     __tmp_reg__, r23
33*810390e3Srobert	brtc    __divmodhi4_a
34*810390e3Srobert	com     __tmp_reg__
35*810390e3Srobert	rcall   __divmodhi4_b
36*810390e3Srobert
37*810390e3Srobert__divmodhi4_a:
38*810390e3Srobert	sbrc    r23, 7
39*810390e3Srobert	rcall   __divmodhi4_c
40*810390e3Srobert	rcall   __udivmodhi4 ; Call __udivmodhi4 to do real calculation.
41*810390e3Srobert	sbrc    __tmp_reg__, 7
42*810390e3Srobert	rcall   __divmodhi4_c
43*810390e3Srobert	brtc    __divmodhi4_exit
44*810390e3Srobert
45*810390e3Srobert__divmodhi4_b:
46*810390e3Srobert	com     r25
47*810390e3Srobert	neg     r24
48*810390e3Srobert	sbci    r25, 255
49*810390e3Srobert	ret                  ; Return quotient via R23:R22 and remainder via R25:R24.
50*810390e3Srobert
51*810390e3Srobert__divmodhi4_c:
52*810390e3Srobert	com     r23
53*810390e3Srobert	neg     r22
54*810390e3Srobert	sbci    r23, 255
55*810390e3Srobert
56*810390e3Srobert__divmodhi4_exit:
57*810390e3Srobert	ret                  ; Return quotient via R23:R22 and remainder via R25:r24.
58