diff options
-rw-r--r-- | Sjit/Compile.dcl | 8 | ||||
-rw-r--r-- | Sjit/Compile.icl | 19 | ||||
-rw-r--r-- | Sjit/Run.icl | 16 | ||||
-rw-r--r-- | sjit_c.c | 68 |
4 files changed, 55 insertions, 56 deletions
diff --git a/Sjit/Compile.dcl b/Sjit/Compile.dcl index fd4b2ee..d373e42 100644 --- a/Sjit/Compile.dcl +++ b/Sjit/Compile.dcl @@ -17,10 +17,10 @@ from Sjit.Syntax import :: Function | Ret | Halt - | IAddRet - | IMulRet - | ISubRet - | IDivRet + | IAdd + | IMul + | ISub + | IDiv | PlaceHolder !Int !Int // only used during compilation diff --git a/Sjit/Compile.icl b/Sjit/Compile.icl index 8fd81a2..527676f 100644 --- a/Sjit/Compile.icl +++ b/Sjit/Compile.icl @@ -64,10 +64,6 @@ where header :: [(!String, ![Instr])] header = [ ("_", [PushI 0,Call 0 /* main address */,Halt]) - , ("+", [IAddRet]) - , ("*", [IMulRet]) - , ("-", [ISubRet]) - , ("/", [IDivRet]) ] initJITState :: !Int -> JITState @@ -105,10 +101,10 @@ where JmpTrue _ -> 0 Ret -> -1 Halt -> -2 - IAddRet -> -1 - IMulRet -> -1 - ISubRet -> -1 - IDivRet -> -1 + IAdd -> -1 + IMul -> -1 + ISub -> -1 + IDiv -> -1 PlaceHolder _ n -> n reserve :: !Int !CompileState -> m (!Int, !CompileState) | Monad m @@ -155,7 +151,12 @@ where expr (App f args) cs # args = if (args=:[]) [Int 0] args = foldM (flip expr) cs (reverse args) >>= \cs -> case get f cs.funs of - Nothing -> Left ("undefined function '" +++ toString f +++ "'") + Nothing -> case f of + "+" -> gen [IAdd] cs + "-" -> gen [ISub] cs + "*" -> gen [IMul] cs + "/" -> gen [IDiv] cs + _ -> Left ("undefined function '" +++ toString f +++ "'") Just f -> case length args of 1 -> gen [Call f] cs n -> gen [Pop (n-1),Call f] cs diff --git a/Sjit/Run.icl b/Sjit/Run.icl index e3e623f..ad03e02 100644 --- a/Sjit/Run.icl +++ b/Sjit/Run.icl @@ -33,14 +33,14 @@ where [r] -> r _ -> abort (toString (length stack) +++ " values left on stack\n") - IAddRet -> case stack of - [ret:a:b:stack] -> exec ret [a:a+b:stack] - IMulRet -> case stack of - [ret:a:b:stack] -> exec ret [a:a*b:stack] - ISubRet -> case stack of - [ret:a:b:stack] -> exec ret [a:a-b:stack] - IDivRet -> case stack of - [ret:a:b:stack] -> exec ret [a:a/b:stack] + IAdd -> case stack of + [a:b:stack] -> exec (i+1) [a+b:stack] + IMul -> case stack of + [a:b:stack] -> exec (i+1) [a*b:stack] + ISub -> case stack of + [a:b:stack] -> exec (i+1) [a-b:stack] + IDiv -> case stack of + [a:b:stack] -> exec (i+1) [a/b:stack] get_program :: !CompileState -> Program get_program cs @@ -16,10 +16,10 @@ enum instr { Ret, Halt, - IAddRet, - IMulRet, - ISubRet, - IDivRet + IAdd, + IMul, + ISub, + IDiv }; static inline uint32_t instr_size(enum instr instr) { @@ -35,10 +35,10 @@ static inline uint32_t instr_size(enum instr instr) { case Ret: return 1; case Halt: return 1+1; - case IAddRet: - case ISubRet: return 5+5+3+5+1; - case IMulRet: return 5+5+4+5+1; - case IDivRet: return 5+5+3+3+5+1; + case IAdd: + case ISub: return 1+4+3+4; + case IMul: return 1+4+4+4; + case IDiv: return 1+4+3+3+4; default: fprintf(stderr,"unknown instruction %d\n",instr); @@ -160,45 +160,43 @@ static inline void gen_instr(char *full_code, char **code_p, uint64_t **pgm_p, u code+=2; break; - case IAddRet: - case IMulRet: - case ISubRet: - case IDivRet: + case IAdd: + case IMul: + case ISub: + case IDiv: #ifdef DEBUG_JIT_INSTRUCTIONS - fprintf(stderr,"I<Op>Ret\n"); + fprintf(stderr,"I<Op>\n"); #endif - /* mov rax,[rsp+8] */ - code[0]='\x48'; code[1]='\x8b'; code[2]='\x44'; code[3]='\x24'; code[4]='\x08'; - /* mov rcx,[rsp+16] */ - code[5]='\x48'; code[6]='\x8b'; code[7]='\x4c'; code[8]='\x24'; code[9]='\x10'; + /* pop rax */ + code[0]='\x58'; + /* mov rcx,[rsp] */ + code[1]='\x48'; code[2]='\x8b'; code[3]='\x0c'; code[4]='\x24'; switch (*pgm) { - case IAddRet: - case ISubRet: + case IAdd: + case ISub: /* {add,sub} rax,rcx */ - code[10]='\x48'; - code[11]=*pgm==IAddRet ? '\x01' : '\x29'; - code[12]='\xc8'; - code+=13; + code[5]='\x48'; + code[6]=*pgm==IAdd ? '\x01' : '\x29'; + code[7]='\xc8'; + code+=8; break; - case IMulRet: + case IMul: /* imul rax,rcx */ - code[10]='\x48'; code[11]='\x0f'; code[12]='\xaf'; code[13]='\xc1'; - code+=14; + code[5]='\x48'; code[6]='\x0f'; code[7]='\xaf'; code[8]='\xc1'; + code+=9; break; - case IDivRet: + case IDiv: /* xor rdx,rdx */ - code[10]='\x48'; code[11]='\x31'; code[12]='\xd2'; + code[5]='\x48'; code[6]='\x31'; code[7]='\xd2'; /* idiv rcx */ - code[13]='\x48'; code[14]='\xf7'; code[15]='\xf9'; - code+=16; + code[8]='\x48'; code[9]='\xf7'; code[10]='\xf9'; + code+=11; break; } - /* mov [rsp+16],rax */ - code[0]='\x48'; code[1]='\x89'; code[2]='\x44'; code[3]='\x24'; code[4]='\x10'; - /* retq */ - code[5]='\xc3'; + /* mov [rsp],rax */ + code[0]='\x48'; code[1]='\x89'; code[2]='\x04'; code[3]='\x24'; pgm++; - code+=6; + code+=4; break; default: |