/* Copyright (C) 2008 Emmanuel Varoquaux This file is part of XOS. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #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