aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/cxxsupp/builtins/avr/divmodhi4.S
blob: 37171331f4b325e54607eceb945eb86d221dd119 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//===------------- divmodhi4.S - sint16 div & mod -------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// As described at
// https://gcc.gnu.org/wiki/avr-gcc#Exceptions_to_the_Calling_Convention, the
// prototype is `struct {sint16, sint16}  __divmodhi4(sint16, sint16)`.
// The sint16 quotient is returned via R23:R22, and the sint16 remainder is
// returned via R25:R24, while registers R21/R26/27/Rtmp and bit T in SREG
// are clobbered.
//
//===----------------------------------------------------------------------===//

	.text
	.align 2

#ifdef __AVR_TINY__
	.set __tmp_reg__, 16
#else
	.set __tmp_reg__, 0
#endif

	.globl __divmodhi4
	.type  __divmodhi4, @function

__divmodhi4:
	bst     r25, 7
	mov     __tmp_reg__, r23
	brtc    __divmodhi4_a
	com     __tmp_reg__
	rcall   __divmodhi4_b

__divmodhi4_a:
	sbrc    r23, 7
	rcall   __divmodhi4_c
	rcall   __udivmodhi4 ; Call __udivmodhi4 to do real calculation.
	sbrc    __tmp_reg__, 7
	rcall   __divmodhi4_c
	brtc    __divmodhi4_exit

__divmodhi4_b:
	com     r25
	neg     r24
	sbci    r25, 255
	ret                  ; Return quotient via R23:R22 and remainder via R25:R24.

__divmodhi4_c:
	com     r23
	neg     r22
	sbci    r23, 255

__divmodhi4_exit:
	ret                  ; Return quotient via R23:R22 and remainder via R25:r24.