__aeabi_uldivmod.S revision 1.8.2.1 1 /*-
2 * Copyright (c) 2012 The NetBSD Foundation, Inc.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Matt Thomas of 3am Software Foundry.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include <machine/asm.h>
31
32 RCSID("$NetBSD: __aeabi_uldivmod.S,v 1.8.2.1 2014/08/10 06:47:05 tls Exp $")
33
34 /*
35 * typedef struct { unsigned long long quo, rem } ulldiv_t;
36 * __value_in_regs ulldiv_t __aeabi_uldivmod(unsigned long long n,
37 * unsigned long long d);
38 */
39
40 ENTRY(__aeabi_uldivmod)
41 #ifdef __ARM_EABI__
42 # if !defined(__ARM_DWARF_EH__)
43 .fnstart
44 #endif
45 .cfi_startproc
46 #endif
47 #if !defined(_KERNEL) && !defined(_STANDALONE)
48 #if !defined(__thumb__)
49 orrs ip, r2, r3
50 beq .Ldivbyzero
51 #elif defined(_ARM_ARCH_T2)
52 cbnz r2, 1f
53 cbz r3, .Ldivbyzero
54 1:
55 #else
56 cmp r2, #0
57 bne 1f
58 cmp r3, #0
59 beq .Ldivbyzero
60 1:
61 #endif
62 #endif
63
64 push {r4,lr}
65 #ifdef __ARM_EABI__
66 # if !defined(__ARM_DWARF_EH__)
67 .save {r4,lr}
68 # endif
69 .cfi_def_cfa_offset 8
70 .cfi_offset 14, -4
71 .cfi_offset 4, -8
72 #endif
73 sub sp, sp, #16
74 #ifdef __ARM_EABI__
75 .cfi_def_cfa_offset 24
76 #endif
77 #if !defined(__thumb__) || defined(_ARM_ARCH_T2)
78 add r4, sp, #8
79 #else
80 mov r4, sp
81 adds r4, r4, #8
82 #endif
83 str r4, [sp]
84 bl PLT_SYM(__qdivrem)
85 add sp, sp, #8
86 #ifdef __ARM_EABI__
87 .cfi_def_cfa_offset 16
88 .cfi_offset 3, -12
89 .cfi_offset 2, -16
90 #endif
91 /*
92 * The remainder is already on the stack just waiting to be popped
93 * into r2/r3.
94 */
95 pop {r2-r4,pc}
96
97 #if !defined(_KERNEL) && !defined(_STANDALONE)
98 .Ldivbyzero:
99 push {r0-r1,r4,lr}
100 #ifdef __ARM_EABI__
101 # if !defined(__ARM_DWARF_EH__)
102 .save {r0-r1,r4,lr}
103 # endif
104 .cfi_def_cfa_offset 16
105 .cfi_offset 14, -4
106 .cfi_offset 4, -8
107 #endif
108 #ifdef __thumb__
109 movs r0, #0
110 mvns r0, r0
111 #else
112 mvn r0, #0
113 #endif
114 movs r1, r0
115 bl PLT_SYM(__aeabi_ldiv0)
116 pop {r2-r4,pc}
117 #endif
118 #ifdef __ARM_EABI__
119 .cfi_endproc
120 # if !defined(__ARM_DWARF_EH__)
121 .fnend
122 # endif
123 #endif
124 END(__aeabi_uldivmod)
125