コード例 #1
0
ファイル: synthetic.c プロジェクト: iainkfraser/TooLegitToJit
void syn_max( struct machine_ops* mop, struct emitter* e, struct machine* m, operand d, operand s, operand t ){
	mop->blt( e, m, s, t, LBL_NEXT( 0 ) );
	mop->move( e, m, d, t );
	mop->b( e, m, LBL_NEXT( 1 ) );
	e->ops->label_local( e, 0 );
	mop->move( e, m, d, s );
	e->ops->label_local( e, 1 );
}
コード例 #2
0
ファイル: synthetic.c プロジェクト: iainkfraser/TooLegitToJit
void syn_memsetw( struct machine_ops* mop, struct emitter* e, struct machine* m, operand d, operand v, operand size ){
	operand iter = OP_TARGETREG( acquire_temp( mop, e, m ) );			
	operand dst = OP_TARGETREG( acquire_temp( mop, e, m ) );

	// init iterator
	mop->move( e, m, iter, OP_TARGETIMMED( 0 ) );
	mop->move( e, m, dst, d );
	
	// start loop 
	e->ops->label_local( e, 0 );
	mop->beq( e, m, iter, size, LBL_NEXT( 0 ) );  

	// copy 
	mop->move( e, m, OP_TARGETDADDR( dst.reg, 0 ), v );
	
	// update pointers 
	mop->add( e, m, dst, dst, OP_TARGETIMMED( 4 ) );
	
	// update iterator
	mop->add( e, m, iter, iter, OP_TARGETIMMED( 1 ) );
	
	mop->b( e, m, LBL_PREV( 0 ) );
	e->ops->label_local( e, 0 );
	
	release_tempn( mop, e, m, 2 );
}
コード例 #3
0
ファイル: synthetic.c プロジェクト: iainkfraser/TooLegitToJit
// this function could be inline
void syn_memcpyw( struct machine_ops* mop, struct emitter* e, struct machine* m, operand d, operand s, operand size ){
	operand iter = OP_TARGETREG( acquire_temp( mop, e, m ) );			
	operand src = OP_TARGETREG( acquire_temp( mop, e, m ) );
	operand dst = OP_TARGETREG( acquire_temp( mop, e, m ) );

	// init iterator
	mop->move( e, m, iter, OP_TARGETIMMED( 0 ) );
	mop->move( e, m, src, s );
	mop->move( e, m, dst, d );
	
	// start loop 
	e->ops->label_local( e, 0 );
	mop->beq( e, m, iter, size, LBL_NEXT( 0 ) );  

	// copy 
	mop->move( e, m, OP_TARGETDADDR( dst.reg, 0 ), OP_TARGETDADDR( src.reg, 0 ) );
	
	// update pointers 
	mop->add( e, m, dst, dst, OP_TARGETIMMED( -4 ) );	// TODO: this is incorrect in general but correct for copyargs
	mop->add( e, m, src, src, OP_TARGETIMMED( -4 ) ); 
	
	// update iterator
	mop->add( e, m, iter, iter, OP_TARGETIMMED( 1 ) );
	
	mop->b( e, m, LBL_PREV( 0 ) );
	e->ops->label_local( e, 0 );
	
	release_tempn( mop, e, m, 3 );
}
コード例 #4
0
ファイル: xlogue.c プロジェクト: giannitedesco/TooLegitToJit
static void do_nilling( struct machine_ops* mop, struct emitter* e, struct machine* m, 
		operand iter, operand limit, operand dst ){

	// start loop 
	e->ops->label_local( e, 0 );
	mop->beq( e, m, iter, limit, LBL_NEXT( 0 ) ); 	// TODO: bgt is equiv to beq so swap? 

	// copy 
	mop->move( e, m, OP_TARGETDADDR( dst.reg, -4 ), OP_TARGETIMMED( LUA_TNIL ) );
	
	// update pointers 
	mop->add( e, m, dst, dst, OP_TARGETIMMED( -8 ) );	
	
	// update iterator
	mop->add( e, m, iter, iter, OP_TARGETIMMED( 1 ) );
	
	mop->b( e, m, LBL_PREV( 0 ) );
	e->ops->label_local( e, 0 );
}
コード例 #5
0
ファイル: libranch.c プロジェクト: iainkfraser/TooLegitToJit
static lua_Number ljc_relational( lua_Number st, lua_Number sv
					, lua_Number tt, lua_Number tv
					, int op ) {
	assert( !( st == LUA_TNUMBER && tt == LUA_TNUMBER ) );
	
	struct TValue s = { .t = st, .v = (union Value)sv };
	struct TValue t = { .t = tt, .v = (union Value)tv };
	
	switch( op ){
		case REL_LT:
			return do_lt( &s, &t ); 
		case REL_LEQ:
			return do_leq( &s, &t );
		case REL_EQ:
			return do_eq( &s, &t );
		default:
			assert( false );	
	}
}


typedef void (*arch_rel)( struct emitter*, struct machine*
					, operand, operand, label );

static void emit_relational( struct emitter *me, struct machine_ops *mop
					, struct frame* f 
					, loperand s, loperand t
					, arch_rel ar, int op
					, bool expect ){

	vreg_operand os = loperand_to_operand( f, s ),
			ot = loperand_to_operand( f, t );

	unsigned int pc = me->ops->pc( me ) + 2;
	label l = LBL_PC( pc );

	// determine if coercion is required 
	operand tag = OP_TARGETREG( acquire_temp( mop, me, f->m ) );
	mop->bor( me, f->m, tag, os.type, ot.type );
	mop->beq( me, f->m, tag, OP_TARGETIMMED( 0 ), LBL_NEXT( 0 ) );

	// do coercion 
	mop->call_static_cfn( me, f, (uintptr_t)&ljc_relational
					, &tag, 5, os.type, os.value 
					, ot.type, ot.value
					, OP_TARGETIMMED( op ) ); 
	mop->beq( me, f->m, tag, OP_TARGETIMMED( expect ), l );
	mop->b( me, f->m, LBL_NEXT( 1 ) );	

	// do primitive relational  
	me->ops->label_local( me, 0 );
	ar( me, f->m, os.value, ot.value, l );
	me->ops->label_local( me, 1 );
	

	release_temp( mop, me, f->m );	

	return;
}

void emit_jmp( struct emitter** mce, struct machine_ops* mop
					, struct frame *f
					, loperand a
					, int offset ){
	assert( a.islocal );

	// if not zero then any upvalues below the vreg need to be closed.
	if( a.index > 0 ){
		vreg_operand op = vreg_to_operand( f, a.index + 1, true );
		operand base = OP_TARGETREG( acquire_temp( mop, REF, f->m ) );
		address_of( mop, REF, f->m, base, op.type );  
		mop->call_static_cfn( REF, f, (uintptr_t)&closure_close, NULL
				, 1
				, base ); 
		release_temp( mop, REF, f->m ); 
	}
	
	unsigned int pc = (int)REF->ops->pc( REF ) + offset + 1;
	mop->b( REF, f->m, LBL_PC( pc ) ); 
}