xref: /freebsd-src/contrib/llvm-project/compiler-rt/lib/builtins/avr/divmodqi4.S (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
1*81ad6265SDimitry Andric//===------------- divmodqi4.S - sint8 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 {sint8, sint8}  __divmodqi4(sint8, sint8)`.
12*81ad6265SDimitry Andric// The sint8 quotient is returned via R24, and the sint8 remainder is returned
13*81ad6265SDimitry Andric// via R25, while registers R23/Rtmp and bit T in SREG are 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#ifdef __AVR_TINY__
21*81ad6265SDimitry Andric	.set __tmp_reg__, 16
22*81ad6265SDimitry Andric#else
23*81ad6265SDimitry Andric	.set __tmp_reg__, 0
24*81ad6265SDimitry Andric#endif
25*81ad6265SDimitry Andric
26*81ad6265SDimitry Andric	.globl __divmodqi4
27*81ad6265SDimitry Andric	.type  __divmodqi4, @function
28*81ad6265SDimitry Andric
29*81ad6265SDimitry Andric__divmodqi4:
30*81ad6265SDimitry Andric	bst     r24, 7
31*81ad6265SDimitry Andric	mov     __tmp_reg__, r24
32*81ad6265SDimitry Andric	eor     __tmp_reg__, r22
33*81ad6265SDimitry Andric	sbrc    r24, 7
34*81ad6265SDimitry Andric	neg     r24
35*81ad6265SDimitry Andric	sbrc    r22, 7
36*81ad6265SDimitry Andric	neg     r22
37*81ad6265SDimitry Andric	rcall   __udivmodqi4   ; Call __udivmodqi4 to do real calculation.
38*81ad6265SDimitry Andric	brtc    __divmodqi4_1
39*81ad6265SDimitry Andric	neg     r25
40*81ad6265SDimitry Andric
41*81ad6265SDimitry Andric__divmodqi4_1:
42*81ad6265SDimitry Andric	sbrc    __tmp_reg__, 7
43*81ad6265SDimitry Andric	neg     r24
44*81ad6265SDimitry Andric	ret                    ; Return quotient via R24 and remainder via R25.
45