Skip to content

JIT compiler my programming specific language (PSL) to x86 architecture

Notifications You must be signed in to change notification settings

shaazmik/JIT_Compiler

Repository files navigation

JIT_Compiler

JIT compiler my programming specific language (PSL) to x86 architecture

Introduction:

JIT-compiler translates my PSL (Programming Specific Language) architecture
into binary code for the x86-64 processor architecture.
The basic idea behind a JIT compiler is to translate the binary code of one architecture into the binary code of another architecture.
The main difference is that the program is executed from a buffer stored in the JIT compiler program.
In this case, creating an OS-specific executable is irrelevant, which is more cross-platform than
creating an executable for each OS. Only the architecture of the processor matters.


To compilie:


OPTIONS:

  • OS: Linux(Ubuntu)
  • Compiler: GCC
  • Language: C, C++, Assembler
  • Profiler: valgrind --tool=callgrind

For PSL_assembler

.JIT_compiler/Assembler_PSL/Assembler

  • make
  • ./assembler.out
  • the PSL binary code is in the assembler.bin file

For CPU_emulator

./JIT_compiler/Assembler_PSL/CPU

  • make
  • to run our processor emulator in C
  • ./processor.out

For JIT_compiler

./JIT_compiler

  • firstly, the assembler.bin file must be prepared
  • start makefile on Linux (Bash).
  • make
  • ./a.out

Main page:

  • The registers were used to transfer data.
  • System V Calling Convention.
  • The memory is used to save registers according to convention and to return and transfer arguments.
  • The assembler commands need to write to the Assembler_PSL\commands.txt file.
  • To compare performance, we will run the same programs on the virtual CPU and compiled by JIT.
  • Take the performance data from the callgrind.

Perfomance tests:

  • factorial
  • Fibonacci number
  • quadratic equation

Processor_command_table

All PSL commands have some kind of wrapper in x86-64, so tabular data may be different
For more information see the Commands_JIT.h file

COMMAND PSL x86-64
PUSH 0x11 0x68
PUSH AX 0x1200 0x50
PUSH BX 0x1201 0x53
PUSH CX 0x1202 0x51
PUSH DX 0x1203 0x52
POP AX 0x2200 0x58
POP BX 0x2201 0x5B
POP CX 0x2202 0x59
POP DX 0x2203 0x5A
ADD 0x06 0x4801F7
SUB 0x07 0x4829F7
MUL 0x08 0x48F7EA
DIV 0x09 0x48F7F9
JMP 0x0D 0xE9
JE 0x1D 0x0F84
JNE 0x2D 0x75
JA 0x3D 0x0F8F
JB 0x4D 0x0F8C
CALL 0x5D 0xE8
RET 0x6A 0xC3
SHOW 0x16 SHOW
IN 0x17 IN
SQRT 0x10 SQRT
HLT 0x0F 0xC3

Description of functions(SHOW, IN, SQRT)

The commands described have a DSL (Domain Specific Language). Their description can be found in the JIT_DSL.h file.
These functions work by calling the standard functions Printf, Scanf, sqrt.

SHOW

DEF_CMD_(0x16, SHOW, 0, 
{
    PUT_IP;
    
    (++ip_PSL);
 
    *(x86struct->x86_code + ip_x86++) = (char)(0x5F);       //pop rdi

    MOV_R10;

    push_show_addr(x86struct->x86_code + ip_x86);           //mov r10, address
    ip_x86 += sizeof(int) / sizeof(char);;



    SAVE_RAX;
    SAVE_RBX;
    SAVE_RCX;
    SAVE_RDX;

    CALL_R10;
    
    RET_RAX;
    RET_RBX;
    RET_RCX;
    RET_RDX;
}
)

IN

DEF_CMD_(0x17, IN, 0,
{
    PUT_IP;

    ip_PSL++;

    SAVE_RAX;
    SAVE_RBX;
    SAVE_RCX;
    SAVE_RDX;

    MOV_R10;

    push_in_addr(x86struct->x86_code + ip_x86);            //mov r10, address
    ip_x86 += sizeof(int) / sizeof(char);;


    SAVE_RSP;

    STACK_ALIGNMENT_16;

    CALL_R10;
    
    RETURN_RSP;

    PUSH_RAX;

    RET_RAX;
    RET_RBX;
    RET_RCX;
    RET_RDX;
}
)

SQRT

DEF_CMD_(0x10, SQRT, 0,
{
    PUT_IP;

    ip_PSL++;

    POP_RDI;

    MOV_R10;

    push_sqrt_addr(x86struct->x86_code + ip_x86);            //mov r10, address
    ip_x86 += sizeof(int) / sizeof(char);

    SAVE_RAX;
    SAVE_RBX;
    SAVE_RCX;
    SAVE_RDX;

    CALL_R10;

    PUSH_RAX;

    RET_RAX;
    RET_RBX;
    RET_RCX;
    RET_RDX;

}
)

Results:

For comparison, let's take the results of our virtual processor and JIT

Virtual processor result:

  • Performance test: calculating the factorial 16
  • All checks and logs disabled
  • -O2 flag
  • 1 789 432 incl.

Image alt

x86-64 result:

  • Performance test: calculating the factorial 16
  • Only record the programme running time.
  • without any flags
  • 152 994 incl.

Image alt


Conclusion:

As you can see the difference in performance is about 11,7 times
This is obvious because the virtual processor has many more x86-64 instructions within it to execute a single instruction
This suggests that the programme is working correctly.

About

JIT compiler my programming specific language (PSL) to x86 architecture

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published