home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / include / asm-i386 / segment.h < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-27  |  4.8 KB  |  230 lines

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