Explorar o código

fixed 8 bits register limitations

Nicolas Cannasse %!s(int64=7) %!d(string=hai) anos
pai
achega
a4daa03a1c
Modificáronse 1 ficheiros con 32 adicións e 15 borrados
  1. 32 15
      src/jit.c

+ 32 - 15
src/jit.c

@@ -192,7 +192,8 @@ typedef enum {
 	RADDR = 4,
 	RMEM = 5,
 	RUNUSED = 6,
-	RCPU_CALL = 1 | 8
+	RCPU_CALL = 1 | 8,
+	RCPU_8BITS = 1 | 16
 } preg_kind;
 
 typedef struct {
@@ -944,6 +945,7 @@ static preg *alloc_reg( jit_ctx *ctx, preg_kind k ) {
 	switch( k ) {
 	case RCPU:
 	case RCPU_CALL:
+	case RCPU_8BITS:
 		{
 			int off = ctx->allocOffset++;
 			const int count = RCPU_SCRATCH_COUNT;
@@ -952,6 +954,7 @@ static preg *alloc_reg( jit_ctx *ctx, preg_kind k ) {
 				p = ctx->pregs + r;
 				if( p->lock >= ctx->currentPos ) continue;
 				if( k == RCPU_CALL && is_call_reg(p) ) continue;
+				if( k == RCPU_8BITS && !is_reg8(p) ) continue;
 				if( p->holds == NULL ) {
 					RLOCK(p);
 					return p;
@@ -961,6 +964,7 @@ static preg *alloc_reg( jit_ctx *ctx, preg_kind k ) {
 				preg *p = ctx->pregs + RCPU_SCRATCH_REGS[(i + off)%count];
 				if( p->lock >= ctx->currentPos ) continue;
 				if( k == RCPU_CALL && is_call_reg(p) ) continue;
+				if( k == RCPU_8BITS && !is_reg8(p) ) continue;
 				if( p->holds ) {
 					RLOCK(p);
 					p->holds->current = NULL;
@@ -1072,6 +1076,7 @@ static preg *alloc_cpu( jit_ctx *ctx, vreg *r, bool andLoad ) {
 	return p;
 }
 
+// allocate a register that is not a call parameter
 static preg *alloc_cpu_call( jit_ctx *ctx, vreg *r ) {
 	preg *p = fetch(r);
 	if( p->kind != RCPU ) {
@@ -1114,6 +1119,23 @@ static preg *alloc_cpu64( jit_ctx *ctx, vreg *r, bool andLoad ) {
 #	endif
 }
 
+// make sure the register can be used with 8 bits access
+static preg *alloc_cpu8( jit_ctx *ctx, vreg *r, bool andLoad ) {
+	preg *p = fetch(r);
+	if( p->kind != RCPU ) {
+		p = alloc_reg(ctx, RCPU_8BITS);
+		load(ctx,p,r);
+	} else if( !is_reg8(p) ) {
+		preg *p2 = alloc_reg(ctx, RCPU_8BITS);
+		op64(ctx,MOV,p2,p);
+		scratch(p);
+		reg_bind(r,p2);
+		return p2;
+	} else
+		RLOCK(p);
+	return p;
+}
+
 static preg *copy( jit_ctx *ctx, preg *to, preg *from, int size ) {
 	if( size == 0 || to == from ) return to;
 	switch( ID2(to->kind,from->kind) ) {
@@ -1141,7 +1163,8 @@ static preg *copy( jit_ctx *ctx, preg *to, preg *from, int size ) {
 				preg *r = alloc_reg(ctx, RCPU_CALL);				
 				op32(ctx, MOV, r, from);
 				RUNLOCK(r);
-				from = r;
+				op32(ctx,MOV8,to,r);
+				return from;
 			}
 			op32(ctx,MOV8,to,from);
 			break;
@@ -1323,7 +1346,7 @@ static void push_reg( jit_ctx *ctx, vreg *r ) {
 	switch( stack_size(r->t) ) {
 	case 1:
 		op64(ctx,SUB,PESP,pconst(&p,1));
-		op32(ctx,MOV8,pmem(&p,Esp,0),alloc_cpu(ctx,r,true));
+		op32(ctx,MOV8,pmem(&p,Esp,0),alloc_cpu8(ctx,r,true));
 		break;
 	case 2:
 		op64(ctx,SUB,PESP,pconst(&p,2));
@@ -2020,8 +2043,8 @@ static void op_jump( jit_ctx *ctx, vreg *a, vreg *b, hl_opcode *op, int targetPo
 		break;
 	case HNULL:
 		{
-			preg *pa = alloc_cpu(ctx,a,true);
-			preg *pb = alloc_cpu(ctx,b,true);
+			preg *pa = a->size == 1 ? alloc_cpu8(ctx,a,true) : alloc_cpu(ctx,a,true);
+			preg *pb = b->size == 1 ? alloc_cpu8(ctx,b,true) : alloc_cpu(ctx,b,true);
 			if( op->op == OJEq ) {
 				// if( a == b || (a && b && a->b == b->v) ) goto
 				int ja, jb;
@@ -2936,14 +2959,8 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 		case OJNotNull:
 		case OJNull:
 			{
-				preg *r = alloc_cpu(ctx, dst, true);
-				int op = dst->t->kind == HBOOL ? TEST8 : TEST;
-				if( op == TEST8 && !is_reg8(r) ) {
-					op32(ctx,SHL,r,pconst(&p,24));
-					op32(ctx,SHR,r,pconst(&p,24));
-					op32(ctx, TEST, r, r);
-				} else
-					op64(ctx, op, r, r);
+				preg *r = dst->t->kind == HBOOL ? alloc_cpu8(ctx, dst, true) : alloc_cpu(ctx, dst, true);
+				op64(ctx, dst->t->kind == HBOOL ? TEST8 : TEST, r, r);
 				XJump( o->op == OJFalse || o->op == OJNull ? JZero : JNotZero,jump);
 				register_jump(ctx,jump,(opCount + 1) + o->p2);
 			}
@@ -3536,7 +3553,7 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 			{
 				preg *base = alloc_cpu(ctx, ra, true);
 				preg *offset = alloc_cpu64(ctx, rb, true);
-				preg *r = alloc_reg(ctx,RCPU);
+				preg *r = alloc_reg(ctx,o->op == OGetI8 ? RCPU_8BITS : RCPU);
 				op64(ctx,XOR,r,r);
 				op32(ctx, o->op == OGetI8 ? MOV8 : MOV16,r,pmem2(&p,base->id,offset->id,1,0));
 				store(ctx, dst, r, true);
@@ -3553,7 +3570,7 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 			{
 				preg *base = alloc_cpu(ctx, dst, true);
 				preg *offset = alloc_cpu64(ctx, ra, true);
-				preg *value = alloc_cpu(ctx, rb, true);
+				preg *value = alloc_cpu8(ctx, rb, true);
 				op32(ctx,MOV8,pmem2(&p,base->id,offset->id,1,0),value);
 			}
 			break;