1
/* MN10300 64-bit division
3
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4
* Written by David Howells (dhowells@redhat.com)
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public Licence
8
* as published by the Free Software Foundation; either version
9
* 2 of the Licence, or (at your option) any later version.
14
#include <linux/types.h>
16
extern void ____unhandled_size_in_do_div___(void);
19
* Beginning with gcc 4.6, the MDR register is represented explicitly. We
20
* must, therefore, at least explicitly clobber the register when we make
21
* changes to it. The following assembly fragments *could* be rearranged in
22
* order to leave the moves to/from the MDR register to the compiler, but the
23
* gains would be minimal at best.
25
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
26
# define CLOBBER_MDR_CC "mdr", "cc"
28
# define CLOBBER_MDR_CC "cc"
32
* divide n by base, leaving the result in n and returning the remainder
33
* - we can do this quite efficiently on the MN10300 by cascading the divides
34
* through the MDR register
36
#define do_div(n, base) \
39
if (sizeof(n) <= 4) { \
43
: "+r"(n), "=d"(__rem) \
44
: "r"(base), "1"(__rem) \
47
} else if (sizeof(n) <= 8) { \
49
unsigned long long l; \
53
asm("mov %0,mdr \n" /* MDR = 0 */ \
55
/* __quot.MSL = __div.MSL / base, */ \
56
/* MDR = MDR:__div.MSL % base */ \
58
/* __quot.LSL = MDR:__div.LSL / base, */ \
59
/* MDR = MDR:__div.LSL % base */ \
61
: "=d"(__rem), "=r"(__quot.w[1]), "=r"(__quot.w[0]) \
62
: "r"(base), "0"(__rem), "1"(__quot.w[1]), \
68
____unhandled_size_in_do_div___(); \
74
* do an unsigned 32-bit multiply and divide with intermediate 64-bit product
75
* so as not to lose accuracy
76
* - we use the MDR register to hold the MSW of the product
78
static inline __attribute__((const))
79
unsigned __muldiv64u(unsigned val, unsigned mult, unsigned div)
83
asm("mulu %2,%0 \n" /* MDR:val = val*mult */
84
"divu %3,%0 \n" /* val = MDR:val/div;
85
* MDR = MDR:val%div */
87
: "0"(val), "ir"(mult), "r"(div)
95
* do a signed 32-bit multiply and divide with intermediate 64-bit product so
96
* as not to lose accuracy
97
* - we use the MDR register to hold the MSW of the product
99
static inline __attribute__((const))
100
signed __muldiv64s(signed val, signed mult, signed div)
104
asm("mul %2,%0 \n" /* MDR:val = val*mult */
105
"div %3,%0 \n" /* val = MDR:val/div;
106
* MDR = MDR:val%div */
108
: "0"(val), "ir"(mult), "r"(div)
115
#endif /* _ASM_DIV64 */