Next Generation Emulation banner

Flags: proper management within your binary translator.

893 Views 2 Replies 2 Participants Last post by  blueshogun96
It's been a while since I've had [adequate] time to work on my emulator. So now that I actually have some of that free time again, I need to get back to work on it. Now, I've generally got the basics of my binary translator going already, but the one thing that has me scratching my head is emulating the flags. This is mainly due to the fact that I was more focused on getting my code emitter to stop crashing!

When writing your code block, do you need to pre-determine how flags will be affected? Or is there a better way? Sorry, my brain is kinda fried atm. This is what I originally planed on doing, but it's probably not the best thing to do. Oh yeah, my core is an x86 -> x86 binary translator.

Code:
u32 pc_flags, xbox_flags;

__asm
{
     // Save host flags
     push eax
     popfd pc_flags
     
     // Set emulated flags
     pushfd xbox_flags
    
     // Execute code
     call code_addr

     // Save emulated flags
     popfd xbox_flags

     // Restore host flags
     pushfd pc_flags
     pop eax
}
May or may not work. Is there a better way to do this? I still have much to learn about dynarec in general. Thanks.
See less See more
1 - 3 of 3 Posts
well, i don't think the above code will even work. AFAIK pushfd pushes the EFLAGS register onto the stack; so
"pushfd xbox_flags"
doesn't make sense (shouldn't take any operands).

i think you meant something like:

Code:
u32 xbox_flags;

__asm
{
     // Save host flags and regs
     pushad
     pushfd
     
     // Set emulated flags
     push xbox_flags
     popfd

     // Execute code
     call code_addr

     // Save emulated flags
     pushfd
     pop xbox_flags

     // Restore host flags and regs
     popfd
     popad
}
IDK if theres a faster way to get a mem value to EFLAGS than the 2 instructions i used in the above code.


Anyways, i'm not entirely sure what you're trying to do in the above code.
code_addr is what? some xbox function that you're going to natively run (since both processors are x86)?

or is this your dynarec dispatcher? which means code_addr is your recompiled code block?


emulating x86 on x86 is a bit odd for me since its not what i'm used to, and i guess there's many ways you can do it.

i guess the 2 main approaches would be to 'emulate' the flag register, and the other is to try and use the one on the host cpu (which i guess you're trying to do).

on emus like pcsx2 or dolphin, we emulate the flag registers.
as in, we have a memory location which stores the emulated flag register, and we manually set/clear the corresponding bits ourselves.
since this is slow, the smart thing to do is to only set flags when they will be read (this involves a multi-pass dynarec and can get very complex in some cases).
See less See more
Thanks for the info on push/popfd. I'm a bit rusty and haven't touched those instructions in a long time. That code looks much better.

That code above just executes a pre-generated code block. The "call code_addr" just calls it.

It might be safer in the long run to do it the "slow" way. That would involve me setting the flag per instruction that affects a certain flag. The most important thing is getting it to work for now. Now that I think about it more, it doesn't sound very safe.
1 - 3 of 3 Posts
This is an older thread, you may not receive a response, and could be reviving an old thread. Please consider creating a new thread.
Top