Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/microblaze/lib/umodsi3.S
26426 views
1
/* SPDX-License-Identifier: GPL-2.0 */
2
#include <linux/linkage.h>
3
4
/*
5
* Unsigned modulo operation for 32 bit integers.
6
* Input : op1 in Reg r5
7
* op2 in Reg r6
8
* Output: op1 mod op2 in Reg r3
9
*/
10
11
.text
12
.globl __umodsi3
13
.type __umodsi3, @function
14
.ent __umodsi3
15
16
__umodsi3:
17
.frame r1, 0, r15
18
19
addik r1, r1, -12
20
swi r29, r1, 0
21
swi r30, r1, 4
22
swi r31, r1, 8
23
24
beqi r6, div_by_zero /* div_by_zero - division error */
25
beqid r5, result_is_zero /* result is zero */
26
addik r3, r0, 0 /* clear div */
27
addik r30, r0, 0 /* clear mod */
28
addik r29, r0, 32 /* initialize the loop count */
29
30
/* check if r6 and r5 are equal /* if yes, return 0 */
31
rsub r18, r5, r6
32
beqi r18, return_here
33
34
/* check if (uns)r6 is greater than (uns)r5. in that case, just return r5 */
35
xor r18, r5, r6
36
bgeid r18, 16
37
addik r3, r5, 0
38
blti r6, return_here
39
bri $lcheckr6
40
rsub r18, r5, r6 /* microblazecmp */
41
bgti r18, return_here
42
43
/* if r6 [bit 31] is set, then return result as r5-r6 */
44
$lcheckr6:
45
bgtid r6, div0
46
addik r3, r0, 0
47
addik r18, r0, 0x7fffffff
48
and r5, r5, r18
49
and r6, r6, r18
50
brid return_here
51
rsub r3, r6, r5
52
/* first part: try to find the first '1' in the r5 */
53
div0:
54
blti r5, div2
55
div1:
56
add r5, r5, r5 /* left shift logical r5 */
57
bgeid r5, div1
58
addik r29, r29, -1
59
div2:
60
/* left shift logical r5 get the '1' into the carry */
61
add r5, r5, r5
62
addc r3, r3, r3 /* move that bit into the mod register */
63
rsub r31, r6, r3 /* try to subtract (r3 a r6) */
64
blti r31, mod_too_small
65
/* move the r31 to mod since the result was positive */
66
or r3, r0, r31
67
addik r30, r30, 1
68
mod_too_small:
69
addik r29, r29, -1
70
beqi r29, loop_end
71
add r30, r30, r30 /* shift in the '1' into div */
72
bri div2 /* div2 */
73
loop_end:
74
bri return_here
75
div_by_zero:
76
result_is_zero:
77
or r3, r0, r0 /* set result to 0 */
78
return_here:
79
/* restore values of csrs and that of r3 and the divisor and the dividend */
80
lwi r29, r1, 0
81
lwi r30, r1, 4
82
lwi r31, r1, 8
83
rtsd r15, 8
84
addik r1, r1, 12
85
86
.size __umodsi3, . - __umodsi3
87
.end __umodsi3
88
89