1*81ad6265SDimitry Andric//===------------ udivmodhi4.S - uint16 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 {uint16, uint16} __udivmodhi4(uint16, uint16)`. 12*81ad6265SDimitry Andric// The uint16 quotient is returned via R23:R22, and the uint16 remainder is 13*81ad6265SDimitry Andric// returned via R25:R24, while R21/R26/R27 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 .globl __udivmodhi4 21*81ad6265SDimitry Andric .type __udivmodhi4, @function 22*81ad6265SDimitry Andric 23*81ad6265SDimitry Andric__udivmodhi4: 24*81ad6265SDimitry Andric sub r26, r26 25*81ad6265SDimitry Andric sub r27, r27 ; Initialize the remainder to zero. 26*81ad6265SDimitry Andric ldi r21, 17 ; Only loop 16 rounds for uint16. 27*81ad6265SDimitry Andric 28*81ad6265SDimitry Andric__udivmodhi4_loop: 29*81ad6265SDimitry Andric adc r24, r24 30*81ad6265SDimitry Andric adc r25, r25 31*81ad6265SDimitry Andric dec r21 32*81ad6265SDimitry Andric breq __udivmodhi4_end 33*81ad6265SDimitry Andric adc r26, r26 34*81ad6265SDimitry Andric adc r27, r27 35*81ad6265SDimitry Andric cp r26, r22 36*81ad6265SDimitry Andric cpc r27, r23 ; Compare with the divisor. 37*81ad6265SDimitry Andric brcs __udivmodhi4_loop 38*81ad6265SDimitry Andric sub r26, r22 39*81ad6265SDimitry Andric sbc r27, r23 ; Subtract the divisor. 40*81ad6265SDimitry Andric rjmp __udivmodhi4_loop 41*81ad6265SDimitry Andric 42*81ad6265SDimitry Andric__udivmodhi4_end: 43*81ad6265SDimitry Andric com r24 44*81ad6265SDimitry Andric com r25 45*81ad6265SDimitry Andric mov r22, r24 46*81ad6265SDimitry Andric mov r23, r25 ; The quotient is returned in R23:R22. 47*81ad6265SDimitry Andric mov r24, r26 48*81ad6265SDimitry Andric mov r25, r27 ; The remainder is returned in in R25:R24. 49*81ad6265SDimitry Andric ret 50