#pragma once #include #include struct arch_task_context { uint64_t rsp; uint8_t* fpu_region; uint16_t ds, es, fs, gs; uint64_t fs_base, gs_base; }; #define ARCH_ABI(typ, reg, ...) \ union { \ typ reg, __VA_ARGS__; \ } struct arch_context { uint64_t r15; uint64_t r14; ARCH_ABI(uint64_t, r13, a7); ARCH_ABI(uint64_t, r12, a6); uint64_t r11; ARCH_ABI(uint64_t, r10, a5); ARCH_ABI(uint64_t, r9, a3); ARCH_ABI(uint64_t, r8, a4); ARCH_ABI(uint64_t, rsi, a1); ARCH_ABI(uint64_t, rdi, a0); uint64_t rbp; ARCH_ABI(uint64_t, rdx, a2, ret1); uint64_t rcx; uint64_t rbx; ARCH_ABI(uint64_t, rax, num, ret0); uint64_t isr; // Pushed onto the stack by the interrupt handler stubs. uint64_t error; // Pushed onto the stack by the CPU if the interrupt has an error code. uint64_t rip; // The rest is pushed onto the stack by the CPU during an interrupt. uint64_t cs; uint64_t rflags; uint64_t rsp; uint64_t ss; }; static_assert(sizeof(struct arch_context) == 22 * sizeof(uint64_t)); #define ARCH_CTX_NUM rax #define ARCH_CTX_A0 rdi #define ARCH_CTX_A1 rsi #define ARCH_CTX_A2 rdx #define ARCH_CTX_A3 r9 #define ARCH_CTX_A4 r8 #define ARCH_CTX_A5 r10 #define ARCH_CTX_A6 r12 #define ARCH_CTX_A7 r13 #define ARCH_CTX_RET0 rax #define ARCH_CTX_RET1 rdx