Support to multi-threading and pthread interface (POSIX.1-2008) (#23)
[lunaix-os.git] / lunaix-os / arch / i386 / includes / sys / abi.h
1 #ifndef __LUNAIX_I386ABI_H
2 #define __LUNAIX_I386ABI_H
3
4 #include <sys/x86_isa.h>
5
6 #define stack_alignment 0xfffffff0
7
8 #ifndef __ASM__
9 #define align_stack(ptr) ((ptr) & stack_alignment)
10 #define store_retval(retval) current_thread->intr_ctx->registers.eax = (retval)
11
12 #define store_retval_to(th, retval) (th)->intr_ctx->registers.eax = (retval)
13
14 #define eret_target(th) (th)->intr_ctx->execp->eip
15 #define eret_stack(th) (th)->intr_ctx->execp->esp
16 #define intr_ivec(th) (th)->intr_ctx->execp->vector
17 #define intr_ierr(th) (th)->intr_ctx->execp->err_code
18
19 #define j_usr(sp, pc)                                                          \
20     asm volatile("movw %0, %%ax\n"                                             \
21                  "movw %%ax, %%es\n"                                           \
22                  "movw %%ax, %%ds\n"                                           \
23                  "movw %%ax, %%fs\n"                                           \
24                  "movw %%ax, %%gs\n"                                           \
25                  "pushl %0\n"                                                  \
26                  "pushl %1\n"                                                  \
27                  "pushl %2\n"                                                  \
28                  "pushl %3\n"                                                  \
29                  "retf" ::"i"(UDATA_SEG),                                      \
30                  "r"(sp),                                                      \
31                  "i"(UCODE_SEG),                                               \
32                  "r"(pc)                                                       \
33                  : "eax", "memory");
34
35
36 static inline void must_inline noret
37 switch_context() {
38     asm volatile("jmp do_switch\n");
39     unreachable;
40 }
41
42 #define push_arg1(stack_ptr, arg) *((typeof((arg))*)(stack_ptr)--) = arg
43 #define push_arg2(stack_ptr, arg1, arg2)                                       \
44     {                                                                          \
45         *((typeof((arg1))*)(stack_ptr)--) = arg1;                              \
46         *((typeof((arg2))*)(stack_ptr)--) = arg2;                              \
47     }
48 #define push_arg3(stack_ptr, arg1, arg2, arg3)                                 \
49     {                                                                          \
50         *((typeof((arg1))*)(stack_ptr)--) = arg1;                              \
51         *((typeof((arg2))*)(stack_ptr)--) = arg2;                              \
52         *((typeof((arg3))*)(stack_ptr)--) = arg3;                              \
53     }
54 #define push_arg4(stack_ptr, arg1, arg2, arg3, arg4)                           \
55     {                                                                          \
56         *((typeof((arg1))*)(stack_ptr)--) = arg1;                              \
57         *((typeof((arg2))*)(stack_ptr)--) = arg2;                              \
58         *((typeof((arg3))*)(stack_ptr)--) = arg3;                              \
59         *((typeof((arg4))*)(stack_ptr)--) = arg4;                              \
60     }
61
62
63 static inline ptr_t must_inline
64 abi_get_callframe()
65 {
66     ptr_t val;
67     asm("movl %%ebp, %0" : "=r"(val)::);
68     return val;
69 }
70
71 static inline ptr_t
72 abi_get_retaddr()
73 {
74     return *((ptr_t*)abi_get_callframe() + 1);
75 }
76
77 static inline ptr_t
78 abi_get_retaddrat(ptr_t fp)
79 {
80     return *((ptr_t*)fp + 1);
81 }
82 #endif
83 #endif /* __LUNAIX_ABI_H */