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.
|