Sign in to follow this  

generating asm code using AngelScript's Jit Capability feature

This topic is 382 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hello,
as the topic title says, i want to generate asm code using AngelScript's Jit capability feature using AsmJit
now, for example, i want to decrement a variable, i should do this:

        case asBC_DecVi:
            a.dec(ptr(par1, ASMJIT_OFFSET_OF(asSVMRegisters, stackFramePointer)- asBC_SWORDARG0(bc)));
            break;
par1 is the asSVMRegisters struct which is passed as the first parameter
and, ASMJIT_OFFSET_OF is like offsetof macro, but defined in asmjit
as far as i know, i must retrieve the asSVMRegisters as the first parameter (which i get on the AllocArgs function of the assembler)
now, i have this assembly code which is not correct:
dec [ebx+3]
par1 is on the ebx and ASMJIT_OFFSET_OF() return's 4, if decremented by 1 with asBC_SWORDARG0(), return's 3
ok, what am i doing wrong?
this is my JitEntry:
        case asBC_JitEntry:
            a.mov(dword_ptr(par2), a.getOffset()- firstEntry);
            break;
a is the assembler, getOffset return's the position of the asm code and firstEntry is the position of the function when it was started to execute

Share this post


Link to post
Share on other sites

Unfortunately I don't know AsmJit (nor do I know much about JIT compilation at all). 

 

I suggest you study the code for BlindMind's JIT compiler to get an understanding of how to make your own JIT compiler work with AngelScript.

 

 

 

In the VM asBC_DecVi is implemented as:

 

    // Decrement the local integer variable
    case asBC_DecVi:
        (*(int*)(l_fp - asBC_SWORDARG0(l_bc)))--;
        l_bc++;
        break;

 

If we translate this to how the JIT compiled function might see it (written as a C++ function) it would be:

 

void JITcompiledFunction(asSVMRegistrers *reg, asPWORD jitArg)
{
    /* prologue for loading CPU registers and jumping to the right spot in the code based on jitArg (defined by JIT compiler) */
 
    (*(int*)(regs->stackFramePointer - (*(((short*)regs->programPointer)+1)))--;
    (regs->programPointer++;
 
    /* epilogue for cleaning up and returning to the VM */
}

 

You can compile this function to assembler and determine the assembler instructions that the JIT compiler has to produce to get the correct result.

Share this post


Link to post
Share on other sites

okay, instead of using for example asBC_SWORDARG0, can i use +1 to retrieve parameters? because in assembly, everything is offset based
and, what about jumps? i want to use jmp, what do you recommend? i think it should be like this:

a.push(a.zax());
a.mov(a.zax(), ptr(regs, ASMJIT_OFFSET_OF(asSVMRegisters, programPointer)));
a.mov(a.zax(), dword_ptr(a.zax(), 2));
a.add(dword_ptr(a.zax()), 1); //asBC_INTARG
a.jmp(a.zax());
a.mov(ptr(regs, ASMJIT_OFFSET_OF(asSVMRegisters, programPointer)), dword_ptr(a.zax());
a.pop(a.zax());
unfortunately, the compiler's generated asm will not help because everything is turned into constance, and dirring the execution everything will be loaded into memory and i have to change the memory with asmjit

Share this post


Link to post
Share on other sites

asBC_SWORDARG0 means: read the 16bit argument at the offset of 2 bytes after the current program pointer address. This is what you'll need to implement in assembler instructions. 

 

Yes, you can use jmp instructions the JIT compiled assembler code. As the asBC_JMP instruction in AngelScript refers to the byte code program pointer you'll need to translate this into the corresponding offset in the JIT assembler code. To do that you'll most likely need to perform multiple passes over the JIT assembler code as it won't be easy to predict the exact size of the assembler instructions until you've actually generated them.

Share this post


Link to post
Share on other sites

hi again,
i have a question:
in (for example asBC_JMP), do the code in ExecuteNext will be executed or not?
i mean, this code which AngelScript has in asBC_JMP:

        l_bc += 2 + asBC_INTARG(l_bc);
do this executed or not? if yes, i don't need to execute it in asm level and just jump in that part of the code Edited by brightening-eyes

Share this post


Link to post
Share on other sites

Yes, the code in ExecuteNext for the instruction asBC_JMP is executed.

 

  l_bc += 2 + asBC_INTARG(l_bc);

 

This code means: move the program pointer 2 + whatever value in the instruction argument. 

 

2 in this case refers to the size of the asBC_JMP instruction itself. So if the argument would be 0, the jump instruction would be the same as a nop instruction, i.e. do nothing and just proceed with the next instruction.

 

In the JIT compiled code you'll want to translate this into the corresponding jump instruction to the appropriate address in the JIT compiled code. Remember that if your JIT compiled code returns control to the VM you must make sure the asSVMRegisters::programPointer member is correctly updated so the VM can resume the execution from the correct bytecode instruction.

Share this post


Link to post
Share on other sites

This topic is 382 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this