aboutsummaryrefslogtreecommitdiff
path: root/sjit_c.c
diff options
context:
space:
mode:
Diffstat (limited to 'sjit_c.c')
-rw-r--r--sjit_c.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/sjit_c.c b/sjit_c.c
index 879ec18..325de47 100644
--- a/sjit_c.c
+++ b/sjit_c.c
@@ -11,6 +11,8 @@ enum instr {
Pop,
Call,
+ Jmp,
+ JmpTrue,
Ret,
Halt,
@@ -28,6 +30,8 @@ static inline uint32_t instr_size(enum instr instr) {
case Pop: return 4;
case Call: return 5;
+ case Jmp: return 5;
+ case JmpTrue: return 1+3+6;
case Ret: return 1;
case Halt: return 1+1;
@@ -52,7 +56,7 @@ static inline void gen_instr(char *full_code, char **code_p, uint64_t **pgm_p, u
case PushRef:
arg=pgm[1];
#ifdef DEBUG_JIT_INSTRUCTIONS
- fprintf(stderr,"PushRef %lu\n",arg);
+ fprintf(stderr,"PushRef %ld\n",arg);
#endif
code[0]='\x48'; /* mov rcx,[rsp+ARG*8] */
code[1]='\x8b';
@@ -86,7 +90,7 @@ static inline void gen_instr(char *full_code, char **code_p, uint64_t **pgm_p, u
code[2]='\x89';
code[3]='\x4c';
code[4]='\x24';
- code[5]=(unsigned char)(arg-1)*8;
+ code[5]=(unsigned char)arg*8;
pgm+=2;
code+=6;
break;
@@ -113,6 +117,31 @@ static inline void gen_instr(char *full_code, char **code_p, uint64_t **pgm_p, u
pgm+=2;
code+=5;
break;
+ case Jmp:
+ arg=pgm[1];
+#ifdef DEBUG_JIT_INSTRUCTIONS
+ fprintf(stderr,"Jmp %lu -> %d\n",arg,mapping[arg]-(uint32_t)(&code[5]-full_code));
+#endif
+ code[0]='\xe9'; /* jmpq ARG */
+ *(uint32_t*)&code[1]=mapping[arg]-(&code[5]-full_code);
+ pgm+=2;
+ code+=5;
+ break;
+ case JmpTrue:
+ arg=pgm[1];
+#ifdef DEBUG_JIT_INSTRUCTIONS
+ fprintf(stderr,"JmpTrue %lu -> %d\n",arg,mapping[arg]-(uint32_t)(&code[10]-full_code));
+#endif
+ code[0]='\x59'; /* pop rcx */
+ code[1]='\x48'; /* test rcx,rcx */
+ code[2]='\x85';
+ code[3]='\xc9';
+ code[4]='\x0f'; /* jne ARG */
+ code[5]='\x85';
+ *(uint32_t*)&code[6]=mapping[arg]-(&code[10]-full_code);
+ pgm+=2;
+ code+=10;
+ break;
case Ret:
#ifdef DEBUG_JIT_INSTRUCTIONS
fprintf(stderr,"Ret\n");
@@ -206,6 +235,8 @@ char *jit_append(char *code_block, uint32_t code_len, char *code_ptr,
case Put:
case Pop:
case Call:
+ case Jmp:
+ case JmpTrue:
pgm_p+=2;
break;
default: