/* Copyright 2019 0KIMS association. This file is part of websnark (Web Assembly zkSnark Prover). websnark is a free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. websnark is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with websnark. If not, see . */ module.exports = function buildMem(module, prefix, prefixField) { function buildCopy() { const f = module.addFunction(prefix+"copy"); f.addParam("s", "i32"); f.addParam("d", "i32"); f.addParam("n", "i32"); f.addLocal("bytesAfter", "i32"); f.addLocal("sp", "i32"); const c = f.getCodeBuilder(); f.addCode( c.setLocal( "n64", c.i32_shl( c.getLocal("n"), c.i32_const(3) ) ), c.setLocal( "bytesAfter", c.i32_and( c.getLocal("n"), c.i32_const(0x7) ) ), c.setLocal("sp", c.getLocal("s")), c.setLocal("dp", c.getLocal("d")), c.setLocal("lastsp", c.add( c.getLocal("s"), c.i32_and( c.getLocal("n"), c.i32_const(0xFFFFFFF8) ) ) ), c.block(c.loop( c.br_if( 1, c.i32_eq( c.getLocal("sp"), c.getLocal("lastsp") ) ), c.i64_store( c.getLocal("dp"), c.i64_load( c.getLocal("sp") ) ), c.setLocal("sp", c.i32_add(c.getLocal("sp"), c.i32_const(8))), c.setLocal("dp", c.i32_add(c.getLocal("dp"), c.i32_const(8))), c.br(0) )), c.if( c.getLocal("bytesAfter"), [ ...c.if( c.i32_and(c.getLocal("bytesAfter"), c.i32_const(0x4)), [ ...c.i32_store( c.getLocal("dp"), c.i32_load( c.getLocal("sp") ) ), ...c.setLocal("sp", c.i32_add(c.getLocal("sp"), c.i32_const(4))), ...c.setLocal("dp", c.i32_add(c.getLocal("dp"), c.i32_const(4))), ] ), ...c.if( c.i32_and(c.getLocal("bytesAfter"), c.i32_const(0x2)), [ ...c.i32_store16( c.getLocal("dp"), c.i32_load16( c.getLocal("sp") ) ), ...c.setLocal("sp", c.i32_add(c.getLocal("sp"), c.i32_const(2))), ...c.setLocal("dp", c.i32_add(c.getLocal("dp"), c.i32_const(2))), ] ), ...c.if( c.i32_and(c.getLocal("bytesAfter"), c.i32_const(0x1)), c.i32_store8( c.getLocal("dp"), c.i32_load8( c.getLocal("sp") ) ) ) ] ) ); } buildCopy(); module.exportFunction(prefix+"_copy"); return prefix; };