#ifndef _SEGMENT_H
#define _SEGMENT_H
#ifdef SEGMENT_C
#define inline
#endif
extern inline char get_fs_byte(const char *fs_addr)
{
register char v;
asm ("movb %%fs:%1, %0" : "=q" (v) : "m" (*fs_addr));
return v;
}
extern inline short get_fs_word(const short *fs_addr)
{
register short v;
asm ("movw %%fs:%1, %0" : "=q" (v) : "m" (*fs_addr));
return v;
}
extern inline long get_fs_long(const long *fs_addr)
{
register long v;
asm ("movl %%fs:%1, %0" : "=q" (v) : "m" (*fs_addr));
return v;
}
extern inline void put_fs_byte(char val, char *fs_addr)
{
asm volatile ("movb %0, %%fs:%1" :: "q" (val), "m" (*fs_addr) : "memory");
}
extern inline void put_fs_word(short val, short *fs_addr)
{
asm volatile ("movw %0, %%fs:%1" :: "q" (val), "m" (*fs_addr) : "memory");
}
extern inline void put_fs_long(long val, long *fs_addr)
{
asm volatile ("movl %0, %%fs:%1" :: "q" (val), "m" (*fs_addr) : "memory");
}
extern inline void *memcpy_tofs(void *fs_dest, const void *src, unsigned int n)
{
int d0, d1, d2;
asm volatile ("push %%es\n\t"
"push %%fs\n\t"
"pop %%es\n\t"
"cld\n\t"
"rep\n\t"
"movsl\n\t"
"testb $2, %b4\n\t"
"je 1f\n\t"
"movsw\n"
"1:\ttestb $1, %b4\n\t"
"je 2f\n\t"
"movsb\n"
"2:\tpop %%es"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
: "0" (n / 4), "q" (n), "1" (fs_dest), "2" (src)
: "cc", "memory");
return fs_dest;
}
extern inline void *memcpy_fromfs(void *dest, const void *fs_src, unsigned int n)
{
int d0, d1, d2;
asm volatile ("cld\n\t"
"rep\n\t"
"fs\n\t"
"movsl\n\t"
"testb $2, %b4\n\t"
"je 1f\n\t"
"fs\n\t"
"movsw\n"
"1:\ttestb $1, %b4\n\t"
"je 2f\n\t"
"fs\n\t"
"movsb\n"
"2:"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
: "0" (n / 4), "q" (n), "1" (dest), "2" (fs_src)
: "cc", "memory");
return dest;
}
extern inline void *memset_tofs(void *fs_s, int c, unsigned int n)
{
int d0, d1;
asm volatile ("push %%es\n\t"
"push %%fs\n\t"
"pop %%es\n\t"
"cld\n\t"
"rep\n\t"
"stosb\n\t"
"pop %%es"
: "=&c" (d0), "=&D" (d1)
: "a" (c), "1" (fs_s), "0" (n)
: "cc", "memory");
return fs_s;
}
extern inline void *strncpy_tofs(char *fs_dest, const char *src, unsigned int n)
{
int d0, d1, d2, d3;
asm volatile ("push %%es\n\t"
"push %%fs\n\t"
"pop %%es\n\t"
"cld\n"
"1:\tdecl %2\n\t"
"js 2f\n\t"
"lodsb\n\t"
"stosb\n\t"
"testb %%al, %%al\n\t"
"jne 1b\n\t"
"rep\n\t"
"stosb\n"
"2:\tpop %%es"
: "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
: "0" (src), "1" (fs_dest), "2" (n)
: "cc", "memory");
return fs_dest;
}
#undef inline
#endif