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 :
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 :
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
00207
00208
00209
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