summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/drcbex86.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/drcbex86.cpp')
-rw-r--r--src/devices/cpu/drcbex86.cpp61
1 files changed, 40 insertions, 21 deletions
diff --git a/src/devices/cpu/drcbex86.cpp b/src/devices/cpu/drcbex86.cpp
index ea192477c12..808418204d7 100644
--- a/src/devices/cpu/drcbex86.cpp
+++ b/src/devices/cpu/drcbex86.cpp
@@ -1285,16 +1285,21 @@ void drcbe_x86::reset()
a.mov(eax, ptr(ecx, regoffsh));
a.mov(MABS(&m_state.f[regnum].s.h), eax);
}
- a.movzx(eax, byte_ptr(ecx, offsetof(drcuml_machine_state, fmod))); // movzx eax,state->fmod
- a.and_(eax, 3); // and eax,3
- a.mov(MABS(&m_state.fmod), al); // mov [fmod],al
- a.fldcw(word_ptr(uintptr_t(&fp_control[0]), eax, 1)); // fldcw fp_control[eax*2]
- a.mov(eax, ptr(ecx, offsetof(drcuml_machine_state, exp))); // mov eax,state->exp
- a.mov(MABS(&m_state.exp), eax); // mov [exp],eax
- a.movzx(eax, byte_ptr(ecx, offsetof(drcuml_machine_state, flags))); // movzx eax,state->flags
- a.push(dword_ptr(uintptr_t(flags_unmap), eax, 2)); // push flags_unmap[eax*4]
- a.popfd(); // popf
- a.ret(); // ret
+ a.movzx(eax, byte_ptr(ecx, offsetof(drcuml_machine_state, fmod)));
+ a.and_(eax, 3);
+ a.mov(MABS(&m_state.fmod), al);
+ a.fldcw(word_ptr(uintptr_t(&fp_control[0]), eax, 1));
+ a.mov(eax, ptr(ecx, offsetof(drcuml_machine_state, exp)));
+ a.mov(MABS(&m_state.exp), eax);
+
+ a.pushfd();
+ a.and_(dword_ptr(esp), ~0x8c5);
+ a.movzx(eax, byte_ptr(ecx, offsetof(drcuml_machine_state, flags)));
+ a.and_(eax, FLAGS_ALL);
+ a.mov(eax, ptr(uintptr_t(flags_unmap), eax, 2));
+ a.or_(dword_ptr(esp), eax);
+ a.popfd();
+ a.ret();
// emit the generated code
@@ -3578,11 +3583,22 @@ void drcbe_x86::op_setflgs(Assembler &a, const instruction &inst)
be_parameter srcp(*this, inst.param(0), PTYPE_MRI);
a.pushfd();
-
- emit_mov_r32_p32(a, eax, srcp);
-
- a.mov(eax, ptr(uintptr_t(flags_unmap), eax, 2));
a.and_(dword_ptr(esp), ~0x8c5);
+
+ if (srcp.is_immediate())
+ {
+ uint32_t const flags = flags_unmap[srcp.immediate() & FLAGS_ALL];
+ if (!flags)
+ a.xor_(eax, eax);
+ else
+ a.mov(eax, flags);
+ }
+ else
+ {
+ emit_mov_r32_p32(a, eax, srcp);
+ a.and_(eax, FLAGS_ALL);
+ a.mov(eax, ptr(uintptr_t(flags_unmap), eax, 2));
+ }
a.or_(dword_ptr(esp), eax);
a.popfd();
@@ -6991,15 +7007,18 @@ void drcbe_x86::op_fcmp(Assembler &a, const instruction &inst)
a.fcomip(st1);
a.fstp(st0);
- // clear Z and C if unordered
- Label ordered = a.newLabel();
+ if (inst.flags() & (FLAG_Z | FLAG_C))
+ {
+ // clear Z and C if unordered
+ Label ordered = a.newLabel();
- a.short_().jnp(ordered);
- a.lahf();
- a.and_(eax, 0x00003e00);
- a.sahf();
+ a.short_().jnp(ordered);
+ a.lahf();
+ a.and_(eax, 0x00003e00);
+ a.sahf();
- a.bind(ordered);
+ a.bind(ordered);
+ }
}