소스 검색

more jit support

Nicolas Cannasse 9 년 전
부모
커밋
edca282c08
1개의 변경된 파일67개의 추가작업 그리고 36개의 파일을 삭제
  1. 67 36
      src/jit.c

+ 67 - 36
src/jit.c

@@ -252,6 +252,7 @@ struct jit_ctx {
 
 #define jit_exit() { hl_debug_break(); exit(-1); }
 #define jit_error(msg)	_jit_error(ctx,msg,__LINE__)
+static void _jit_error( jit_ctx *ctx, const char *msg, int line );
 
 static preg *pmem( preg *r, CpuReg reg, int offset ) {
 	r->kind = RMEM;
@@ -1126,9 +1127,15 @@ static int prepare_call_args( jit_ctx *ctx, int count, int *args, vreg *vregs, b
 			size += pad;
 		}
 		switch( r->size ) {
-		case 4:
 		case 1:
+			op64(ctx,SUB,PESP,pconst(&p,1));
+			op32(ctx,MOV8,pmem(&p,Esp,0),alloc_cpu(ctx,r,true));
+			RUNLOCK(r->current);
+			break;
 		case 2:
+			BREAK();
+			break;
+		case 4:
 			if( !IS_64 ) {
 				if( r->current != NULL && r->current->kind == RFPU ) scratch(r->current);
 				op32(ctx,PUSH,fetch(r),UNUSED);
@@ -1136,6 +1143,7 @@ static int prepare_call_args( jit_ctx *ctx, int count, int *args, vreg *vregs, b
 				// pseudo push32 (not available)
 				op64(ctx,SUB,PESP,pconst(&p,4));
 				op32(ctx,MOV,pmem(&p,Esp,0),alloc_cpu(ctx,r,true));
+				RUNLOCK(r->current);
 			}
 			break;
 		case 8:
@@ -1501,13 +1509,46 @@ static void register_jump( jit_ctx *ctx, int pos, int target ) {
 		ctx->opsPos[target] = -1;
 }
 
-static void op_jump( jit_ctx *ctx, vreg *a, vreg *b, hl_opcode *op, int targetPos ) {
+static void dyn_value_compare( jit_ctx *ctx, preg *a, preg *b, hl_type *t ) {
 	preg p;
-	if( a->t->kind == HDYN || b->t->kind == HDYN ) {
+	switch( t->kind ) {
+	case HI8:
+	case HBOOL:
+		op32(ctx,MOV8,a,pmem(&p,a->id,8));
+		op32(ctx,MOV8,b,pmem(&p,b->id,8));
+		op64(ctx,CMP8,a,b);
+		break;
+	case HI16:
 		jit_error("TODO");
-		return;
+		break;
+	case HI32:
+		op32(ctx,MOV,a,pmem(&p,a->id,8));
+		op32(ctx,MOV,b,pmem(&p,b->id,8));
+		op64(ctx,CMP,a,b);
+		break;
+	case HF32:
+		jit_error("TODO");
+		break;
+	case HF64:
+		jit_error("TODO");
+		break;
+	default:
+		jit_error("TODO");
+		break;
 	}
-	switch( a->t->kind ) {
+}
+
+static void op_jump( jit_ctx *ctx, vreg *a, vreg *b, hl_opcode *op, int targetPos ) {
+	if( a->t->kind == HDYN || b->t->kind == HDYN ) {
+		int args[] = { a->stack.id, b->stack.id };
+		int size = prepare_call_args(ctx,2,args,ctx->vregs,true,0);
+		call_native(ctx,hl_dyn_compare,size);
+		op32(ctx,TEST,PEAX,PEAX);
+		if( op->op == OJSGt || op->op == OJSGte ) {
+			jit_error("TODO");
+			return;
+		}
+	} else switch( a->t->kind ) {
 	case HI16:
 		jit_error("TODO");
 		return;
@@ -1524,9 +1565,23 @@ static void op_jump( jit_ctx *ctx, vreg *a, vreg *b, hl_opcode *op, int targetPo
 		{
 			preg *pa = alloc_cpu(ctx,a,true);
 			preg *pb = alloc_cpu(ctx,b,true);
-			if( op->op == OJEq )
-				jit_error("TODO");
-			else if( op->op == OJNotEq ) {
+			if( op->op == OJEq ) {
+				// if( a == b || (a && b && a->b == b->v) ) goto
+				int ja, jb;
+				// if( a != b && (!a || !b || a->v != b->v) ) goto
+				op64(ctx,CMP,pa,pb);
+				register_jump(ctx,do_jump(ctx,OJEq,false),targetPos);
+				op64(ctx,TEST,pa,pa);
+				XJump_small(JZero,ja);
+				op64(ctx,TEST,pb,pb);
+				XJump_small(JZero,jb);
+				dyn_value_compare(ctx,pa,pb,a->t->tparam);
+				register_jump(ctx,do_jump(ctx,OJEq,false),targetPos);
+				scratch(pa);
+				scratch(pb);
+				patch_jump(ctx,ja);
+				patch_jump(ctx,jb);
+			} else if( op->op == OJNotEq ) {
 				int jeq, jcmp;
 				// if( a != b && (!a || !b || a->v != b->v) ) goto
 				op64(ctx,CMP,pa,pb);
@@ -1535,32 +1590,7 @@ static void op_jump( jit_ctx *ctx, vreg *a, vreg *b, hl_opcode *op, int targetPo
 				register_jump(ctx,do_jump(ctx,OJEq,false),targetPos);
 				op64(ctx,TEST,pb,pb);
 				register_jump(ctx,do_jump(ctx,OJEq,false),targetPos);
-
-				switch( a->t->tparam->kind ) {
-				case HI8:
-				case HBOOL:
-					op32(ctx,MOV8,pa,pmem(&p,pa->id,8));
-					op32(ctx,MOV8,pb,pmem(&p,pb->id,8));
-					op64(ctx,CMP8,pa,pb);
-					break;
-				case HI16:
-					jit_error("TODO");
-					break;
-				case HI32:
-					op32(ctx,MOV,pa,pmem(&p,pa->id,8));
-					op32(ctx,MOV,pb,pmem(&p,pb->id,8));
-					op64(ctx,CMP,pa,pb);
-					break;
-				case HF32:
-					jit_error("TODO");
-					break;
-				case HF64:
-					jit_error("TODO");
-					break;
-				default:
-					jit_error("TODO");
-					break;
-				}
+				dyn_value_compare(ctx,pa,pb,a->t->tparam);
 				XJump_small(JZero,jcmp);
 				scratch(pa);
 				scratch(pb);
@@ -1598,7 +1628,7 @@ static void op_jump( jit_ctx *ctx, vreg *a, vreg *b, hl_opcode *op, int targetPo
 				op64(ctx,TEST,pb,pb);
 				XJump_small(JZero,jb);
 				op_call_fun(ctx,NULL,(int)a->t->obj->rt->compareFun,2,args);
-				op64(ctx,TEST,PEAX,PEAX);
+				op32(ctx,TEST,PEAX,PEAX);
 				XJump_small(JNotZero,jcmp);
 				patch_jump(ctx,jeq);
 				register_jump(ctx,do_jump(ctx,OJAlways,false),targetPos);
@@ -1616,7 +1646,7 @@ static void op_jump( jit_ctx *ctx, vreg *a, vreg *b, hl_opcode *op, int targetPo
 				register_jump(ctx,do_jump(ctx,OJEq,false),targetPos);
 
 				op_call_fun(ctx,NULL,(int)a->t->obj->rt->compareFun,2,args);
-				op64(ctx,TEST,PEAX,PEAX);
+				op32(ctx,TEST,PEAX,PEAX);
 				XJump_small(JZero,jcmp);
 
 				register_jump(ctx,do_jump(ctx,OJNotEq,false),targetPos);
@@ -2155,6 +2185,7 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 #				ifdef HL_64
 				jit_error("TODO");
 #				else
+				scratch(tmp);
 				size = prepare_call_args(ctx,o->p3,o->extra,ctx->vregs,false,4);
 				if( r->holds != ra ) r = alloc_cpu(ctx, ra, true);
 				op64(ctx, PUSH,pmem(&p,r->id,HL_WSIZE*3),UNUSED); // push closure value