diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 27617d1..11d0815 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -1348,6 +1348,13 @@ void exec386_dynarec(int cycs) valid_block = 0; } } + if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) + { + /*FPU top-of-stack does not match the value this block was compiled + with, re-compile using dynamic top-of-stack*/ + block->flags &= ~CODEBLOCK_STATIC_TOP; + block->was_recompiled = 0; + } } if (valid_block && block->was_recompiled) diff --git a/src/codegen.h b/src/codegen.h index b178778..3f3f38d 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -56,10 +56,17 @@ typedef struct codeblock_t uint64_t page_mask, page_mask2; int was_recompiled; + uint32_t flags; + int TOP; uint8_t data[2048]; } codeblock_t; +/*Code block uses FPU*/ +#define CODEBLOCK_HAS_FPU 1 +/*Code block is always entered with the same FPU top-of-stack*/ +#define CODEBLOCK_STATIC_TOP 2 + static inline codeblock_t *codeblock_tree_find(uint32_t phys) { codeblock_t *block = pages[phys >> 12].head; diff --git a/src/codegen_ops_x86.h b/src/codegen_ops_x86.h index 34992cd..24287e6 100644 --- a/src/codegen_ops_x86.h +++ b/src/codegen_ops_x86.h @@ -1838,427 +1838,642 @@ static void FP_ENTER() static void FP_FLD(int reg) { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte(cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (reg) + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); + addbyte(0xf3); /*MOVQ XMM0, ST[reg][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x45); + addbyte(cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte(cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0xf3); /*MOVQ XMM1, MM[reg][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x4d); + addbyte(cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); + addbyte(0x66); /*MOVQ ST[-1][EBP], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x45); + addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + addbyte(0x8a); /*MOV AL, tag[reg][EBP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); + addbyte(0x66); /*MOVQ MM[-1][EBP], XMM1*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x4d); + addbyte(cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); + addbyte(0x88); /*MOV tag[-1][EBP], AL*/ + addbyte(0x45); + addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); } else { - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - } + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + if (reg) + { + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(0x07); + } + else + { + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + } - addbyte(0xdd); /*FLD [ST+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte(cpu_state_offset(ST)); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(0x07); - addbyte(0x8b); /*MOV EDX, [ST_i64+EAX]*/ - addbyte(0x54); - addbyte(0xc5); - addbyte(cpu_state_offset(MM)); - addbyte(0x8b); /*MOV ECX, [ST_i64+4+EAX]*/ - addbyte(0x4c); - addbyte(0xc5); - addbyte(cpu_state_offset(MM)+4); - addbyte(0x8a); /*MOV AL, [tag+EAX]*/ - addbyte(0x44); - addbyte(0x05); - addbyte(cpu_state_offset(tag[0])); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - addbyte(0x88); /*MOV [tag+EBX], AL*/ - addbyte(0x44); - addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); - addbyte(0x89); /*MOV [ST_i64+EBX], EDX*/ - addbyte(0x54); - addbyte(0xdd); - addbyte(cpu_state_offset(MM)); - addbyte(0x89); /*MOV [ST_i64+EBX+4], ECX*/ - addbyte(0x4c); - addbyte(0xdd); - addbyte(cpu_state_offset(MM)+4); + addbyte(0xdd); /*FLD [ST+EAX*8]*/ + addbyte(0x44); + addbyte(0xc5); + addbyte(cpu_state_offset(ST)); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(0x07); + addbyte(0x8b); /*MOV EDX, [ST_i64+EAX]*/ + addbyte(0x54); + addbyte(0xc5); + addbyte(cpu_state_offset(MM)); + addbyte(0x8b); /*MOV ECX, [ST_i64+4+EAX]*/ + addbyte(0x4c); + addbyte(0xc5); + addbyte(cpu_state_offset(MM)+4); + addbyte(0x8a); /*MOV AL, [tag+EAX]*/ + addbyte(0x44); + addbyte(0x05); + addbyte(cpu_state_offset(tag[0])); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + addbyte(0x88); /*MOV [tag+EBX], AL*/ + addbyte(0x44); + addbyte(0x1d); + addbyte(cpu_state_offset(tag[0])); + addbyte(0x89); /*MOV [ST_i64+EBX], EDX*/ + addbyte(0x54); + addbyte(0xdd); + addbyte(cpu_state_offset(MM)); + addbyte(0x89); /*MOV [ST_i64+EBX+4], ECX*/ + addbyte(0x4c); + addbyte(0xdd); + addbyte(cpu_state_offset(MM)+4); - addbyte(0x89); /*MOV [TOP], EBX*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [TOP], EBX*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + } } static void FP_FST(int reg) { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte(cpu_state_offset(TOP)); - addbyte(0xdd); /*FLD [ST+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte(cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [tag+EAX]*/ - addbyte(0x5c); - addbyte(0x05); - addbyte(cpu_state_offset(tag[0])); - - if (reg) + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); + addbyte(0xf3); /*MOVQ XMM0, ST[0][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x45); + addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x8a); /*MOV AL, tag[0][EBP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte(0x66); /*MOVQ ST[reg][EBP], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x45); + addbyte(cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + addbyte(0x88); /*MOV tag[reg][EBP], AL*/ + addbyte(0x45); + addbyte(cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); } + else + { + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(TOP)); + addbyte(0xdd); /*FLD [ST+EAX*8]*/ + addbyte(0x44); + addbyte(0xc5); + addbyte(cpu_state_offset(ST)); + addbyte(0x8a); /*MOV BL, [tag+EAX]*/ + addbyte(0x5c); + addbyte(0x05); + addbyte(cpu_state_offset(tag[0])); - addbyte(0xdd); /*FSTP [ST+EAX*8]*/ - addbyte(0x5c); - addbyte(0xc5); - addbyte(cpu_state_offset(ST)); - addbyte(0x88); /*MOV [tag+EAX], BL*/ - addbyte(0x5c); - addbyte(0x05); - addbyte(cpu_state_offset(tag[0])); + if (reg) + { + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(0x07); + } + + addbyte(0xdd); /*FSTP [ST+EAX*8]*/ + addbyte(0x5c); + addbyte(0xc5); + addbyte(cpu_state_offset(ST)); + addbyte(0x88); /*MOV [tag+EAX], BL*/ + addbyte(0x5c); + addbyte(0x05); + addbyte(cpu_state_offset(tag[0])); + } } static void FP_FXCH(int reg) { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte(cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); -//#if 0 - addbyte(0xdd); /*FLD [ST+EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - addbyte(0xdd); /*FLD [ST+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte(cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP [ST+EAX*8]*/ - addbyte(0x5c); - addbyte(0xc5); - addbyte(cpu_state_offset(ST)); -// addbyte(0xbe); /*MOVL ESI, tag*/ -// addlong((uintptr_t)cpu_state.tag); - addbyte(0x8a); /*MOV CL, tag[EAX]*/ - addbyte(0x4c); - addbyte(0x05); - addbyte(cpu_state_offset(tag[0])); - addbyte(0x8a); /*MOV DL, tag[EBX]*/ - addbyte(0x54); - addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); - addbyte(0x88); /*MOV tag[EBX], CL*/ - addbyte(0x4c); - addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); - addbyte(0x88); /*MOV tag[EAX], DL*/ - addbyte(0x54); - addbyte(0x05); - addbyte(cpu_state_offset(tag[0])); - addbyte(0xbe); /*MOVL ESI, ST_int64*/ - addlong((uintptr_t)cpu_state.MM); - addbyte(0x8b); /*MOV ECX, ST_int64[EAX*8]*/ - addbyte(0x0c); - addbyte(0xc6); - addbyte(0x8b); /*MOV EDX, ST_int64[EBX*8]*/ - addbyte(0x14); - addbyte(0xde); - addbyte(0x89); /*MOV ST_int64[EBX*8], ECX*/ - addbyte(0x0c); - addbyte(0xde); - addbyte(0x89); /*MOV ST_int64[EAX*8], EDX*/ - addbyte(0x14); - addbyte(0xc6); - addbyte(0x8b); /*MOV ECX, ST_int64[EAX*8]+4*/ - addbyte(0x4c); - addbyte(0xc6); - addbyte(0x04); - addbyte(0x8b); /*MOV EDX, ST_int64[EBX*8]+4*/ - addbyte(0x54); - addbyte(0xde); - addbyte(0x04); - addbyte(0x89); /*MOV ST_int64[EBX*8]+4, ECX*/ - addbyte(0x4c); - addbyte(0xde); - addbyte(0x04); - addbyte(0x89); /*MOV ST_int64[EAX*8]+4, EDX*/ - addbyte(0x54); - addbyte(0xc6); - addbyte(0x04); - reg = reg; -//#endif -#if 0 - addbyte(0xbe); /*MOVL ESI, ST*/ - addlong((uintptr_t)cpu_state.ST); - - addbyte(0x8b); /*MOVL EDX, [ESI+EBX*8]*/ - addbyte(0x14); - addbyte(0xde); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - addbyte(0x8b); /*MOVL ECX, [ESI+EAX*8]*/ - addbyte(0x0c); - addbyte(0xc6); - addbyte(0x89); /*MOVL [ESI+EBX*8], ECX*/ - addbyte(0x0c); - addbyte(0xde); - addbyte(0x89); /*MOVL [ESI+EAX*8], EDX*/ - addbyte(0x14); - addbyte(0xc6); + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) + { + addbyte(0xf3); /*MOVQ XMM0, ST[0][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x45); + addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0xf3); /*MOVQ XMM1, ST[reg][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x4d); + addbyte(cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + addbyte(0x66); /*MOVQ ST[reg][EBP], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x45); + addbyte(cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + addbyte(0xf3); /*MOVQ XMM2, MM[0][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x55); + addbyte(cpu_state_offset(MM[cpu_state.TOP].q)); + addbyte(0x66); /*MOVQ ST[0][EBP], XMM1*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x4d); + addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0xf3); /*MOVQ XMM3, MM[reg][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x5d); + addbyte(cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); + addbyte(0x66); /*MOVQ MM[reg][EBP], XMM2*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x55); + addbyte(cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); + addbyte(0x8a); /*MOV AL, tag[0][EBP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte(0x66); /*MOVQ MM[0][EBP], XMM3*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x5d); + addbyte(cpu_state_offset(MM[cpu_state.TOP].q)); + addbyte(0x8a); /*MOV AH, tag[reg][EBP]*/ + addbyte(0x65); + addbyte(cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); + addbyte(0x88); /*MOV tag[reg][EBP], AL*/ + addbyte(0x45); + addbyte(cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); + addbyte(0x88); /*MOV tag[0][EBP], AH*/ + addbyte(0x65); + addbyte(cpu_state_offset(tag[cpu_state.TOP])); + } + else + { + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); - addbyte(0x8b); /*MOVL ECX, [4+ESI+EAX*8]*/ - addbyte(0x4c); - addbyte(0xc6); - addbyte(0x04); - addbyte(0x8b); /*MOVL EDX, [4+ESI+EBX*8]*/ - addbyte(0x54); - addbyte(0xde); - addbyte(0x04); - addbyte(0x89); /*MOVL [4+ESI+EBX*8], ECX*/ - addbyte(0x4c); - addbyte(0xde); - addbyte(0x04); - addbyte(0x89); /*MOVL [4+ESI+EAX*8], EDX*/ - addbyte(0x54); - addbyte(0xc6); - addbyte(0x04); -#endif + addbyte(0xdd); /*FLD [ST+EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(0x07); + addbyte(0xdd); /*FLD [ST+EAX*8]*/ + addbyte(0x44); + addbyte(0xc5); + addbyte(cpu_state_offset(ST)); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + addbyte(0xdd); /*FSTP [ST+EAX*8]*/ + addbyte(0x5c); + addbyte(0xc5); + addbyte(cpu_state_offset(ST)); + addbyte(0x8a); /*MOV CL, tag[EAX]*/ + addbyte(0x4c); + addbyte(0x05); + addbyte(cpu_state_offset(tag[0])); + addbyte(0x8a); /*MOV DL, tag[EBX]*/ + addbyte(0x54); + addbyte(0x1d); + addbyte(cpu_state_offset(tag[0])); + addbyte(0x88); /*MOV tag[EBX], CL*/ + addbyte(0x4c); + addbyte(0x1d); + addbyte(cpu_state_offset(tag[0])); + addbyte(0x88); /*MOV tag[EAX], DL*/ + addbyte(0x54); + addbyte(0x05); + addbyte(cpu_state_offset(tag[0])); + addbyte(0xbe); /*MOVL ESI, ST_int64*/ + addlong((uintptr_t)cpu_state.MM); + addbyte(0x8b); /*MOV ECX, ST_int64[EAX*8]*/ + addbyte(0x0c); + addbyte(0xc6); + addbyte(0x8b); /*MOV EDX, ST_int64[EBX*8]*/ + addbyte(0x14); + addbyte(0xde); + addbyte(0x89); /*MOV ST_int64[EBX*8], ECX*/ + addbyte(0x0c); + addbyte(0xde); + addbyte(0x89); /*MOV ST_int64[EAX*8], EDX*/ + addbyte(0x14); + addbyte(0xc6); + addbyte(0x8b); /*MOV ECX, ST_int64[EAX*8]+4*/ + addbyte(0x4c); + addbyte(0xc6); + addbyte(0x04); + addbyte(0x8b); /*MOV EDX, ST_int64[EBX*8]+4*/ + addbyte(0x54); + addbyte(0xde); + addbyte(0x04); + addbyte(0x89); /*MOV ST_int64[EBX*8]+4, ECX*/ + addbyte(0x4c); + addbyte(0xde); + addbyte(0x04); + addbyte(0x89); /*MOV ST_int64[EAX*8]+4, EDX*/ + addbyte(0x54); + addbyte(0xc6); + addbyte(0x04); + } } static void FP_LOAD_S() { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0xd9); /*FLD [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x83); /*CMP EAX, 0*/ - addbyte(0xf8); - addbyte(0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) + { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x85); /*TEST EAX, EAX*/ + addbyte(0xc0); + addbyte(0xd9); /*FLD [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte(cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0x0f); /*SETE tag[reg][EBP]*/ + addbyte(0x94); + addbyte(0x45); + addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte(0xdd); /*FSTP ST[reg][EBP]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + block_current = block_current; + } + else + { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0xd9); /*FLD [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x85); /*TEST EAX, EAX*/ + addbyte(0xc0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte(cpu_state_offset(tag[0])); + } } static void FP_LOAD_D() { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0x09); /*OR EAX, EDX*/ - addbyte(0xd0); - addbyte(0xdd); /*FLD [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x83); /*CMP EAX, 0*/ - addbyte(0xf8); - addbyte(0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) + { + addbyte(0x89); /*MOV ST[reg][EBP], EAX*/ + addbyte(0x45); + addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + addbyte(0x09); /*OR EAX, EDX*/ + addbyte(0xd0); + addbyte(0x89); /*MOV ST[reg][EBP]+4, EDX*/ + addbyte(0x55); + addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]) + 4); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte(cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0x0f); /*SETE tag[reg][EBP]*/ + addbyte(0x94); + addbyte(0x45); + addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + } + else + { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0x09); /*OR EAX, EDX*/ + addbyte(0xd0); + addbyte(0xdd); /*FLD [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x83); /*CMP EAX, 0*/ + addbyte(0xf8); + addbyte(0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte(cpu_state_offset(tag[0])); + } } static void FP_LOAD_IW() { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0xdf); /*FILDw [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x83); /*CMP EAX, 0*/ - addbyte(0xf8); - addbyte(0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) + { + addbyte(0x66); /*MOV [ESP], AX*/ + addbyte(0x89); + addbyte(0x04); + addbyte(0x24); + addbyte(0x66); /*TEST AX, AX*/ + addbyte(0x85); + addbyte(0xc0); + addbyte(0xdf); /*FILDw [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte(cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0x0f); /*SETE tag[reg][EBP]*/ + addbyte(0x94); + addbyte(0x45); + addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte(0xdd); /*FSTP ST[reg][EBP]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + } + else + { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0xdf); /*FILDw [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x83); /*CMP EAX, 0*/ + addbyte(0xf8); + addbyte(0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte(cpu_state_offset(tag[0])); + } } static void FP_LOAD_IL() { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0xdb); /*FILDl [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x83); /*CMP EAX, 0*/ - addbyte(0xf8); - addbyte(0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) + { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x85); /*TEST EAX, EAX*/ + addbyte(0xc0); + addbyte(0xdb); /*FILDl [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte(cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0x0f); /*SETE tag[reg][EBP]*/ + addbyte(0x94); + addbyte(0x45); + addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte(0xdd); /*FSTP ST[reg][EBP]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + } + else + { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0xdb); /*FILDl [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x83); /*CMP EAX, 0*/ + addbyte(0xf8); + addbyte(0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte(cpu_state_offset(tag[0])); + } } static void FP_LOAD_IQ() { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x89); /*MOV [ST_i64+EBX*8], EAX*/ - addbyte(0x44); - addbyte(0xdd); - addbyte(cpu_state_offset(MM)); - addbyte(0x09); /*OR EAX, EDX*/ - addbyte(0xd0); - addbyte(0x89); /*MOV [ST_i64+4+EBX*8], EDX*/ - addbyte(0x54); - addbyte(0xdd); - addbyte(cpu_state_offset(MM)+4); - addbyte(0x83); /*CMP EAX, 0*/ - addbyte(0xf8); - addbyte(0); - addbyte(0xdf); /*FILDl [ST_i64+EBX*8]*/ - addbyte(0x6c); - addbyte(0xdd); - addbyte(cpu_state_offset(MM)); - addbyte(0x0f); /*SETE AL*/ - addbyte(0x94); - addbyte(0xc0); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - addbyte(0x0c); /*OR AL, TAG_UINT64*/ - addbyte(TAG_UINT64); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0x88); /*MOV [tag+EBX], AL*/ - addbyte(0x44); - addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) + { + addbyte(0x89); /*MOV MM[reg][EBP], EAX*/ + addbyte(0x45); + addbyte(cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); + addbyte(0x09); /*OR EAX, EDX*/ + addbyte(0xd0); + addbyte(0x89); /*MOV MM[reg][EBP]+4, EDX*/ + addbyte(0x55); + addbyte(cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q) + 4); + addbyte(0x0f); /*SETE AL*/ + addbyte(0x94); + addbyte(0xc0); + addbyte(0xdf); /*FILDq MM[reg][EBP]*/ + addbyte(0x6d); + addbyte(cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); + addbyte(0x0c); /*OR AL, TAG_UINT64*/ + addbyte(TAG_UINT64); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte(cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0x88); /*MOV tag[reg][EBP], AL*/ + addbyte(0x45); + addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte(0xdd); /*FSTP ST[reg][EBP]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + } + else + { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x89); /*MOV [ST_i64+EBX*8], EAX*/ + addbyte(0x44); + addbyte(0xdd); + addbyte(cpu_state_offset(MM)); + addbyte(0x09); /*OR EAX, EDX*/ + addbyte(0xd0); + addbyte(0x89); /*MOV [ST_i64+4+EBX*8], EDX*/ + addbyte(0x54); + addbyte(0xdd); + addbyte(cpu_state_offset(MM)+4); + addbyte(0x83); /*CMP EAX, 0*/ + addbyte(0xf8); + addbyte(0); + addbyte(0xdf); /*FILDl [ST_i64+EBX*8]*/ + addbyte(0x6c); + addbyte(0xdd); + addbyte(cpu_state_offset(MM)); + addbyte(0x0f); /*SETE AL*/ + addbyte(0x94); + addbyte(0xc0); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + addbyte(0x0c); /*OR AL, TAG_UINT64*/ + addbyte(TAG_UINT64); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0x88); /*MOV [tag+EBX], AL*/ + addbyte(0x44); + addbyte(0x1d); + addbyte(cpu_state_offset(tag[0])); + } } static int FP_LOAD_REG(int reg) { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - if (reg) + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); + addbyte(0xdd); /*FLD ST[reg][EBP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + } + else + { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + if (reg) + { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc3); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + } + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); } - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); addbyte(0xd9); /*FSTP [ESP]*/ addbyte(0x1c); addbyte(0x24); @@ -2271,22 +2486,31 @@ static int FP_LOAD_REG(int reg) static void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - if (reg) + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); + addbyte(0xdd); /*FLD ST[reg][EBP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + } + else + { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + if (reg) + { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc3); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + } + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); } - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); addbyte(0xdd); /*FSTP [ESP]*/ addbyte(0x1c); addbyte(0x24); @@ -2542,21 +2766,35 @@ static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) static void FP_POP() { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte(cpu_state_offset(TOP)); - addbyte(0xc6); /*MOVB tag[EAX], 3*/ - addbyte(0x44); - addbyte(0x05); - addbyte(cpu_state_offset(tag[0])); - addbyte(3); - addbyte(0x04); /*ADD AL, 1*/ - addbyte(1); - addbyte(0x24); /*AND AL, 7*/ - addbyte(7); - addbyte(0x88); /*MOV TOP, AL*/ - addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) + { + addbyte(0xc6); /*MOVB tag[0][EBP], 3*/ + addbyte(0x45); + addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte(3); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte(cpu_state_offset(TOP)); + addbyte((cpu_state.TOP + 1) & 7); + } + else + { + addbyte(0x8b); /*MOV EAX, TOP*/ + addbyte(0x45); + addbyte(cpu_state_offset(TOP)); + addbyte(0xc6); /*MOVB tag[EAX], 3*/ + addbyte(0x44); + addbyte(0x05); + addbyte(cpu_state_offset(tag[0])); + addbyte(3); + addbyte(0x04); /*ADD AL, 1*/ + addbyte(1); + addbyte(0x24); /*AND AL, 7*/ + addbyte(7); + addbyte(0x88); /*MOV TOP, AL*/ + addbyte(0x45); + addbyte(cpu_state_offset(TOP)); + } } #define FPU_ADD 0x00 @@ -2568,340 +2806,33 @@ static void FP_POP() static void FP_OP_S(int op) { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xd8); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); -} -static void FP_OP_D(int op) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { - addbyte(0x9b); /*FSTCW [ESP+8]*/ - addbyte(0xd9); - addbyte(0x7c); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); addbyte(0x24); - addbyte(0x08); - addbyte(0x66); /*MOV AX, [ESP+8]*/ - addbyte(0x8b); - addbyte(0x44); + addbyte(0xdd); /*FLD ST[dst][EBP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ + addbyte(0x65); + addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte(~TAG_UINT64); + addbyte(0xd8); /*FADD [ESP]*/ + addbyte(0x04 | op); addbyte(0x24); - addbyte(0x08); - addbyte(0x66); /*AND AX, ~(3 << 10)*/ - addbyte(0x25); - addword(~(3 << 10)); - addbyte(0x66); /*OR AX, npxc & (3 << 10)*/ - addbyte(0x0d); - addword(cpu_state.npxc & (3 << 10)); - addbyte(0x66); /*MOV [ESP+12], AX*/ - addbyte(0x89); - addbyte(0x44); - addbyte(0x24); - addbyte(0x0c); - addbyte(0xd9); /*FLDCW [ESP+12]*/ - addbyte(0x6c); - addbyte(0x24); - addbyte(0x0c); + addbyte(0xdd); /*FSTP ST[dst][EBP]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(ST[cpu_state.TOP])); } - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xdc); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) + else { - addbyte(0xd9); /*FLDCW [ESP+8]*/ - addbyte(0x6c); + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); addbyte(0x24); - addbyte(0x08); - } -} -static void FP_OP_IW(int op) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xde); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); -} -static void FP_OP_IL(int op) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xda); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); -} -static void FP_OP_IQ(int op) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xdc); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); -} - -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) - -static void FP_COMPARE_S() -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xd8); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); -} -static void FP_COMPARE_D() -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xdc); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); -} -static void FP_COMPARE_IW() -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xde); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); -} -static void FP_COMPARE_IL() -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xda); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); -} - -static void FP_OP_REG(int op, int dst, int src) -{ - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte(cpu_state_offset(TOP)); -// addbyte(0xbe); /*MOVL ESI, ST*/ -// addlong((uintptr_t)cpu_state.ST); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (src || dst) - { - addbyte(0x83); /*ADD EAX, 1*/ - addbyte(0xc0); - addbyte(src ? src : dst); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - - if (src) - { addbyte(0xdd); /*FLD ST[EBX*8]*/ addbyte(0x44); addbyte(0xdd); @@ -2911,98 +2842,741 @@ static void FP_OP_REG(int op, int dst, int src) addbyte(0x1d); addbyte(cpu_state_offset(tag[0])); addbyte(~TAG_UINT64); - addbyte(0xdc); /*FADD ST[EAX*8]*/ - addbyte(0x44 | op); - addbyte(0xc5); - addbyte(cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP ST[EBX*8]*/ + addbyte(0xd8); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ addbyte(0x5c); addbyte(0xdd); addbyte(cpu_state_offset(ST)); } +} +static void FP_OP_D(int op) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) + { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) + { + addbyte(0x9b); /*FSTCW [ESP+8]*/ + addbyte(0xd9); + addbyte(0x7c); + addbyte(0x24); + addbyte(0x08); + addbyte(0x66); /*MOV AX, [ESP+8]*/ + addbyte(0x8b); + addbyte(0x44); + addbyte(0x24); + addbyte(0x08); + addbyte(0x66); /*AND AX, ~(3 << 10)*/ + addbyte(0x25); + addword(~(3 << 10)); + addbyte(0x66); /*OR AX, npxc & (3 << 10)*/ + addbyte(0x0d); + addword(cpu_state.npxc & (3 << 10)); + addbyte(0x66); /*MOV [ESP+12], AX*/ + addbyte(0x89); + addbyte(0x44); + addbyte(0x24); + addbyte(0x0c); + addbyte(0xd9); /*FLDCW [ESP+12]*/ + addbyte(0x6c); + addbyte(0x24); + addbyte(0x0c); + } + addbyte(0xdd); /*FLD ST[dst][EBP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ + addbyte(0x65); + addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte(~TAG_UINT64); + addbyte(0xdc); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP ST[dst][EBP]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(ST[cpu_state.TOP])); + if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) + { + addbyte(0xd9); /*FLDCW [ESP+8]*/ + addbyte(0x6c); + addbyte(0x24); + addbyte(0x08); + } + } else { - addbyte(0xdd); /*FLD [ESI+EAX*8]*/ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) + { + addbyte(0x9b); /*FSTCW [ESP+8]*/ + addbyte(0xd9); + addbyte(0x7c); + addbyte(0x24); + addbyte(0x08); + addbyte(0x66); /*MOV AX, [ESP+8]*/ + addbyte(0x8b); + addbyte(0x44); + addbyte(0x24); + addbyte(0x08); + addbyte(0x66); /*AND AX, ~(3 << 10)*/ + addbyte(0x25); + addword(~(3 << 10)); + addbyte(0x66); /*OR AX, npxc & (3 << 10)*/ + addbyte(0x0d); + addword(cpu_state.npxc & (3 << 10)); + addbyte(0x66); /*MOV [ESP+12], AX*/ + addbyte(0x89); + addbyte(0x44); + addbyte(0x24); + addbyte(0x0c); + addbyte(0xd9); /*FLDCW [ESP+12]*/ + addbyte(0x6c); + addbyte(0x24); + addbyte(0x0c); + } + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + addbyte(0xdd); /*FLD ST[EBX*8]*/ addbyte(0x44); - addbyte(0xc5); - addbyte(cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - addbyte(cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xdc); /*FADD ST[EBX*8]*/ - addbyte(0x44 | op); addbyte(0xdd); addbyte(cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP ST[EAX*8]*/ + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x1d); + addbyte(cpu_state_offset(tag[0])); + addbyte(~TAG_UINT64); + addbyte(0xdc); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ addbyte(0x5c); - addbyte(0xc5); + addbyte(0xdd); addbyte(cpu_state_offset(ST)); + if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) + { + addbyte(0xd9); /*FLDCW [ESP+8]*/ + addbyte(0x6c); + addbyte(0x24); + addbyte(0x08); + } + } +} +static void FP_OP_IW(int op) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) + { + addbyte(0x66); /*MOV [ESP], AX*/ + addbyte(0x89); + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ + addbyte(0x65); + addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte(~TAG_UINT64); + addbyte(0xde); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP ST[0][EBP]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(ST[cpu_state.TOP])); + } + else + { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x1d); + addbyte(cpu_state_offset(tag[0])); + addbyte(~TAG_UINT64); + addbyte(0xde); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + } +} +static void FP_OP_IL(int op) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) + { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ + addbyte(0x65); + addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte(~TAG_UINT64); + addbyte(0xda); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP ST[0][EBP]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(ST[cpu_state.TOP])); + } + else + { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x1d); + addbyte(cpu_state_offset(tag[0])); + addbyte(~TAG_UINT64); + addbyte(0xda); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + } +} +static void FP_OP_IQ(int op) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) + { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ + addbyte(0x65); + addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte(~TAG_UINT64); + addbyte(0xdc); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP ST[0][EBP]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(ST[cpu_state.TOP])); + } + else + { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x1d); + addbyte(cpu_state_offset(tag[0])); + addbyte(~TAG_UINT64); + addbyte(0xdc); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + } +} + +#define C0 (1<<8) +#define C1 (1<<9) +#define C2 (1<<10) +#define C3 (1<<14) + +static void FP_COMPARE_S() +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) + { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0|C2|C3)) >> 8); + addbyte(0xd8); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0|C2|C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte(cpu_state_offset(npxs) + 1); + } + else + { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0|C2|C3)) >> 8); + addbyte(0xd8); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0|C2|C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte(cpu_state_offset(npxs) + 1); + } +} +static void FP_COMPARE_D() +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) + { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0|C2|C3)) >> 8); + addbyte(0xdc); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0|C2|C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte(cpu_state_offset(npxs) + 1); + } + else + { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0|C2|C3)) >> 8); + addbyte(0xdc); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0|C2|C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte(cpu_state_offset(npxs) + 1); + } +} +static void FP_COMPARE_IW() +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) + { + addbyte(0x66); /*MOV [ESP], AX*/ + addbyte(0x89); + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0|C2|C3)) >> 8); + addbyte(0xde); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0|C2|C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte(cpu_state_offset(npxs) + 1); + } + else + { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0|C2|C3)) >> 8); + addbyte(0xde); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0|C2|C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte(cpu_state_offset(npxs) + 1); + } +} +static void FP_COMPARE_IL() +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) + { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0|C2|C3)) >> 8); + addbyte(0xda); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0|C2|C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte(cpu_state_offset(npxs) + 1); + } + else + { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte(cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0|C2|C3)) >> 8); + addbyte(0xda); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0|C2|C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte(cpu_state_offset(npxs) + 1); + } +} + +static void FP_OP_REG(int op, int dst, int src) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) + { + addbyte(0xdd); /*FLD ST[dst][EBP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); + addbyte(0xdc); /*FADD ST[src][EBP]*/ + addbyte(0x45 | op); + addbyte(cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); + addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ + addbyte(0x65); + addbyte(cpu_state_offset(tag[(cpu_state.TOP + dst) & 7])); + addbyte(~TAG_UINT64); + addbyte(0xdd); /*FSTP ST[dst][EBP]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); + } + else + { + addbyte(0x8b); /*MOV EAX, TOP*/ + addbyte(0x45); + addbyte(cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + if (src || dst) + { + addbyte(0x83); /*ADD EAX, 1*/ + addbyte(0xc0); + addbyte(src ? src : dst); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(7); + } + + if (src) + { + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x1d); + addbyte(cpu_state_offset(tag[0])); + addbyte(~TAG_UINT64); + addbyte(0xdc); /*FADD ST[EAX*8]*/ + addbyte(0x44 | op); + addbyte(0xc5); + addbyte(cpu_state_offset(ST)); + addbyte(0xdd); /*FSTP ST[EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + } + else + { + addbyte(0xdd); /*FLD [ESI+EAX*8]*/ + addbyte(0x44); + addbyte(0xc5); + addbyte(cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x05); + addbyte(cpu_state_offset(tag[0])); + addbyte(~TAG_UINT64); + addbyte(0xdc); /*FADD ST[EBX*8]*/ + addbyte(0x44 | op); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + addbyte(0xdd); /*FSTP ST[EAX*8]*/ + addbyte(0x5c); + addbyte(0xc5); + addbyte(cpu_state_offset(ST)); + } } } static void FP_COMPARE_REG(int dst, int src) { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte(cpu_state_offset(TOP)); -// addbyte(0xbe); /*MOVL ESI, ST*/ -// addlong((uintptr_t)cpu_state.ST); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (src || dst) + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { - addbyte(0x83); /*ADD EAX, 1*/ - addbyte(0xc0); - addbyte(src ? src : dst); - addbyte(0x83); /*AND EAX, 7*/ + addbyte(0x8a); /*MOV CL, [npxs+1]*/ + addbyte(0x4d); + addbyte(cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0xdd); /*FLD ST[dst][EBP]*/ + addbyte(0x45); + addbyte(cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); + addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ + addbyte(0xe1); + addbyte((~(C0|C2|C3)) >> 8); + addbyte(0xdc); /*FCOMP ST[src][EBP]*/ + addbyte(0x5d); + addbyte(cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); + addbyte(0xdf); /*FSTSW AX*/ addbyte(0xe0); - addbyte(7); - } - - addbyte(0x8a); /*MOV CL, [npxs+1]*/ - addbyte(0x4d); - addbyte(cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ - addbyte(0xe1); - addbyte((~(C0|C2|C3)) >> 8); - - if (src) - { - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - addbyte(0xdc); /*FCOMP ST[EAX*8]*/ - addbyte(0x44 | 0x18); - addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0|C2|C3) >> 8); + addbyte(0x08); /*OR CL, AH*/ + addbyte(0xe1); + addbyte(0x88); /*MOV [npxs+1], CL*/ + addbyte(0x4d); + addbyte(cpu_state_offset(npxs) + 1); } else { - addbyte(0xdd); /*FLD [ESI+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte(cpu_state_offset(ST)); - addbyte(0xdc); /*FCOMP ST[EBX*8]*/ - addbyte(0x44 | 0x18); - addbyte(0xdd); - addbyte(cpu_state_offset(ST)); - } + addbyte(0x8b); /*MOV EAX, TOP*/ + addbyte(0x45); + addbyte(cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + if (src || dst) + { + addbyte(0x83); /*ADD EAX, 1*/ + addbyte(0xc0); + addbyte(src ? src : dst); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(7); + } - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR CL, AH*/ - addbyte(0xe1); - addbyte(0x88); /*MOV [npxs+1], CL*/ - addbyte(0x4d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte(0x8a); /*MOV CL, [npxs+1]*/ + addbyte(0x4d); + addbyte(cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ + addbyte(0xe1); + addbyte((~(C0|C2|C3)) >> 8); + + if (src) + { + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + addbyte(0xdc); /*FCOMP ST[EAX*8]*/ + addbyte(0x44 | 0x18); + addbyte(0xc5); + addbyte(cpu_state_offset(ST)); + } + else + { + addbyte(0xdd); /*FLD [ESI+EAX*8]*/ + addbyte(0x44); + addbyte(0xc5); + addbyte(cpu_state_offset(ST)); + addbyte(0xdc); /*FCOMP ST[EBX*8]*/ + addbyte(0x44 | 0x18); + addbyte(0xdd); + addbyte(cpu_state_offset(ST)); + } + + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0|C2|C3) >> 8); + addbyte(0x08); /*OR CL, AH*/ + addbyte(0xe1); + addbyte(0x88); /*MOV [npxs+1], CL*/ + addbyte(0x4d); + addbyte(cpu_state_offset(npxs) + 1); + } } static int ZERO_EXTEND_W_B(int reg) diff --git a/src/codegen_x86-64.c b/src/codegen_x86-64.c index 3520342..70bdc51 100644 --- a/src/codegen_x86-64.c +++ b/src/codegen_x86-64.c @@ -281,7 +281,8 @@ void codegen_block_init(uint32_t phys_addr) block->next = block->prev = NULL; block->next_2 = block->prev_2 = NULL; block->page_mask = 0; - + block->flags = 0; + block->was_recompiled = 0; recomp_page = block->phys & ~0xfff; @@ -1005,6 +1006,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t over = 1; pc_off = -1; test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; break; case 0xd9: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; @@ -1013,6 +1015,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t over = 1; pc_off = -1; test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; break; case 0xda: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; @@ -1021,6 +1024,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t over = 1; pc_off = -1; test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; break; case 0xdb: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; @@ -1029,6 +1033,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t over = 1; pc_off = -1; test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; break; case 0xdc: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; @@ -1038,6 +1043,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t over = 1; pc_off = -1; test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; break; case 0xdd: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; @@ -1046,6 +1052,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t over = 1; pc_off = -1; test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; break; case 0xde: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; @@ -1054,6 +1061,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t over = 1; pc_off = -1; test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; break; case 0xdf: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; @@ -1062,6 +1070,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t over = 1; pc_off = -1; test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; break; case 0xf0: /*LOCK*/ diff --git a/src/codegen_x86.c b/src/codegen_x86.c index 73e6909..728cf82 100644 --- a/src/codegen_x86.c +++ b/src/codegen_x86.c @@ -281,6 +281,7 @@ void codegen_block_init(uint32_t phys_addr) block->next = block->prev = NULL; block->next_2 = block->prev_2 = NULL; block->page_mask = 0; + block->flags = CODEBLOCK_STATIC_TOP; block->was_recompiled = 0; @@ -359,6 +360,7 @@ void codegen_block_start_recompile(codeblock_t *block) _ds.checked = _es.checked = _fs.checked = _gs.checked = (cr0 & 1) ? 0 : 1; + block->TOP = cpu_state.TOP; block->was_recompiled = 1; } @@ -484,6 +486,9 @@ void codegen_block_end_recompile(codeblock_t *block) codegen_block_generate_end_mask(); add_to_block_list(block); // pclog("End block %i\n", block_num); + + if (!(block->flags & CODEBLOCK_HAS_FPU)) + block->flags &= ~CODEBLOCK_STATIC_TOP; } void codegen_flush() @@ -821,6 +826,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t over = 1; pc_off = -1; test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; break; case 0xd9: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; @@ -829,6 +835,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t over = 1; pc_off = -1; test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; break; case 0xda: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; @@ -837,6 +844,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t over = 1; pc_off = -1; test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; break; case 0xdb: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; @@ -845,6 +853,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t over = 1; pc_off = -1; test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; break; case 0xdc: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; @@ -854,6 +863,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t over = 1; pc_off = -1; test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; break; case 0xdd: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; @@ -862,6 +872,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t over = 1; pc_off = -1; test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; break; case 0xde: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; @@ -870,6 +881,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t over = 1; pc_off = -1; test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; break; case 0xdf: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; @@ -878,6 +890,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t over = 1; pc_off = -1; test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; break; case 0xf0: /*LOCK*/