Page 1 of 1

Questions on JIT...

Posted: Sun May 20, 2007 9:30 pm
by Alboin
Regarding Just In Time Compilation for emulation of a full computer architecture: how does the code, once recompiled, run on the host PC, while still emulating the architecture being emulated?

For example: If I have some 6502 code, and then I translate it to x86 and run it on the host, how does that emulate the architecture being emulated? Isn't it being run on the host?

Can someone please point out the oh-so-obvious-point that I'm somehow missing?

Thanks. :cry:

Posted: Sun May 20, 2007 9:50 pm
by niteice
Once you JIT the 6502 code, it becomes x86 code doing the same as what the 6502 version did.

Posted: Mon May 21, 2007 3:45 am
by os64dev
keep in mind that the whole you translate the code from a platform to x86. You in fact only translate the behaviour. The architecture you simulate by handling the peripherals via memory mapped io etc. Thus every memory read or write you check whether if it is only memory or if it is hardware and take the appropriate action.

Posted: Mon May 21, 2007 7:33 am
by Brendan
Hi,
os64dev wrote:keep in mind that the whole you translate the code from a platform to x86. You in fact only translate the behaviour. The architecture you simulate by handling the peripherals via memory mapped io etc. Thus every memory read or write you check whether if it is only memory or if it is hardware and take the appropriate action.
IIRC for 6502 there is no MMU (no segmentation and no paging) so it'd be faster to add the checks into the final code. For example, something like:

Code: Select all

    LDX #$12
    LDA $1234,X
    STA $C000
Might be translated into:

Code: Select all

    movzx ebx,byte 0x12
    mov al,[EMU_RAM_base + 0x1234 + ebx]
    test dword [EMU_CHIPSET_CONTROL], ENABLE_IO_BANK
    je .l1
    call EMU_IO_BANK_WRITE_ACCUMULATOR
    jmp .l2
.l1:
    mov [EMU_RAM_base + 0xC000],al
.l2:

Cheers,

Brendan

Posted: Mon May 21, 2007 1:44 pm
by Alboin
So the translated assembly instructions don't really run on the machine. ie. they run on the processor, but affect the emulator's data. (stack, registers, etc.) This is what I had been getting confused. I thought they acted upon the actual machine's registers and such. =P~

An implementation question, however. Let's say I have a function, t. t takes raw opcodes from the emulated data and translates them to assembly for the host PC. How to go about assembling them? An external assembler? Or just program the x86 codes right into the program? (I'm thinking more towards the latter.)

A more minor question, however. How to execute assembled code from C? A function pointer to the code that is then called?

Thanks!

Posted: Mon May 21, 2007 2:22 pm
by Candy
Alboin wrote:A more minor question, however. How to execute assembled code from C? A function pointer to the code that is then called?
For that, look at this IOCCC worst abuse of the rules entry. Think about how it works.

http://www.au.ioccc.org/1984/mullender.c

Posted: Mon May 21, 2007 2:42 pm
by Alboin
Candy wrote:
Alboin wrote:A more minor question, however. How to execute assembled code from C? A function pointer to the code that is then called?
For that, look at this IOCCC worst abuse of the rules entry. Think about how it works.

http://www.au.ioccc.org/1984/mullender.c
Ah, okay. I wasn't too far off. :wink:

The entry used an array, but couldn't one use a function pointer that is directed at an array?

Posted: Mon May 21, 2007 3:51 pm
by Candy
Alboin wrote:
Candy wrote:
Alboin wrote:A more minor question, however. How to execute assembled code from C? A function pointer to the code that is then called?
For that, look at this IOCCC worst abuse of the rules entry. Think about how it works.

http://www.au.ioccc.org/1984/mullender.c
Ah, okay. I wasn't too far off. :wink:

The entry used an array, but couldn't one use a function pointer that is directed at an array?
Implicitly, the symbol "main" is a function pointer to your entry point. I believe your compiler will complain though (nowadays compilers don't let you make main an array of shorts).

Posted: Tue May 22, 2007 12:52 am
by os64dev
i've been programming emulators for some while now even with dynamic recompilation. The basic concept is like so: you have an byte array of N size (lets say 4 KiB) and an current translation instruction pointer.

Code: Select all

unsigned char translateCode[4096];
unsigned int  translateIP;
Then you have some helper functions to enter opcodes in the code buffer.

Code: Select all

void genOpcode(int opc) {
    translateCode[translateIP++] = opc;
}
now you have to write a parser to parse the original machine code and translate them into host machine opcodes.. as an example i just put some nop instructions and a return statement.

Code: Select all

void main(void){
    translateIP = 0;
    for(int i = 0; i < 4095; i++) {
        genOpcode(0x90); //- insert a nop instruction (x86).
    }
    genOpcode(0xC3); //- insert a return instruction (x86).
    //- now execute the 4095 nops and the return.
    (void(*)(void))translateCode();
    printf("done...");
}
I hope this explains roughly what you need to do. I've written an PSone emulator like this and it works well.

Posted: Tue May 22, 2007 4:52 am
by Alboin
Ah, thanks. That clears everything up.