/*
This file is part of jpcsp.
Jpcsp is 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.
Jpcsp 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 Jpcsp. If not, see <http://www.gnu.org/licenses/>.
*/
package jpcsp.Allegrex.compiler.nativeCode;
import jpcsp.Allegrex.compiler.Compiler;
/**
* @author gid15
*
*/
public class MemcpySequence extends AbstractNativeCodeSequence implements INativeCodeSequence {
static public void call(int dstAddrReg, int srcAddrReg, int lengthReg) {
int dstAddr = getRegisterValue(dstAddrReg);
int srcAddr = getRegisterValue(srcAddrReg);
int length = getRegisterValue(lengthReg);
getMemory().memcpy(dstAddr, srcAddr, length);
// Update registers
setRegisterValue(dstAddrReg, dstAddr + length);
setRegisterValue(srcAddrReg, srcAddr + length);
setRegisterValue(lengthReg, 0);
}
static public void call(int dstAddrReg, int srcAddrReg, int lengthReg, int dstOffset, int srcOffset) {
int dstAddr = getRegisterValue(dstAddrReg);
int srcAddr = getRegisterValue(srcAddrReg);
int length = getRegisterValue(lengthReg);
getMemory().memcpy(dstAddr + dstOffset, srcAddr + srcOffset, length);
// Update registers
setRegisterValue(dstAddrReg, dstAddr + length);
setRegisterValue(srcAddrReg, srcAddr + length);
setRegisterValue(lengthReg, 0);
}
static public void call(int dstAddrReg, int srcAddrReg, int targetAddrReg, int targetReg) {
int dstAddr = getRegisterValue(dstAddrReg);
int srcAddr = getRegisterValue(srcAddrReg);
int targetAddr = getRegisterValue(targetAddrReg);
int length = targetAddr - getRegisterValue(targetReg);
getMemory().memcpy(dstAddr, srcAddr, length);
// Update registers
setRegisterValue(dstAddrReg, dstAddr + length);
setRegisterValue(srcAddrReg, srcAddr + length);
}
static public void call(int dstAddrReg, int srcAddrReg, int targetAddrReg, int targetReg, int dstOffset, int srcOffset, int valueReg, int valueBytes) {
int dstAddr = getRegisterValue(dstAddrReg);
int srcAddr = getRegisterValue(srcAddrReg);
int targetAddr = getRegisterValue(targetAddrReg);
int length = targetAddr - getRegisterValue(targetReg);
getMemory().memcpy(dstAddr + dstOffset, srcAddr + srcOffset, length);
// Update registers
setRegisterValue(dstAddrReg, dstAddr + length);
setRegisterValue(srcAddrReg, srcAddr + length);
// Update the register "valueReg" with the last value processed by the memcpy loop
int valueAddr = srcAddr + length - valueBytes;
int value;
switch (valueBytes) {
case 1: value = getMemory().read8(valueAddr); break;
case 2: value = getMemory().read16(valueAddr); break;
case 4: value = getMemory().read32(valueAddr); break;
default: value = 0; Compiler.log.error("MemcpySequence.call(): Unimplemented valueBytes=" + valueBytes); break;
}
setRegisterValue(valueReg, value);
}
static public void callWithStep(int dstAddrReg, int srcAddrReg, int lengthReg, int step, int lengthOffset) {
int dstAddr = getRegisterValue(dstAddrReg);
int srcAddr = getRegisterValue(srcAddrReg);
int length = (getRegisterValue(lengthReg) + lengthOffset) * step;
getMemory().memcpy(dstAddr, srcAddr, length);
// Update registers
setRegisterValue(dstAddrReg, dstAddr + length);
setRegisterValue(srcAddrReg, srcAddr + length);
setRegisterValue(lengthReg, 0);
}
static public void callWithCountStep(int dstAddrReg, int srcAddrReg, int lengthReg, int count, int step) {
int dstAddr = getRegisterValue(dstAddrReg);
int srcAddr = getRegisterValue(srcAddrReg);
int length = (count - getRegisterValue(lengthReg)) * step;
getMemory().memcpy(dstAddr, srcAddr, length);
// Update registers
setRegisterValue(dstAddrReg, dstAddr + length);
setRegisterValue(srcAddrReg, srcAddr + length);
setRegisterValue(lengthReg, count);
}
static public void callFixedLength(int dstAddrReg, int srcAddrReg, int dstOffset, int srcOffset, int length) {
int dstAddr = getRegisterValue(dstAddrReg) + dstOffset;
int srcAddr = getRegisterValue(srcAddrReg) + srcOffset;
getMemory().memcpy(dstAddr, srcAddr, length);
}
static public void callFixedLength(int dstAddrReg, int srcAddrReg, int dstOffset, int srcOffset, int length, int updatedSrcAddrReg) {
int dstAddr = getRegisterValue(dstAddrReg) + dstOffset;
int srcAddr = getRegisterValue(srcAddrReg) + srcOffset;
getMemory().memcpy(dstAddr, srcAddr, length);
setRegisterValue(updatedSrcAddrReg, srcAddr);
}
static public void callIndirectLength(int dstAddrReg, int srcAddrReg, int lengthAddrReg, int lengthAddrOffset) {
int dstAddr = getRegisterValue(dstAddrReg);
int srcAddr = getRegisterValue(srcAddrReg);
int length = getMemory().read32(getRegisterValue(lengthAddrReg) + lengthAddrOffset);
getMemory().memcpy(dstAddr, srcAddr, length);
// Update registers
setRegisterValue(dstAddrReg, dstAddr + length);
setRegisterValue(srcAddrReg, srcAddr + length);
}
}