xref: /freebsd/contrib/llvm-project/compiler-rt/lib/builtins/arm/aeabi_uidivmod.S (revision a90b9d0159070121c221b966469c3e36d912bf82)
1//===-- aeabi_uidivmod.S - EABI uidivmod implementation -------------------===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "../assembly.h"
10
11// struct { unsigned quot, unsigned rem}
12//        __aeabi_uidivmod(unsigned numerator, unsigned denominator) {
13//   unsigned rem, quot;
14//   quot = __udivmodsi4(numerator, denominator, &rem);
15//   return {quot, rem};
16// }
17
18#if defined(__MINGW32__)
19#define __aeabi_uidivmod __rt_udiv
20#endif
21
22        .syntax unified
23        .text
24        DEFINE_CODE_STATE
25        .p2align 2
26DEFINE_COMPILERRT_FUNCTION(__aeabi_uidivmod)
27#if defined(USE_THUMB_1)
28        cmp     r0, r1
29        bcc     LOCAL_LABEL(case_denom_larger)
30        push    {r0, r1, lr}
31        bl      SYMBOL_NAME(__aeabi_uidiv)
32        pop     {r1, r2, r3}
33        muls    r2, r0, r2 // r2 = quot * denom
34        subs    r1, r1, r2
35        JMP     (r3)
36LOCAL_LABEL(case_denom_larger):
37        movs    r1, r0
38        movs    r0, #0
39        JMP     (lr)
40#else // defined(USE_THUMB_1)
41        push    { lr }
42        sub     sp, sp, #4
43        mov     r2, sp
44#if defined(__MINGW32__)
45        mov     r3, r0
46        mov     r0, r1
47        mov     r1, r3
48#endif
49        bl      SYMBOL_NAME(__udivmodsi4)
50        ldr     r1, [sp]
51        add     sp, sp, #4
52        pop     { pc }
53#endif
54END_COMPILERRT_FUNCTION(__aeabi_uidivmod)
55
56NO_EXEC_STACK_DIRECTIVE
57
58