diff options
-rw-r--r-- | arch/mn10300/include/asm/div64.h | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/arch/mn10300/include/asm/div64.h b/arch/mn10300/include/asm/div64.h index 34dcb8e68309..503efab2a516 100644 --- a/arch/mn10300/include/asm/div64.h +++ b/arch/mn10300/include/asm/div64.h | |||
@@ -16,6 +16,19 @@ | |||
16 | extern void ____unhandled_size_in_do_div___(void); | 16 | extern void ____unhandled_size_in_do_div___(void); |
17 | 17 | ||
18 | /* | 18 | /* |
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. | ||
24 | */ | ||
25 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) | ||
26 | # define CLOBBER_MDR_CC "mdr", "cc" | ||
27 | #else | ||
28 | # define CLOBBER_MDR_CC "cc" | ||
29 | #endif | ||
30 | |||
31 | /* | ||
19 | * divide n by base, leaving the result in n and returning the remainder | 32 | * divide n by base, leaving the result in n and returning the remainder |
20 | * - we can do this quite efficiently on the MN10300 by cascading the divides | 33 | * - we can do this quite efficiently on the MN10300 by cascading the divides |
21 | * through the MDR register | 34 | * through the MDR register |
@@ -29,7 +42,7 @@ extern void ____unhandled_size_in_do_div___(void); | |||
29 | "mov mdr,%1 \n" \ | 42 | "mov mdr,%1 \n" \ |
30 | : "+r"(n), "=d"(__rem) \ | 43 | : "+r"(n), "=d"(__rem) \ |
31 | : "r"(base), "1"(__rem) \ | 44 | : "r"(base), "1"(__rem) \ |
32 | : "cc" \ | 45 | : CLOBBER_MDR_CC \ |
33 | ); \ | 46 | ); \ |
34 | } else if (sizeof(n) <= 8) { \ | 47 | } else if (sizeof(n) <= 8) { \ |
35 | union { \ | 48 | union { \ |
@@ -48,7 +61,7 @@ extern void ____unhandled_size_in_do_div___(void); | |||
48 | : "=d"(__rem), "=r"(__quot.w[1]), "=r"(__quot.w[0]) \ | 61 | : "=d"(__rem), "=r"(__quot.w[1]), "=r"(__quot.w[0]) \ |
49 | : "r"(base), "0"(__rem), "1"(__quot.w[1]), \ | 62 | : "r"(base), "0"(__rem), "1"(__quot.w[1]), \ |
50 | "2"(__quot.w[0]) \ | 63 | "2"(__quot.w[0]) \ |
51 | : "cc" \ | 64 | : CLOBBER_MDR_CC \ |
52 | ); \ | 65 | ); \ |
53 | n = __quot.l; \ | 66 | n = __quot.l; \ |
54 | } else { \ | 67 | } else { \ |
@@ -72,7 +85,7 @@ unsigned __muldiv64u(unsigned val, unsigned mult, unsigned div) | |||
72 | * MDR = MDR:val%div */ | 85 | * MDR = MDR:val%div */ |
73 | : "=r"(result) | 86 | : "=r"(result) |
74 | : "0"(val), "ir"(mult), "r"(div) | 87 | : "0"(val), "ir"(mult), "r"(div) |
75 | : "cc" | 88 | : CLOBBER_MDR_CC |
76 | ); | 89 | ); |
77 | 90 | ||
78 | return result; | 91 | return result; |
@@ -93,7 +106,7 @@ signed __muldiv64s(signed val, signed mult, signed div) | |||
93 | * MDR = MDR:val%div */ | 106 | * MDR = MDR:val%div */ |
94 | : "=r"(result) | 107 | : "=r"(result) |
95 | : "0"(val), "ir"(mult), "r"(div) | 108 | : "0"(val), "ir"(mult), "r"(div) |
96 | : "cc" | 109 | : CLOBBER_MDR_CC |
97 | ); | 110 | ); |
98 | 111 | ||
99 | return result; | 112 | return result; |