VOGONS


First post, by corto

User metadata
Rank Newbie
Rank
Newbie

Hi all

This is my first post in this forum in which I already looked for information. I am a developer and a PowerPC fan. I spent much time profiling dosbox on PowerPC and applied some changes using the normal core but as it is very to optimize, I would like to work on the dynrec core.

I compiled with the file "risc_ppc.h" that I found in the archive for the Wii but that crashes at the beginning (gen_return_function is called before gen_run_code and access the stack that is not initialized).

1. First, I would like to understand what do gen_run_code and gen_return_function and exactly how they are used. As the code in a block is called like a C function, I think they are used as prolog and epilog (like with MIPS).

2. When I look at the MIPS function "gen_run_code", I see "jr $a0" that means there is a jump to register $a0 (R4), so that the code to execute is given in $a0 but its value not given explicitely anywhere. And how the code comes back at the end of the code execution ? The epilog had been put at the end of the code ?

3. So please, does anyone could explain the mechanism of all that ?

4. If there is an error in the generated code, is there a possibility to check the content of a block that is under execution ?

5. In the PowerPC part, registers are saved and restored : is it necessary because I suppose the PPC has enough volatile registers, r3 to r8, to use in the translated code ? How are handled nested function calls ? As in the generated PPC code, parameters will be put in r3, r4, ... is there a risk that these registers may be trashed ? The MIPS version doesn't seem to prevent that.

Thanks,

Corto

Reply 1 of 5, by corto

User metadata
Rank Newbie
Rank
Newbie

No answer after one month and half ... I suppose nobody is able to give information 🙁

I am disappointed to see there are no more technical explanations within Dosbox. And the code is nor clean neither documented to understand by itself.

So I will continue do to work on my own optimizations in the normal core, even if it is a very hard job.

Reply 2 of 5, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

No answer after one month and half ...

Correct, and since i neither have any knowledge of ppc or powerpc/wii/whatever architectures
and nobody with such knowledge responded up to now you can't do much more to
force-get an answer.

I am disappointed to see there are no more technical explanations within Dosbox.

Yeah sorry, though the dynrec core is the pretty much best documented part
in dosbox since it aims at portability, which seems to have succeeded since other
people were able to code new backends.

Don't see what would be extraordinarily complicated about the recompiler when
adding a new backend (besides complexity itself), best you start with one of the
existing backends where you have an architecture you're familiar with (x86 would
be nice for this) and debug the thing a bit to see how it behaves, what it does.

1. First, I would like to understand what do gen_run_code and gen_return_function and exactly how they are used. As the code in a block is called like a C function, I think they are used as prolog and epilog (like with MIPS).

Right, they generate code (-> cache) that serves as pro/epilog.

2. When I look at the MIPS function "gen_run_code", I see "jr $a0" that means there is a jump to register $a0 (R4), so that the code to execute is given in $a0 but its value not given explicitely anywhere.

Since it's not set explicitly, it gets its value implicitly from the argument in

BlockReturn ret=core_dynrec.runcode(block->cache.start);

5. In the PowerPC part, registers are saved and restored : is it necessary because I suppose the PPC has enough volatile registers, r3 to r8, to use in the translated code ? How are handled nested function calls ? As in the generated PPC code, parameters will be put in r3, r4, ... is there a risk that these registers may be trashed ? The MIPS version doesn't seem to prevent that.

There is no nesting.
There are some registers that maintain their value according to the ABI on any
function call, the rest is trashed (possibly protected by the recompiler, one reg or so iirc).

Reply 3 of 5, by corto

User metadata
Rank Newbie
Rank
Newbie

Thanks for your answer. I will use the information to try again.

For my attempt, I got a patch for the Wii and with what I tested, I failed to make it working.

I wonder what is the best approach to debug when implementing a dynamic engine for a new architecture.

Reply 4 of 5, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

If you are familiar with x86 then configure dosbox to use the x86 dynrec core,
so you can trace the generating functions as well as the generated code
(the latter being the fun thing to trace, visual studio comes handy for that imo
but gnu toolchains should work as well).

I wonder what is the best approach to debug when implementing a dynamic engine for a new architecture.

You'll just need the architecture-specific backend (the risc_xyz files), and usually
it's easiest to try getting a minimal set to work (check decoder.h in the dynrec
directory with contains the generator functions for the emulated x86 opcodes,
you can arbitrarily delete those so only a small set is called, the rest will be handled
by the normal core).

Reply 5 of 5, by valency

User metadata
Rank Newbie
Rank
Newbie

Hi Corto, I've been reading the Dosbox source for a while and I believe I understand the dynrec portions fairly well, and I am also interested in doing a PowerPC port of the backend. Perhaps we could share notes?