virtual void compile(X86Compiler& c) { c.newFunc(kX86FuncConvDefault, FuncBuilder3<Void, uint32_t*, const uint32_t*, size_t>()); c.getFunc()->setHint(kFuncHintNaked, true); // Omit unnecessary prolog/epilog. Label L_Loop = c.newLabel(); // Create base labels we use Label L_Exit = c.newLabel(); // in our function. GpVar dst(c.getGpArg(0)); // Get reference to function GpVar src(c.getGpArg(1)); // arguments. GpVar cnt(c.getGpArg(2)); c.alloc(dst); // Allocate all registers now, c.alloc(src); // because we want to keep them c.alloc(cnt); // in physical registers only. c.test(cnt, cnt); // Exit if length is zero. c.jz(L_Exit); c.bind(L_Loop); // Bind the loop label here. GpVar tmp(c.newGpVar(kX86VarTypeGpd)); // Copy a single dword (4 bytes). c.mov(tmp, dword_ptr(src)); c.mov(dword_ptr(dst), tmp); c.add(src, 4); // Increment dst/src pointers. c.add(dst, 4); c.dec(cnt); // Loop until cnt isn't zero. c.jnz(L_Loop); c.bind(L_Exit); // Bind the exit label here. c.endFunc(); // End of function. }
virtual void compile(X86Compiler& c) { c.newFunc(kX86FuncConvDefault, FuncBuilder3<int, int, int, int>()); GpVar x(c.getGpArg(0)); GpVar y(c.getGpArg(1)); GpVar op(c.getGpArg(2)); GpVar result; X86CompilerFuncCall* fCall; Label opAdd(c.newLabel()); Label opMul(c.newLabel()); c.cmp(op, 0); c.jz(opAdd); c.cmp(op, 1); c.jz(opMul); result = c.newGpVar(); c.mov(result, imm(0)); c.ret(result); c.bind(opAdd); result = c.newGpVar(); fCall = c.call((void*)calledFuncAdd); fCall->setPrototype(kX86FuncConvDefault, FuncBuilder2<int, int, int>()); fCall->setArgument(0, x); fCall->setArgument(1, y); fCall->setReturn(result); c.ret(result); c.bind(opMul); result = c.newGpVar(); fCall = c.call((void*)calledFuncMul); fCall->setPrototype(kX86FuncConvDefault, FuncBuilder2<int, int, int>()); fCall->setArgument(0, x); fCall->setArgument(1, y); fCall->setReturn(result); c.ret(result); c.endFunc(); }