3 /* This was taken from Mingw32's winnt.h */
6 #define CONTEXT_AMD64 0x100000
8 #define CONTEXT_CONTROL (CONTEXT_AMD64 | 0x1L)
9 #define CONTEXT_INTEGER (CONTEXT_AMD64 | 0x2L)
10 #define CONTEXT_SEGMENTS (CONTEXT_AMD64 | 0x4L)
11 #define CONTEXT_FLOATING_POINT (CONTEXT_AMD64 | 0x8L)
12 #define CONTEXT_DEBUG_REGISTERS (CONTEXT_AMD64 | 0x10L)
13 #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
14 #define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS)
22 typedef struct _XMM_SAVE_AREA32
37 M128A FloatRegisters
[8];
38 M128A XmmRegisters
[16];
42 typedef struct _CONTEXT
83 XMM_SAVE_AREA32 FltSave
;
105 M128A VectorRegister
[26];
108 IPTR LastBranchToRip
;
109 IPTR LastBranchFromRip
;
110 IPTR LastExceptionToRip
;
111 IPTR LastExceptionFromRip
;
116 M128A VectorRegister
[26];
119 IPTR LastBranchToRip
;
120 IPTR LastBranchFromRip
;
121 IPTR LastExceptionToRip
;
122 IPTR LastExceptionFromRip
;
125 /* Complete context frame, with Windows private data */
126 struct AROSCPUContext
128 struct ExceptionContext regs
; /* Public portion */
129 IPTR PHome
[6]; /* Some Windows-specific data */
130 struct VectorContext vec
;
131 ULONG LastError
; /* LastError code */
135 * Common part of SAVEREGS and TRAP_SAVEREGS.
136 * Saves CPU registers from CONTEXT in struct ExceptionContext.
138 #define SAVE_CPU(regs, ctx) \
140 ctx.rax = regs->Rax; \
141 ctx.rbx = regs->Rbx; \
142 ctx.rcx = regs->Rcx; \
143 ctx.rdx = regs->Rdx; \
144 ctx.rsi = regs->Rsi; \
145 ctx.rdi = regs->Rdi; \
148 ctx.r10 = regs->R10; \
149 ctx.r11 = regs->R11; \
150 ctx.r12 = regs->R12; \
151 ctx.r13 = regs->R13; \
152 ctx.r14 = regs->R14; \
153 ctx.r15 = regs->R15; \
154 ctx.rbp = regs->Rbp; \
155 ctx.rip = regs->Rip; \
156 ctx.rflags = regs->EFlags; \
157 ctx.rsp = regs->Rsp; \
158 if (regs->ContextFlags & CONTEXT_SEGMENTS) \
160 ctx.Flags |= ECF_SEGMENTS; \
161 ctx.ds = regs->SegDs; \
162 ctx.es = regs->SegEs; \
163 ctx.fs = regs->SegFs; \
164 ctx.gs = regs->SegGs; \
165 ctx.cs = regs->SegCs; \
166 ctx.ss = regs->SegSs; \
170 * Restore CPU registers.
171 * Does not restore segment registers because they are of private use
172 * by Windows. We can't modify them.
174 #define RESTORE_CPU(regs, ctx) \
175 regs->ContextFlags = CONTEXT_CONTROL|CONTEXT_INTEGER; \
176 regs->Rax = ctx.rax; \
177 regs->Rbx = ctx.rbx; \
178 regs->Rcx = ctx.rcx; \
179 regs->Rdx = ctx.rdx; \
180 regs->Rsi = ctx.rsi; \
181 regs->Rdi = ctx.rdi; \
184 regs->R10 = ctx.r10; \
185 regs->R11 = ctx.r11; \
186 regs->R12 = ctx.r12; \
187 regs->R13 = ctx.r13; \
188 regs->R14 = ctx.r14; \
189 regs->R15 = ctx.r15; \
190 regs->Rbp = ctx.rbp; \
191 regs->Rip = ctx.rip; \
192 regs->EFlags = ctx.rflags; \
196 * Save the whole set of registers in the allocated context space.
197 * Also saves FPU and SSE, if available.
199 #define SAVEREGS(regs, ctx) \
200 SAVE_CPU(regs, ctx->regs); \
201 if (regs->ContextFlags & CONTEXT_FLOATING_POINT) \
203 ctx->regs.Flags |= ECF_FPX; \
204 CopyMemQuick(®s->FltSave, ctx->regs.FXData, sizeof(XMM_SAVE_AREA32)); \
206 CopyMemQuick(®s->P1Home, ctx->PHome, 6 * sizeof(IPTR)); \
207 CopyMemQuick(regs->VectorRegister, &ctx->vec, sizeof(struct VectorContext));
210 * Restore complete set of registers.
211 * Restores SSE only if the corresponding flag is set in struct ExceptionContext.
213 #define RESTOREREGS(regs, ctx) \
214 RESTORE_CPU(regs, ctx->regs); \
215 if (ctx->regs.Flags & ECF_FPX) \
217 regs->ContextFlags |= CONTEXT_FLOATING_POINT; \
218 CopyMemQuick(ctx->regs.FXData, ®s->FltSave, sizeof(XMM_SAVE_AREA32)); \
219 regs->MxCsr = regs->FltSave.MxCsr; \
221 CopyMemQuick(ctx->PHome, ®s->P1Home, 6 * sizeof(IPTR)); \
222 CopyMemQuick(&ctx->vec, regs->VectorRegister, sizeof(struct VectorContext));
225 * Similar to SAVEREGS and RESTOREREGS, but actually copies only public CPU part.
226 * SSE frame is specified by reference (frames format in host and AROS match).
227 * This is for use within trap handling code.
229 #define TRAP_SAVEREGS(src, dest) \
230 SAVE_CPU(src, dest) \
231 if (src->ContextFlags & CONTEXT_FLOATING_POINT) \
233 dest.Flags |= ECF_FPX; \
234 dest.FXData = &src->FltSave; \
237 #define TRAP_RESTOREREGS(dest, src) \
238 RESTORE_CPU(dest, src); \
239 if (src.Flags & ECF_FPX) \
241 dest->ContextFlags |= CONTEXT_FLOATING_POINT; \
242 dest->MxCsr = dest->FltSave.MxCsr; \
246 * Realign and copy FPU portion from src to dest. It is supposed
247 * that common part is already copied.
249 #define COPY_FPU(src, dest) \
250 if ((src)->Flags & ECF_FPX) \
252 IPTR fpdata = (IPTR)(dest) + sizeof(struct AROSCPUContext); \
253 fpdata = (fpdata + 15) & ~15; \
254 (dest)->FXData = (struct FPXContext *)fpdata; \
255 CopyMemQuick((src)->FXData, (dest)->FXData, sizeof(struct FPXContext)); \
258 (dest)->FXData = NULL;
260 #define GET_SP(ctx) (void *)ctx->regs.rsp
262 #define EXCEPTIONS_COUNT 18
264 #define PRINT_CPUCONTEXT(ctx) \
265 bug (" ContextFlags: 0x%08lX\n" \
266 " RSP=%016lx RBP=%016lx RIP=%016lx\n" \
267 " RAX=%016lx RBX=%016lx RCX=%016lx RDX=%016lx\n" \
268 " R08=%016lx R09=%016lx R10=%016lx R11=%016lx\n" \
269 " R12=%016lx R13=%016lx R14=%016lx R15=%016lx\n" \
270 " RDI=%016lx RSI=%016lx EFLAGS=%08lx\n" \
271 , (ctx)->ContextFlags \
272 , (ctx)->Rsp, (ctx)->Rbp, (ctx)->Rip \
273 , (ctx)->Rax, (ctx)->Rbx, (ctx)->Rcx, (ctx)->Rdx \
274 , (ctx)->R8 , (ctx)->R9 , (ctx)->R10, (ctx)->R11 \
275 , (ctx)->R12, (ctx)->R13, (ctx)->R14, (ctx)->R15 \
276 , (ctx)->Rdi, (ctx)->Rsi, (ctx)->EFlags \
281 #define PRINT_CPUCONTEXT(ctx) \
282 printf(" ContextFlags: 0x%08lX\n" \
283 " RSP=%016I64x RBP=%016I64x RIP=%016I64x\n" \
284 " RAX=%016I64x RBX=%016I64x RCX=%016I64x RDX=%016I64x\n" \
285 " R08=%016I64x R09=%016I64x R10=%016I64x R11=%016I64x\n" \
286 " R12=%016I64x R13=%016I64x R14=%016I64x R15=%016I64x\n" \
287 " RDI=%016I64x RSI=%016I64x EFLAGS=%08lx\n" \
288 , (ctx)->ContextFlags \
289 , (ctx)->Rsp, (ctx)->Rbp, (ctx)->Rip \
290 , (ctx)->Rax, (ctx)->Rbx, (ctx)->Rcx, (ctx)->Rdx \
291 , (ctx)->R8 , (ctx)->R9 , (ctx)->R10, (ctx)->R11 \
292 , (ctx)->R12, (ctx)->R13, (ctx)->R14, (ctx)->R15 \
293 , (ctx)->Rdi, (ctx)->Rsi, (ctx)->EFlags \
296 #endif /* __AROS__ */
298 #define CONTEXT_INIT_FLAGS(ctx) (ctx)->ContextFlags = CONTEXT_ALL
300 #define PC(regs) regs->Rip
301 #define R0(regs) regs->Rax