@@ -469,8 +469,8 @@ class drcbe_x64 : public drcbe_interface
469
469
470
470
void * stacksave; // saved stack pointer
471
471
472
- uint8_t flagsmap[0x1000 ]; // flags map
473
- uint64_t flagsunmap[0x20 ]; // flags unmapper
472
+ uint8_t flagsmap[0x100 ]; // flags map
473
+ uint32_t flagsunmap[0x20 ]; // flags unmapper
474
474
};
475
475
476
476
// resolved memory handler functions
@@ -1047,17 +1047,17 @@ drcbe_x64::drcbe_x64(drcuml_state &drcuml, device_t &device, drc_cache &cache, u
1047
1047
if (entry & 0x004 ) flags |= FLAG_U;
1048
1048
if (entry & 0x040 ) flags |= FLAG_Z;
1049
1049
if (entry & 0x080 ) flags |= FLAG_S;
1050
- if (entry & 0x800 ) flags |= FLAG_V;
1050
+ // can't get FLAG_V from lahf
1051
1051
m_near.flagsmap [entry] = flags;
1052
1052
}
1053
1053
for (int entry = 0 ; entry < std::size (m_near.flagsunmap ); entry++)
1054
1054
{
1055
- uint64_t flags = 0 ;
1056
- if (entry & FLAG_C) flags |= 0x001 ;
1057
- if (entry & FLAG_U) flags |= 0x004 ;
1058
- if (entry & FLAG_Z) flags |= 0x040 ;
1059
- if (entry & FLAG_S) flags |= 0x080 ;
1060
- if (entry & FLAG_V) flags |= 0x800 ;
1055
+ uint32_t flags = 0 ;
1056
+ if (entry & FLAG_C) flags |= 0x001 << 8 ;
1057
+ if (entry & FLAG_U) flags |= 0x004 << 8 ;
1058
+ if (entry & FLAG_Z) flags |= 0x040 << 8 ;
1059
+ if (entry & FLAG_S) flags |= 0x080 << 8 ;
1060
+ // can't set V -> O with sahf
1061
1061
m_near.flagsunmap [entry] = flags;
1062
1062
}
1063
1063
@@ -2527,27 +2527,31 @@ void drcbe_x64::op_setflgs(Assembler &a, const instruction &inst)
2527
2527
2528
2528
be_parameter srcp (*this , inst.param (0 ), PTYPE_MRI);
2529
2529
2530
- a.pushfq ();
2531
- a.and_ (qword_ptr (rsp), ~0x8c5 );
2532
-
2533
2530
if (srcp.is_immediate ())
2534
2531
{
2535
- uint64_t const flags = m_near.flagsunmap [srcp.immediate () & FLAGS_ALL];
2532
+ uint32_t const flags = m_near.flagsunmap [srcp.immediate () & FLAGS_ALL];
2536
2533
if (!flags)
2537
- a.xor_ (rax, rax);
2534
+ a.xor_ (eax, eax);
2535
+ else
2536
+ a.mov (eax, flags);
2537
+
2538
+ if (srcp.immediate () & FLAG_V)
2539
+ a.mov (ecx, 1 );
2538
2540
else
2539
- a.mov (rax, flags );
2541
+ a.xor_ (ecx, ecx );
2540
2542
}
2541
2543
else
2542
2544
{
2543
- mov_reg_param (a, rax, srcp);
2544
- a.and_ (rax, FLAGS_ALL);
2545
+ mov_reg_param (a, eax, srcp);
2546
+ a.mov (ecx, FLAG_V);
2547
+ a.and_ (ecx, eax);
2548
+ a.and_ (eax, FLAGS_ALL);
2545
2549
2546
- a.mov (rax , ptr (rbp, rax, 3 , offset_from_rbp (&m_near.flagsunmap [0 ])));
2550
+ a.mov (eax , ptr (rbp, rax, 2 , offset_from_rbp (&m_near.flagsunmap [0 ])));
2547
2551
}
2548
- a.or_ (qword_ptr (rsp), rax);
2549
2552
2550
- a.popfq ();
2553
+ a.add (cl, 0x7f );
2554
+ a.sahf ();
2551
2555
}
2552
2556
2553
2557
@@ -2566,20 +2570,25 @@ void drcbe_x64::op_save(Assembler &a, const instruction &inst)
2566
2570
be_parameter dstp (*this , inst.param (0 ), PTYPE_M);
2567
2571
2568
2572
// copy live state to the destination
2569
- mov_r64_imm (a, rcx, (uintptr_t )dstp.memory ()); // mov rcx,dstp
2573
+ mov_r64_imm (a, rcx, (uintptr_t )dstp.memory ());
2570
2574
2571
2575
// copy flags
2572
- a.pushfq (); // pushf
2573
- a.pop (rax); // pop rax
2574
- a.and_ (eax, 0x8c5 ); // and eax,0x8c5
2575
- a.mov (al, ptr (rbp, rax, 0 , offset_from_rbp (&m_near.flagsmap [0 ]))); // mov al,[flags_map]
2576
- a.mov (ptr (rcx, offsetof (drcuml_machine_state, flags)), al); // mov state->flags,al
2576
+ a.lahf ();
2577
+ a.seto (dl);
2578
+ a.shr (eax, 8 );
2579
+ a.movzx (edx, dl);
2580
+ a.and_ (eax, 0x0c5 );
2581
+ a.movzx (eax, byte_ptr (rbp, rax, 0 , offset_from_rbp (&m_near.flagsmap [0 ])));
2582
+ a.lea (rax, ptr (rax, rdx, 1 ));
2583
+ a.mov (ptr (rcx, offsetof (drcuml_machine_state, flags)), al);
2577
2584
2578
2585
// copy fmod and exp
2579
- a.mov (al, MABS (&m_state.fmod )); // mov al,[fmod]
2580
- a.mov (ptr (rcx, offsetof (drcuml_machine_state, fmod)), al); // mov state->fmod,al
2581
- a.mov (eax, MABS (&m_state.exp )); // mov eax,[exp]
2582
- a.mov (ptr (rcx, offsetof (drcuml_machine_state, exp)), eax); // mov state->exp,eax
2586
+ Mem fmod = MABS (&m_state.fmod );
2587
+ fmod.setSize (1 );
2588
+ a.movzx (eax, fmod);
2589
+ a.mov (ptr (rcx, offsetof (drcuml_machine_state, fmod)), al);
2590
+ a.mov (eax, MABS (&m_state.exp ));
2591
+ a.mov (ptr (rcx, offsetof (drcuml_machine_state, exp)), eax);
2583
2592
2584
2593
// copy integer registers
2585
2594
int regoffs = offsetof (drcuml_machine_state, r);
@@ -2627,7 +2636,7 @@ void drcbe_x64::op_restore(Assembler &a, const instruction &inst)
2627
2636
be_parameter srcp (*this , inst.param (0 ), PTYPE_M);
2628
2637
2629
2638
// copy live state from the destination
2630
- mov_r64_imm (a, rcx, (uintptr_t )srcp.memory ()); // mov rcx,dstp
2639
+ mov_r64_imm (a, rcx, (uintptr_t )srcp.memory ());
2631
2640
2632
2641
// copy integer registers
2633
2642
int regoffs = offsetof (drcuml_machine_state, r);
@@ -2667,13 +2676,13 @@ void drcbe_x64::op_restore(Assembler &a, const instruction &inst)
2667
2676
a.mov (MABS (&m_state.exp ), eax);
2668
2677
2669
2678
// copy flags
2670
- a.pushfq ();
2671
- a.and_ (qword_ptr (rsp), ~0x8c5 );
2672
2679
a.movzx (eax, byte_ptr (rcx, offsetof (drcuml_machine_state, flags)));
2680
+ a.mov (ecx, FLAG_V); // don't need pointer to src any more
2681
+ a.and_ (ecx, eax);
2673
2682
a.and_ (eax, FLAGS_ALL);
2674
- a.mov (rax , ptr (rbp, rax, 3 , offset_from_rbp (&m_near.flagsunmap [0 ])));
2675
- a.or_ ( qword_ptr (rsp), rax );
2676
- a.popfq ();
2683
+ a.mov (eax , ptr (rbp, rax, 2 , offset_from_rbp (&m_near.flagsunmap [0 ])));
2684
+ a.add (cl, 0x7f );
2685
+ a.sahf ();
2677
2686
}
2678
2687
2679
2688
0 commit comments