home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / include / asm / segment.h < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-01  |  4.7 KB  |  220 lines

  1. #ifndef _ASM_SEGMENT_H
  2. #define _ASM_SEGMENT_H
  3.  
  4. static inline unsigned char get_user_byte(const char * addr)
  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)
  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)
  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)
  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)
  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)
  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)
  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)
  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)
  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)
  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)
  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)
  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)
  215. {
  216.     __asm__ __volatile__("mov %w0,%%fs": /* no output */ :"r" (val));
  217. }
  218.  
  219. #endif /* _ASM_SEGMENT_H */
  220.