| 947 | }; |
| 948 | void common_fxsave(CPU* cpu, U32 address); |
| 949 | void writeToContext(KThread* thread, U32 stack, U32 context, bool altStack, U32 trapNo, U32 errorNo) { |
| 950 | CPU* cpu = thread->cpu; |
| 951 | KMemory* memory = thread->memory; |
| 952 | |
| 953 | if (altStack) { |
| 954 | memory->writed(context+0x8, thread->alternateStack); |
| 955 | memory->writed(context+0xC, K_SS_ONSTACK); |
| 956 | memory->writed(context+0x10, thread->alternateStackSize); |
| 957 | } else { |
| 958 | memory->writed(context+0x8, thread->alternateStack); |
| 959 | memory->writed(context+0xC, K_SS_DISABLE); |
| 960 | memory->writed(context+0x10, 0); |
| 961 | } |
| 962 | memory->writed(context+0x14, cpu->seg[GS].value); |
| 963 | memory->writed(context+0x18, cpu->seg[FS].value); |
| 964 | memory->writed(context+0x1C, cpu->seg[ES].value); |
| 965 | memory->writed(context+0x20, cpu->seg[DS].value); |
| 966 | memory->writed(context+0x24, cpu->reg[7].u32); // EDI |
| 967 | memory->writed(context+0x28, cpu->reg[6].u32); // ESI |
| 968 | memory->writed(context+0x2C, cpu->reg[5].u32); // EBP |
| 969 | memory->writed(context+0x30, stack); // ESP |
| 970 | memory->writed(context+0x34, cpu->reg[3].u32); // EBX |
| 971 | memory->writed(context+0x38, cpu->reg[2].u32); // EDX |
| 972 | memory->writed(context+0x3C, cpu->reg[1].u32); // ECX |
| 973 | memory->writed(context+0x40, cpu->reg[0].u32); // EAX |
| 974 | memory->writed(context+0x44, trapNo); // REG_TRAPNO |
| 975 | memory->writed(context+0x48, errorNo); // REG_ERR |
| 976 | memory->writed(context+0x4C, cpu->isBig()?cpu->eip.u32:cpu->eip.u16); |
| 977 | memory->writed(context+0x50, cpu->seg[CS].value); |
| 978 | memory->writed(context+0x54, cpu->flags); |
| 979 | memory->writed(context+0x58, 0); // REG_UESP |
| 980 | memory->writed(context+0x5C, cpu->seg[SS].value); |
| 981 | memory->writed(context+0x60, 0); // sigset_t uc_sigmask; |
| 982 | memory->writed(context+0x64, 0); // cr2 |
| 983 | memory->writed(context+0x68, context + 0x70); // fpu save state |
| 984 | // sizeof(struct _fpstate) = 624 (0x270) on 32-bit debian 11 |
| 985 | memory->writed(context+0x70, cpu->fpu.CW()); |
| 986 | memory->writed(context+0x74, cpu->fpu.SW()); |
| 987 | memory->writed(context+0x78, cpu->fpu.GetTag(cpu)); |
| 988 | memory->writed(context+0x7C, 0); |
| 989 | memory->writed(context+0x80, 0); |
| 990 | memory->writed(context+0x84, 0); |
| 991 | memory->writed(context+0x88, 0); |
| 992 | for (U32 i = 0; i < 8; i++) { |
| 993 | U32 address = context + 0x8C + i * 10; |
| 994 | cpu->fpu.ST80(cpu, address, cpu->fpu.STV(i)); |
| 995 | } |
| 996 | memory->writew(context + 0xDC, 0); // status |
| 997 | // magic :TODO: what should this value be, wine just checks if it has a value |
| 998 | // #define FPUX_sig(context) (FPU_sig(context) && !((context)->uc_mcontext.fpregs->status >> 16) ? (XSAVE_FORMAT *)(FPU_sig(context) + 1) : NULL) |
| 999 | memory->writew(context + 0xDE, 1); |
| 1000 | memory->memset(context + 0xE0, 0, 512); // wine will look for a magic number that we don't want to set. fpu->Reserved4)[12] == FP_XSTATE_MAGIC1 |
| 1001 | common_fxsave(cpu, context + 0xE0); |
| 1002 | } |
| 1003 | |
| 1004 | void common_fxrstor(CPU* cpu, U32 address); |
| 1005 | void readFromContext(CPU* cpu, U32 context) { |