+// Low level macros for reading/writing memory via a segment selector.
+#define READ8_SEG(prefix, SEG, value, var) \
+ __asm__(prefix "movb %%" #SEG ":%1, %b0" : "=Qi"(value) \
+ : "m"(var), "m"(__segment_ ## SEG))
+#define READ16_SEG(prefix, SEG, value, var) \
+ __asm__(prefix "movw %%" #SEG ":%1, %w0" : "=ri"(value) \
+ : "m"(var), "m"(__segment_ ## SEG))
+#define READ32_SEG(prefix, SEG, value, var) \
+ __asm__(prefix "movl %%" #SEG ":%1, %0" : "=ri"(value) \
+ : "m"(var), "m"(__segment_ ## SEG))
+#define READ64_SEG(prefix, SEG, value, var) do { \
+ union u64_u32_u __value; \
+ union u64_u32_u *__r64_ptr = (union u64_u32_u *)&(var); \
+ READ32_SEG(prefix, SEG, __value.hi, __r64_ptr->hi); \
+ READ32_SEG(prefix, SEG, __value.lo, __r64_ptr->lo); \
+ *(u64*)&(value) = __value.val; \
+ } while (0)
+#define WRITE8_SEG(prefix, SEG, var, value) \
+ __asm__(prefix "movb %b1, %%" #SEG ":%0" : "=m"(var) \
+ : "Q"(value), "m"(__segment_ ## SEG))
+#define WRITE16_SEG(prefix, SEG, var, value) \
+ __asm__(prefix "movw %w1, %%" #SEG ":%0" : "=m"(var) \
+ : "r"(value), "m"(__segment_ ## SEG))
+#define WRITE32_SEG(prefix, SEG, var, value) \
+ __asm__(prefix "movl %1, %%" #SEG ":%0" : "=m"(var) \
+ : "r"(value), "m"(__segment_ ## SEG))
+#define WRITE64_SEG(prefix, SEG, var, value) do { \
+ union u64_u32_u __value; \
+ union u64_u32_u *__w64_ptr = (union u64_u32_u *)&(var); \
+ typeof(var) __value_tmp = (value); \
+ __value.val = *(u64*)&__value_tmp; \
+ WRITE32_SEG(prefix, SEG, __w64_ptr->hi, __value.hi); \
+ WRITE32_SEG(prefix, SEG, __w64_ptr->lo, __value.lo); \
+ } while (0)