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 ); }
// 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 ); }
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 ); }