Initial checkin.
[people/mcb30/legacybios.git] / src / farptr.h
1 // Code to access multiple segments within gcc.
2 //
3 // Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
4 //
5 // This file may be distributed under the terms of the GNU GPLv3 license.
6
7 #define READ8_SEG(SEG, var) ({                                          \
8     u8 __value;                                                         \
9     __asm__ __volatile__("movb %%" #SEG ":%1, %b0"                      \
10                          : "=Qi"(__value) : "m"(var));                  \
11     __value; })
12 #define READ16_SEG(SEG, var) ({                                         \
13     u16 __value;                                                        \
14     __asm__ __volatile__("movw %%" #SEG ":%1, %w0"                      \
15                          : "=ri"(__value) : "m"(var));                  \
16     __value; })
17 #define READ32_SEG(SEG, var) ({                                         \
18     u32 __value;                                                        \
19     __asm__ __volatile__("movl %%" #SEG ":%1, %0"                       \
20                          : "=ri"(__value) : "m"(var));                  \
21     __value; })
22 #define WRITE8_SEG(SEG, var, value)                     \
23     __asm__ __volatile__("movb %b0, %%" #SEG ":%1"      \
24                          : : "Q"(value), "m"(var))
25 #define WRITE16_SEG(SEG, var, value)                    \
26     __asm__ __volatile__("movw %w0, %%" #SEG ":%1"      \
27                          : : "r"(value), "m"(var))
28 #define WRITE32_SEG(SEG, var, value)                    \
29     __asm__ __volatile__("movl %0, %%" #SEG ":%1"       \
30                          : : "r"(value), "m"(var))
31
32 #define GET_VAR(seg, var) ({                                    \
33     typeof(var) __val;                                          \
34     if (__builtin_types_compatible_p(typeof(__val), u8))        \
35         __val = READ8_SEG(seg, var);                            \
36     else if (__builtin_types_compatible_p(typeof(__val), u16))  \
37         __val = READ16_SEG(seg, var);                           \
38     else if (__builtin_types_compatible_p(typeof(__val), u32))  \
39         __val = READ32_SEG(seg, var);                           \
40     __val; })
41
42 #define SET_VAR(seg, var, val) do {                               \
43         if (__builtin_types_compatible_p(typeof(var), u8))        \
44             WRITE8_SEG(seg, var, (val));                          \
45         else if (__builtin_types_compatible_p(typeof(var), u16))  \
46             WRITE16_SEG(seg, var, (val));                         \
47         else if (__builtin_types_compatible_p(typeof(var), u32))  \
48             WRITE32_SEG(seg, var, (val));                         \
49     } while (0)
50
51 #define SET_SEG(SEG, value)                                     \
52     __asm__ __volatile__("movw %w0, %%" #SEG : : "r"(value))
53 #define GET_SEG(SEG) ({                                         \
54     u16 __seg;                                                  \
55     __asm__ __volatile__("movw %%" #SEG ", %w0" : "=r"(__seg)); \
56     __seg;})
57