Import 1.1.43
[davej-history.git] / include / asm / segment.h
blob76dfe64016822f9fa9ba4ad195599600d7ad9164
1 #ifndef _ASM_SEGMENT_H
2 #define _ASM_SEGMENT_H
4 staticinlineunsigned charget_user_byte(const char* addr)
6 registerunsigned char _v;
8 __asm__("movb %%fs:%1,%0":"=q"(_v):"m"(*addr));
9 return _v;
12 #define get_fs_byte(addr) get_user_byte((char *)(addr))
14 staticinlineunsigned shortget_user_word(const short*addr)
16 unsigned short _v;
18 __asm__("movw %%fs:%1,%0":"=r"(_v):"m"(*addr));
19 return _v;
22 #define get_fs_word(addr) get_user_word((short *)(addr))
24 staticinlineunsigned longget_user_long(const int*addr)
26 unsigned long _v;
28 __asm__("movl %%fs:%1,%0":"=r"(_v):"m"(*addr)); \
29 return _v;
32 #define get_fs_long(addr) get_user_long((int *)(addr))
34 staticinlinevoidput_user_byte(char val,char*addr)
36 __asm__("movb %0,%%fs:%1":/* no outputs */:"iq"(val),"m"(*addr));
39 #define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr))
41 staticinlinevoidput_user_word(short val,short* addr)
43 __asm__("movw %0,%%fs:%1":/* no outputs */:"ir"(val),"m"(*addr));
46 #define put_fs_word(x,addr) put_user_word((x),(short *)(addr))
48 staticinlinevoidput_user_long(unsigned long val,int* addr)
50 __asm__("movl %0,%%fs:%1":/* no outputs */:"ir"(val),"m"(*addr));
53 #define put_fs_long(x,addr) put_user_long((x),(int *)(addr))
55 staticinlinevoid__generic_memcpy_tofs(void* to,const void* from,unsigned long n)
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");
75 staticinlinevoid__constant_memcpy_tofs(void* to,const void* from,unsigned long n)
77 switch(n) {
78 case0:
79 return;
80 case1:
81 put_user_byte(*(const char*) from, (char*) to);
82 return;
83 case2:
84 put_user_word(*(const short*) from, (short*) to);
85 return;
86 case3:
87 put_user_word(*(const short*) from, (short*) to);
88 put_user_byte(*(2+(const char*) from),2+(char*) to);
89 return;
90 case4:
91 put_user_long(*(const int*) from, (int*) to);
92 return;
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" \
101 "pop %%es" \
102 :/* no outputs */ \
103 :"c" (n/4),"D" ((long) to),"S" ((long) from) \
104 :"cx","di","si")
106 switch(n %4) {
107 case0:
108 COMMON("");
109 return;
110 case1:
111 COMMON("movsb\n\t");
112 return;
113 case2:
114 COMMON("movsw\n\t");
115 return;
116 case3:
117 COMMON("movsw\n\tmovsb\n\t");
118 return;
120 #undef COMMON
123 staticinlinevoid__generic_memcpy_fromfs(void* to,const void* from,unsigned long n)
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");
139 staticinlinevoid__constant_memcpy_fromfs(void* to,const void* from,unsigned long n)
141 switch(n) {
142 case0:
143 return;
144 case1:
145 *(char*)to =get_user_byte((const char*) from);
146 return;
147 case2:
148 *(short*)to =get_user_word((const short*) from);
149 return;
150 case3:
151 *(short*) to =get_user_word((const short*) from);
152 *(char*) to =get_user_byte(2+(const char*) from);
153 return;
154 case4:
155 *(int*) to =get_user_long((const int*) from);
156 return;
158 #define COMMON(x) \
159 __asm__("cld\n\t" \
160 "rep ; fs ; movsl\n\t" \
162 :/* no outputs */ \
163 :"c" (n/4),"D" ((long) to),"S" ((long) from) \
164 :"cx","di","si","memory")
166 switch(n %4) {
167 case0:
168 COMMON("");
169 return;
170 case1:
171 COMMON("fs ; movsb");
172 return;
173 case2:
174 COMMON("fs ; movsw");
175 return;
176 case3:
177 COMMON("fs ; movsw\n\tfs ; movsb");
178 return;
180 #undef COMMON
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)))
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)))
194 * Someone who knows GNU asm better than I should double check the following.
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 ]
200 staticinlineunsigned longget_fs(void)
202 unsigned long _v;
203 __asm__("mov %%fs,%w0":"=r"(_v):"0"(0));
204 return _v;
207 staticinlineunsigned longget_ds(void)
209 unsigned long _v;
210 __asm__("mov %%ds,%w0":"=r"(_v):"0"(0));
211 return _v;
214 staticinlinevoidset_fs(unsigned long val)
216 __asm__ __volatile__("mov %w0,%%fs":/* no output */:"r"(val));
219 #endif/* _ASM_SEGMENT_H */
close