50 lines · plain
1//===------------ udivmodhi4.S - uint16 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-exception6//7//===----------------------------------------------------------------------===//8//9// As described at10// https://gcc.gnu.org/wiki/avr-gcc#Exceptions_to_the_Calling_Convention, the11// prototype is `struct {uint16, uint16} __udivmodhi4(uint16, uint16)`.12// The uint16 quotient is returned via R23:R22, and the uint16 remainder is13// returned via R25:R24, while R21/R26/R27 are clobbered.14//15//===----------------------------------------------------------------------===//16 17 .text18 .align 219 20 .globl __udivmodhi421 .type __udivmodhi4, @function22 23__udivmodhi4:24 sub r26, r2625 sub r27, r27 ; Initialize the remainder to zero.26 ldi r21, 17 ; Only loop 16 rounds for uint16.27 28__udivmodhi4_loop:29 adc r24, r2430 adc r25, r2531 dec r2132 breq __udivmodhi4_end33 adc r26, r2634 adc r27, r2735 cp r26, r2236 cpc r27, r23 ; Compare with the divisor.37 brcs __udivmodhi4_loop38 sub r26, r2239 sbc r27, r23 ; Subtract the divisor.40 rjmp __udivmodhi4_loop41 42__udivmodhi4_end:43 com r2444 com r2545 mov r22, r2446 mov r23, r25 ; The quotient is returned in R23:R22.47 mov r24, r2648 mov r25, r27 ; The remainder is returned in in R25:R24.49 ret50