segment.h

Go to the documentation of this file.
00001 #ifndef _ASM_SEGMENT_H
00002 #define _ASM_SEGMENT_H
00003 
00004 static inline unsigned char get_user_byte(const char * addr)
00005 {
00006         register unsigned char _v;
00007 
00008         __asm__ ("movb %%fs:%1,%0":"=q" (_v):"m" (*addr));
00009         return _v;
00010 }
00011 
00012 #define get_fs_byte(addr) get_user_byte((char *)(addr))
00013 
00014 static inline unsigned short get_user_word(const short *addr)
00015 {
00016         unsigned short _v;
00017 
00018         __asm__ ("movw %%fs:%1,%0":"=r" (_v):"m" (*addr));
00019         return _v;
00020 }
00021 
00022 #define get_fs_word(addr) get_user_word((short *)(addr))
00023 
00024 static inline unsigned long get_user_long(const int *addr)
00025 {
00026         unsigned long _v;
00027 
00028         __asm__ ("movl %%fs:%1,%0":"=r" (_v):"m" (*addr)); \
00029         return _v;
00030 }
00031 
00032 #define get_fs_long(addr) get_user_long((int *)(addr))
00033 
00034 static inline void put_user_byte(char val,char *addr)
00035 {
00036 
00037 
00038 */ :"iq" (val),"m" (*addr));
00039 }
00040 
00041 #define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr))
00042 
00043 static inline void put_user_word(short val,short * addr)
00044 {
00045 
00046 
00047 */ :"ir" (val),"m" (*addr));
00048 }
00049 
00050 #define put_fs_word(x,addr) put_user_word((x),(short *)(addr))
00051 
00052 static inline void put_user_long(unsigned long val,int * addr)
00053 {
00054 
00055 
00056 */ :"ir" (val),"m" (*addr));
00057 }
00058 
00059 #define put_fs_long(x,addr) put_user_long((x),(int *)(addr))
00060 
00061 static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
00062 {
00063 __asm__("cld\n\t"
00064         "push %%es\n\t"
00065         "push %%fs\n\t"
00066         "pop %%es\n\t"
00067         "testb $1,%%cl\n\t"
00068         "je 1f\n\t"
00069         "movsb\n"
00070         "1:\ttestb $2,%%cl\n\t"
00071         "je 2f\n\t"
00072         "movsw\n"
00073         "2:\tshrl $2,%%ecx\n\t"
00074         "rep ; movsl\n\t"
00075         "pop %%es"
00076         : ///< no outputs 
00077         :"c" (n),"D" ((long) to),"S" ((long) from)
00078         :"cx","di","si");
00079 }
00080 
00081 static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
00082 {
00083         switch (n) {
00084                 case 0:
00085                         return;
00086                 case 1:
00087                         put_user_byte(*(const char *) from, (char *) to);
00088                         return;
00089                 case 2:
00090                         put_user_word(*(const short *) from, (short *) to);
00091                         return;
00092                 case 3:
00093                         put_user_word(*(const short *) from, (short *) to);
00094                         put_user_byte(*(2+(const char *) from), 2+(char *) to);
00095                         return;
00096                 case 4:
00097                         put_user_long(*(const int *) from, (int *) to);
00098                         return;
00099         }
00100 #define COMMON(x) \
00101 __asm__("cld\n\t" \
00102         "push %%es\n\t" \
00103         "push %%fs\n\t" \
00104         "pop %%es\n\t" \
00105         "rep ; movsl\n\t" \
00106         x \
00107         "pop %%es" \
00108 
00109 
00110 */ \
00111         :"c" (n/4),"D" ((long) to),"S" ((long) from) \
00112         :"cx","di","si")
00113 
00114         switch (n % 4) {
00115                 case 0:
00116                         COMMON("");
00117                         return;
00118                 case 1:
00119                         COMMON("movsb\n\t");
00120                         return;
00121                 case 2:
00122                         COMMON("movsw\n\t");
00123                         return;
00124                 case 3:
00125                         COMMON("movsw\n\tmovsb\n\t");
00126                         return;
00127         }
00128 #undef COMMON
00129 }
00130 
00131 static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
00132 {
00133 __asm__("cld\n\t"
00134         "testb $1,%%cl\n\t"
00135         "je 1f\n\t"
00136         "fs ; movsb\n"
00137         "1:\ttestb $2,%%cl\n\t"
00138         "je 2f\n\t"
00139         "fs ; movsw\n"
00140         "2:\tshrl $2,%%ecx\n\t"
00141         "rep ; fs ; movsl"
00142         : ///< no outputs 
00143         :"c" (n),"D" ((long) to),"S" ((long) from)
00144         :"cx","di","si","memory");
00145 }
00146 
00147 static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
00148 {
00149         switch (n) {
00150                 case 0:
00151                         return;
00152                 case 1:
00153                         *(char *)to = get_user_byte((const char *) from);
00154                         return;
00155                 case 2:
00156                         *(short *)to = get_user_word((const short *) from);
00157                         return;
00158                 case 3:
00159                         *(short *) to = get_user_word((const short *) from);
00160                         *(char *) to = get_user_byte(2+(const char *) from);
00161                         return;
00162                 case 4:
00163                         *(int *) to = get_user_long((const int *) from);
00164                         return;
00165         }
00166 #define COMMON(x) \
00167 __asm__("cld\n\t" \
00168         "rep ; fs ; movsl\n\t" \
00169         x \
00170 
00171 
00172 */ \
00173         :"c" (n/4),"D" ((long) to),"S" ((long) from) \
00174         :"cx","di","si","memory")
00175 
00176         switch (n % 4) {
00177                 case 0:
00178                         COMMON("");
00179                         return;
00180                 case 1:
00181                         COMMON("fs ; movsb");
00182                         return;
00183                 case 2:
00184                         COMMON("fs ; movsw");
00185                         return;
00186                 case 3:
00187                         COMMON("fs ; movsw\n\tfs ; movsb");
00188                         return;
00189         }
00190 #undef COMMON
00191 }
00192 
00193 #define memcpy_fromfs(to, from, n) \
00194 (__builtin_constant_p(n) ? \
00195  __constant_memcpy_fromfs((to),(from),(n)) : \
00196  __generic_memcpy_fromfs((to),(from),(n)))
00197 
00198 #define memcpy_tofs(to, from, n) \
00199 (__builtin_constant_p(n) ? \
00200  __constant_memcpy_tofs((to),(from),(n)) : \
00201  __generic_memcpy_tofs((to),(from),(n)))
00202 
00203 /**
00204 *
00205 
00206  * Someone who knows GNU asm better than I should double check the followig.
00207  * It seems to work, but I don't know if I'm doing something subtly wrong.
00208  * --- TYT, 11/24/91
00209  * [ nothing wrong here, Linus: I just changed the ax to be any reg ]
00210 
00211 
00212 */
00213 
00214 static inline unsigned long get_fs(void)
00215 {
00216         unsigned long _v;
00217         __asm__("mov %%fs,%w0":"=r" (_v):"0" (0));
00218         return _v;
00219 }
00220 
00221 static inline unsigned long get_ds(void)
00222 {
00223         unsigned long _v;
00224         __asm__("mov %%ds,%w0":"=r" (_v):"0" (0));
00225         return _v;
00226 }
00227 
00228 static inline void set_fs(unsigned long val)
00229 {
00230 
00231 
00232 */ :"r" (val));
00233 }
00234 
00235 #endif // _ASM_SEGMENT_H 

Generated on Mon May 1 21:46:59 2006 for KernelAPI by  doxygen 1.4.6-5