소스 검색

added OSwitch, OEndTrap, fixed OJump to function start

Nicolas Cannasse 9 년 전
부모
커밋
82cd9ea04c
2개의 변경된 파일54개의 추가작업 그리고 5개의 파일을 삭제
  1. 4 3
      src/code.c
  2. 50 2
      src/jit.c

+ 4 - 3
src/code.c

@@ -289,10 +289,11 @@ static void hl_read_opcode( hl_reader *r, hl_function *f, hl_opcode *o ) {
 			{
 				int i;
 				o->p1 = UINDEX();
-				o->extra = (int*)hl_malloc(&r->code->alloc,sizeof(int) * o->p1);
-				for(i=0;i<o->p1;i++)
-					o->extra[i] = UINDEX();
 				o->p2 = UINDEX();
+				o->extra = (int*)hl_malloc(&r->code->alloc,sizeof(int) * o->p2);
+				for(i=0;i<o->p2;i++)
+					o->extra[i] = UINDEX();
+				o->p3 = UINDEX();
 			}
 			break;
 		default:

+ 50 - 2
src/jit.c

@@ -71,6 +71,7 @@ typedef enum {
 	SAR,
 	INC,
 	DEC,
+	JMP,
 	// SSE
 	MOVSD,
 	MOVSS,
@@ -240,6 +241,7 @@ struct jit_ctx {
 	hl_function *f;
 	jlist *jumps;
 	jlist *calls;
+	jlist *switchs;
 	hl_alloc falloc; // cleared per-function
 	hl_alloc galloc;
 	vclosure *closure_list;
@@ -354,6 +356,7 @@ static opform OP_FORMS[_CPU_LAST] = {
 	{ "SAR", RM(0xD3,7), 0, 0, RM(0xC1,7) },
 	{ "INC", IS_64 ? RM(0xFF,0) : 0x40, RM(0xFF,0) },
 	{ "DEC", IS_64 ? RM(0xFF,1) : 0x48, RM(0xFF,1) },
+	{ "JMP", RM(0xFF,4) },
 	// SSE
 	{ "MOVSD", 0xF20F10, 0xF20F11  },
 	{ "MOVSS", 0xF30F10, 0xF30F11  },
@@ -1688,7 +1691,7 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 	jit_buf(ctx);
 	ctx->functionPos = BUF_POS();
 	op_enter(ctx);
-	ctx->opsPos[0] = 0;
+	ctx->opsPos[0] = BUF_POS();
 
 	for(opCount=0;opCount<f->nops;opCount++) {
 		int jump;
@@ -2380,7 +2383,16 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 			}
 			break;
 		case OEndTrap:
-			jit_error("TODO");
+			{
+				int trap_size = (sizeof(hl_trap_ctx) + 15) & 0xFFF0;
+				preg *r = alloc_reg(ctx, RCPU);
+				hl_trap_ctx *tmp = NULL;
+				BREAK();
+				op64(ctx, MOV, r, paddr(&p,&hl_current_trap));
+				op64(ctx, MOV, r, pmem(&p,r->id,(int)(int_val)&tmp->prev));
+				op64(ctx, MOV, paddr(&p,&hl_current_trap), r);
+				op64(ctx,ADD,PESP,pconst(&p,trap_size));
+			}
 			break;
 		case OEnumIndex:
 			switch( ra->t->kind ) {
@@ -2403,6 +2415,36 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 				jit_error("assert");
 			}
 			break;
+		case OSwitch:
+			{
+				int jdefault;
+				int i;
+				preg *r = alloc_cpu(ctx, dst, true);
+				preg *r2 = alloc_reg(ctx, RCPU);
+				op32(ctx, CMP, r, pconst(&p,o->p2));
+				XJump(JUGte,jdefault);
+				// r2 = r * 5 + eip
+				op32(ctx, MOV, r2, r); 
+				op32(ctx, SHL, r2, pconst(&p,2));
+				op32(ctx, ADD, r2, r);
+				op64(ctx, ADD, r2, pconst64(&p,0));
+				{
+					jlist *s = (jlist*)hl_malloc(&ctx->galloc, sizeof(jlist));
+					s->pos = BUF_POS() - sizeof(void*);
+					s->next = ctx->switchs;
+					ctx->switchs = s;
+				}
+				op64(ctx, JMP, r2, UNUSED);
+				for(i=0;i<o->p2;i++) {
+					int j = do_jump(ctx,OJAlways,false);
+					register_jump(ctx,j,(opCount + 1) + o->extra[i]);
+				}
+				patch_jump(ctx, jdefault);
+			}
+			break;
+		case OGetTID:
+			op32(ctx, MOV, alloc_cpu(ctx,dst,false), pmem(&p,alloc_cpu(ctx,ra,true)->id,0));
+			break;
 		default:
 			{
 				static bool TRACES[OLast] = {false};
@@ -2458,6 +2500,12 @@ void *hl_jit_code( jit_ctx *ctx, hl_module *m, int *codesize ) {
 		*(int*)(code + c->pos + 1) = fpos - (c->pos + 5);
 		c = c->next;
 	}
+	// patch switchs
+	c = ctx->switchs;
+	while( c ) {
+		*(void**)(code + c->pos) = code + c->pos + 6;
+		c = c->next;
+	}
 	// patch closures
 	{
 		vclosure *c = ctx->closure_list;