~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mn10300/include/asm/div64.h

Version: ~ [ linux-5.7-rc7 ] ~ [ linux-5.6.14 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.42 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.124 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.181 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.224 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.224 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.84 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* MN10300 64-bit division
  2  *
  3  * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
  4  * Written by David Howells (dhowells@redhat.com)
  5  *
  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.
 10  */
 11 #ifndef _ASM_DIV64
 12 #define _ASM_DIV64
 13 
 14 #include <linux/types.h>
 15 
 16 extern void ____unhandled_size_in_do_div___(void);
 17 
 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 /*
 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
 35  */
 36 #define do_div(n, base)                                                 \
 37 ({                                                                      \
 38         unsigned __rem = 0;                                             \
 39         if (sizeof(n) <= 4) {                                           \
 40                 asm("mov        %1,mdr  \n"                             \
 41                     "divu       %2,%0   \n"                             \
 42                     "mov        mdr,%1  \n"                             \
 43                     : "+r"(n), "=d"(__rem)                              \
 44                     : "r"(base), "1"(__rem)                             \
 45                     : CLOBBER_MDR_CC                                    \
 46                     );                                                  \
 47         } else if (sizeof(n) <= 8) {                                    \
 48                 union {                                                 \
 49                         unsigned long long l;                           \
 50                         u32 w[2];                                       \
 51                 } __quot;                                               \
 52                 __quot.l = n;                                           \
 53                 asm("mov        %0,mdr  \n"     /* MDR = 0 */           \
 54                     "divu       %3,%1   \n"                             \
 55                     /* __quot.MSL = __div.MSL / base, */                \
 56                     /* MDR = MDR:__div.MSL % base */                    \
 57                     "divu       %3,%2   \n"                             \
 58                     /* __quot.LSL = MDR:__div.LSL / base, */            \
 59                     /* MDR = MDR:__div.LSL % base */                    \
 60                     "mov        mdr,%0  \n"                             \
 61                     : "=d"(__rem), "=r"(__quot.w[1]), "=r"(__quot.w[0]) \
 62                     : "r"(base), ""(__rem), "1"(__quot.w[1]),          \
 63                       "2"(__quot.w[0])                                  \
 64                     : CLOBBER_MDR_CC                                    \
 65                     );                                                  \
 66                 n = __quot.l;                                           \
 67         } else {                                                        \
 68                 ____unhandled_size_in_do_div___();                      \
 69         }                                                               \
 70         __rem;                                                          \
 71 })
 72 
 73 /*
 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
 77  */
 78 static inline __attribute__((const))
 79 unsigned __muldiv64u(unsigned val, unsigned mult, unsigned div)
 80 {
 81         unsigned result;
 82 
 83         asm("mulu       %2,%0   \n"     /* MDR:val = val*mult */
 84             "divu       %3,%0   \n"     /* val = MDR:val/div;
 85                                          * MDR = MDR:val%div */
 86             : "=r"(result)
 87             : ""(val), "ir"(mult), "r"(div)
 88             : CLOBBER_MDR_CC
 89             );
 90 
 91         return result;
 92 }
 93 
 94 /*
 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
 98  */
 99 static inline __attribute__((const))
100 signed __muldiv64s(signed val, signed mult, signed div)
101 {
102         signed result;
103 
104         asm("mul        %2,%0   \n"     /* MDR:val = val*mult */
105             "div        %3,%0   \n"     /* val = MDR:val/div;
106                                          * MDR = MDR:val%div */
107             : "=r"(result)
108             : ""(val), "ir"(mult), "r"(div)
109             : CLOBBER_MDR_CC
110             );
111 
112         return result;
113 }
114 
115 #endif /* _ASM_DIV64 */
116 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp