2
0
Эх сурвалжийг харах

fixed double arg/ret in C->JIT calls

Nicolas Cannasse 9 жил өмнө
parent
commit
96a957446f
2 өөрчлөгдсөн 22 нэмэгдсэн , 6 устгасан
  1. 10 4
      src/callback.c
  2. 12 2
      src/jit.c

+ 10 - 4
src/callback.c

@@ -77,6 +77,12 @@ void *hl_callback( void *f, hl_type *t, void **args, vdynamic *ret ) {
 			break;
 		case 8:
 			*(double*)&stack.b[pos] = *(double*)v;
+			{
+				// SWAP (we push in reverse order in hl_callback_entry !
+				int i = *(int*)&stack.b[pos];
+				*(int*)&stack.b[pos] = *(int*)&stack.b[pos + 4];
+				*(int*)&stack.b[pos + 4] = i;
+			}
 			break;
 		default:
 			hl_error("Invalid callback arg");
@@ -88,16 +94,16 @@ void *hl_callback( void *f, hl_type *t, void **args, vdynamic *ret ) {
 	case HI16:
 	case HI32:
 	case HBOOL:
-		ret->v.i = ((int (*)(void *, void *, int))hl_callback_entry)(f, &stack, (IS_64?pos>>3:pos>>2));
+		ret->v.i = ((int (*)(void *, void *, int, bool))hl_callback_entry)(f, &stack, (IS_64?pos>>3:pos>>2), false);
 		return &ret->v.i;
 	case HF32:
-		ret->v.f = ((float (*)(void *, void *, int))hl_callback_entry)(f, &stack, (IS_64?pos>>3:pos>>2));
+		ret->v.f = ((float (*)(void *, void *, int, bool))hl_callback_entry)(f, &stack, (IS_64?pos>>3:pos>>2), true);
 		return &ret->v.f;
 	case HF64:
-		ret->v.d = ((double (*)(void *, void *, int))hl_callback_entry)(f, &stack, (IS_64?pos>>3:pos>>2));
+		ret->v.d = ((double (*)(void *, void *, int, bool))hl_callback_entry)(f, &stack, (IS_64?pos>>3:pos>>2), true);
 		return &ret->v.d;
 	default:
-		return ((void *(*)(void *, void *, int))hl_callback_entry)(f, &stack, (IS_64?pos>>3:pos>>2));
+		return ((void *(*)(void *, void *, int, bool))hl_callback_entry)(f, &stack, (IS_64?pos>>3:pos>>2), false);
 	}
 }
 

+ 12 - 2
src/jit.c

@@ -76,6 +76,7 @@ typedef enum {
 	JMP,
 	// FPU
 	FSTP,
+	FLD,
 	// SSE
 	MOVSD,
 	MOVSS,
@@ -382,6 +383,7 @@ static opform OP_FORMS[_CPU_LAST] = {
 	{ "JMP", RM(0xFF,4) },
 	// FPU
 	{ "FSTP", 0, RM(0xDD,3) },
+	{ "FLD", 0, RM(0xDD,0) },
 	// SSE
 	{ "MOVSD", 0xF20F10, 0xF20F11  },
 	{ "MOVSS", 0xF30F10, 0xF30F11  },
@@ -1804,7 +1806,7 @@ int hl_jit_init_callback( jit_ctx *ctx ) {
 	CpuReg R8 = Eax;
 #	endif
 	int pos = BUF_POS();
-	int jstart, jcall, jloop;
+	int jstart, jcall, jloop, jfp;
 	preg p;
 
 	jit_buf(ctx);
@@ -1846,6 +1848,14 @@ int hl_jit_init_callback( jit_ctx *ctx ) {
 
 	op64(ctx,CALL,REG_AT(Ecx),UNUSED);
 
+	// if want return float, move XMM0 to x87 stack
+	op64(ctx,MOV,REG_AT(Ecx),pmem(&p,Ebp,HL_WSIZE*5));
+	op64(ctx,TEST,REG_AT(Ecx),REG_AT(Ecx));
+	XJump_small(JZero,jfp);
+	op64(ctx,MOVSD,pmem(&p,Ebp,-8),PXMM(0));
+	op64(ctx,FLD,pmem(&p,Ebp,-8),UNUSED);
+	patch_jump(ctx, jfp);
+
 	// cleanup and ret
 	op64(ctx,MOV,PESP,PEBP);
 	op64(ctx,POP,PEBP, UNUSED);
@@ -2441,7 +2451,7 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 						op64(ctx,PUSH,r,UNUSED);
 						op64(ctx,PUSH,v,UNUSED);
 						call_native(ctx,get_dynget(dst->t),size);
-						store(ctx,dst,IS_FLOAT(dst) ? PXMM(0) : PEAX,true);
+						store_native_result(ctx,dst);
 #						endif
 						XJump_small(JAlways,jend);
 						patch_jump(ctx,jhasfield);