root/include/asm/segment.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. get_user_byte
  2. get_user_word
  3. get_user_long
  4. put_user_byte
  5. put_user_word
  6. put_user_long
  7. __generic_memcpy_tofs
  8. __constant_memcpy_tofs
  9. __generic_memcpy_fromfs
  10. __constant_memcpy_fromfs
  11. get_fs
  12. get_ds
  13. set_fs

   1 #ifndef _ASM_SEGMENT_H
   2 #define _ASM_SEGMENT_H
   3 
   4 static inline unsigned char get_user_byte(const char * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
   5 {
   6         register unsigned char _v;
   7 
   8         __asm__ ("movb %%fs:%1,%0":"=q" (_v):"m" (*addr));
   9         return _v;
  10 }
  11 
  12 #define get_fs_byte(addr) get_user_byte((char *)(addr))
  13 
  14 static inline unsigned short get_user_word(const short *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  15 {
  16         unsigned short _v;
  17 
  18         __asm__ ("movw %%fs:%1,%0":"=r" (_v):"m" (*addr));
  19         return _v;
  20 }
  21 
  22 #define get_fs_word(addr) get_user_word((short *)(addr))
  23 
  24 static inline unsigned long get_user_long(const int *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  25 {
  26         unsigned long _v;
  27 
  28         __asm__ ("movl %%fs:%1,%0":"=r" (_v):"m" (*addr)); \
  29         return _v;
  30 }
  31 
  32 #define get_fs_long(addr) get_user_long((int *)(addr))
  33 
  34 static inline void put_user_byte(char val,char *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  35 {
  36 __asm__ ("movb %0,%%fs:%1": /* no outputs */ :"iq" (val),"m" (*addr));
  37 }
  38 
  39 #define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr))
  40 
  41 static inline void put_user_word(short val,short * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  42 {
  43 __asm__ ("movw %0,%%fs:%1": /* no outputs */ :"ir" (val),"m" (*addr));
  44 }
  45 
  46 #define put_fs_word(x,addr) put_user_word((x),(short *)(addr))
  47 
  48 static inline void put_user_long(unsigned long val,int * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  49 {
  50 __asm__ ("movl %0,%%fs:%1": /* no outputs */ :"ir" (val),"m" (*addr));
  51 }
  52 
  53 #define put_fs_long(x,addr) put_user_long((x),(int *)(addr))
  54 
  55 static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
     /* [previous][next][first][last][top][bottom][index][help] */
  56 {
  57 __asm__("cld\n\t"
  58         "push %%es\n\t"
  59         "push %%fs\n\t"
  60         "pop %%es\n\t"
  61         "testb $1,%%cl\n\t"
  62         "je 1f\n\t"
  63         "movsb\n"
  64         "1:\ttestb $2,%%cl\n\t"
  65         "je 2f\n\t"
  66         "movsw\n"
  67         "2:\tshrl $2,%%ecx\n\t"
  68         "rep ; movsl\n\t"
  69         "pop %%es"
  70         : /* no outputs */
  71         :"c" (n),"D" ((long) to),"S" ((long) from)
  72         :"cx","di","si");
  73 }
  74 
  75 static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
     /* [previous][next][first][last][top][bottom][index][help] */
  76 {
  77         switch (n) {
  78                 case 0:
  79                         return;
  80                 case 1:
  81                         put_user_byte(*(const char *) from, (char *) to);
  82                         return;
  83                 case 2:
  84                         put_user_word(*(const short *) from, (short *) to);
  85                         return;
  86                 case 3:
  87                         put_user_word(*(const short *) from, (short *) to);
  88                         put_user_byte(*(2+(const char *) from), 2+(char *) to);
  89                         return;
  90                 case 4:
  91                         put_user_long(*(const int *) from, (int *) to);
  92                         return;
  93         }
  94 #define COMMON(x) \
  95 __asm__("cld\n\t" \
  96         "push %%es\n\t" \
  97         "push %%fs\n\t" \
  98         "pop %%es\n\t" \
  99         "rep ; movsl\n\t" \
 100         x \
 101         "pop %%es" \
 102         : /* no outputs */ \
 103         :"c" (n/4),"D" ((long) to),"S" ((long) from) \
 104         :"cx","di","si")
 105 
 106         switch (n % 4) {
 107                 case 0:
 108                         COMMON("");
 109                         return;
 110                 case 1:
 111                         COMMON("movsb\n\t");
 112                         return;
 113                 case 2:
 114                         COMMON("movsw\n\t");
 115                         return;
 116                 case 3:
 117                         COMMON("movsw\n\tmovsb\n\t");
 118                         return;
 119         }
 120 #undef COMMON
 121 }
 122 
 123 static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
     /* [previous][next][first][last][top][bottom][index][help] */
 124 {
 125 __asm__("cld\n\t"
 126         "testb $1,%%cl\n\t"
 127         "je 1f\n\t"
 128         "fs ; movsb\n"
 129         "1:\ttestb $2,%%cl\n\t"
 130         "je 2f\n\t"
 131         "fs ; movsw\n"
 132         "2:\tshrl $2,%%ecx\n\t"
 133         "rep ; fs ; movsl"
 134         : /* no outputs */
 135         :"c" (n),"D" ((long) to),"S" ((long) from)
 136         :"cx","di","si","memory");
 137 }
 138 
 139 static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
     /* [previous][next][first][last][top][bottom][index][help] */
 140 {
 141         switch (n) {
 142                 case 0:
 143                         return;
 144                 case 1:
 145                         *(char *)to = get_user_byte((const char *) from);
 146                         return;
 147                 case 2:
 148                         *(short *)to = get_user_word((const short *) from);
 149                         return;
 150                 case 3:
 151                         *(short *) to = get_user_word((const short *) from);
 152                         *(char *) to = get_user_byte(2+(const char *) from);
 153                         return;
 154                 case 4:
 155                         *(int *) to = get_user_long((const int *) from);
 156                         return;
 157         }
 158 #define COMMON(x) \
 159 __asm__("cld\n\t" \
 160         "rep ; fs ; movsl\n\t" \
 161         x \
 162         : /* no outputs */ \
 163         :"c" (n/4),"D" ((long) to),"S" ((long) from) \
 164         :"cx","di","si","memory")
 165 
 166         switch (n % 4) {
 167                 case 0:
 168                         COMMON("");
 169                         return;
 170                 case 1:
 171                         COMMON("fs ; movsb");
 172                         return;
 173                 case 2:
 174                         COMMON("fs ; movsw");
 175                         return;
 176                 case 3:
 177                         COMMON("fs ; movsw\n\tfs ; movsb");
 178                         return;
 179         }
 180 #undef COMMON
 181 }
 182 
 183 #define memcpy_fromfs(to, from, n) \
 184 (__builtin_constant_p(n) ? \
 185  __constant_memcpy_fromfs((to),(from),(n)) : \
 186  __generic_memcpy_fromfs((to),(from),(n)))
 187 
 188 #define memcpy_tofs(to, from, n) \
 189 (__builtin_constant_p(n) ? \
 190  __constant_memcpy_tofs((to),(from),(n)) : \
 191  __generic_memcpy_tofs((to),(from),(n)))
 192 
 193 /*
 194  * Someone who knows GNU asm better than I should double check the followig.
 195  * It seems to work, but I don't know if I'm doing something subtly wrong.
 196  * --- TYT, 11/24/91
 197  * [ nothing wrong here, Linus: I just changed the ax to be any reg ]
 198  */
 199 
 200 static inline unsigned long get_fs(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 201 {
 202         unsigned long _v;
 203         __asm__("mov %%fs,%w0":"=r" (_v):"0" (0));
 204         return _v;
 205 }
 206 
 207 static inline unsigned long get_ds(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 208 {
 209         unsigned long _v;
 210         __asm__("mov %%ds,%w0":"=r" (_v):"0" (0));
 211         return _v;
 212 }
 213 
 214 static inline void set_fs(unsigned long val)
     /* [previous][next][first][last][top][bottom][index][help] */
 215 {
 216         __asm__ __volatile__("mov %w0,%%fs": /* no output */ :"r" (val));
 217 }
 218 
 219 #endif /* _ASM_SEGMENT_H */

/* [previous][next][first][last][top][bottom][index][help] */