MN10300: gcc 4.6 vs am33 inline assembly

GCC 4.6 explicitly represents the MDR register. It may be accessed
via the "z" constraint. Perhaps more importantly, it tracks when
the MDR register is clobbered and uses the RETF instruction if the
incoming value is still valid.

Thus it is important to (at least) clobber the MDR register in
relevant inline assembly fragments, lest RETF be used incorrectly.

The only instances I could find are here. There are reads of the
MDR register in kernel/gdb-stub.c, but that's harmless. Although,
frankly, __builtin_return_address(0) might be a better thing in
those cases. Certainly MDR isn't going to contain anything else
that might be useful...

Signed-off-by: Richard Henderson <rth@redhat.com>
Signed-off-by: David Howells <dhowells@redhat.com>

authored by Richard Henderson and committed by David Howells 5a4b65ab 1a8d59e5

+17 -4
+17 -4
arch/mn10300/include/asm/div64.h
··· 16 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 32 * divide n by base, leaving the result in n and returning the remainder 20 33 * - we can do this quite efficiently on the MN10300 by cascading the divides 21 34 * through the MDR register ··· 42 29 "mov mdr,%1 \n" \ 43 30 : "+r"(n), "=d"(__rem) \ 44 31 : "r"(base), "1"(__rem) \ 45 - : "cc" \ 32 + : CLOBBER_MDR_CC \ 46 33 ); \ 47 34 } else if (sizeof(n) <= 8) { \ 48 35 union { \ ··· 61 48 : "=d"(__rem), "=r"(__quot.w[1]), "=r"(__quot.w[0]) \ 62 49 : "r"(base), "0"(__rem), "1"(__quot.w[1]), \ 63 50 "2"(__quot.w[0]) \ 64 - : "cc" \ 51 + : CLOBBER_MDR_CC \ 65 52 ); \ 66 53 n = __quot.l; \ 67 54 } else { \ ··· 85 72 * MDR = MDR:val%div */ 86 73 : "=r"(result) 87 74 : "0"(val), "ir"(mult), "r"(div) 88 - : "cc" 75 + : CLOBBER_MDR_CC 89 76 ); 90 77 91 78 return result; ··· 106 93 * MDR = MDR:val%div */ 107 94 : "=r"(result) 108 95 : "0"(val), "ir"(mult), "r"(div) 109 - : "cc" 96 + : CLOBBER_MDR_CC 110 97 ); 111 98 112 99 return result;