aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Sjit/Compile.dcl8
-rw-r--r--Sjit/Compile.icl19
-rw-r--r--Sjit/Run.icl16
-rw-r--r--sjit_c.c68
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
diff --git a/sjit_c.c b/sjit_c.c
index 325de47..caae10f 100644
--- a/sjit_c.c
+++ b/sjit_c.c
@@ -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: