Compare commits
7 Commits
b130322de5
...
c9798f4816
Author | SHA1 | Date | |
---|---|---|---|
|
c9798f4816 | ||
|
16c84948c2 | ||
|
6746d96fd4 | ||
|
07dcd98e86 | ||
|
7eb95ac130 | ||
|
b881b7f9a2 | ||
|
3b01c3a71c |
346
vm/vm.cpp
346
vm/vm.cpp
@ -128,7 +128,24 @@ void VM::initVariables(void) {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
bool VM::dstRegCheck(uint8_t reg) {
|
||||||
|
if (reg == IP || reg == SP || reg == RP) {
|
||||||
|
DBG_ERROR(("Invalid register!\n"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool VM::srcDstRegCheck(uint8_t dst, uint8_t src) {
|
||||||
|
if (dst == IP || dst == SP || dst == RP) {
|
||||||
|
DBG_ERROR(("Invalid register!\n"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (src == IP || src == SP || src == RP) {
|
||||||
|
DBG_ERROR(("Invalid register!\n"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
INSTRUCTIONS IMPLEMENTATIONS
|
INSTRUCTIONS IMPLEMENTATIONS
|
||||||
*/
|
*/
|
||||||
@ -142,8 +159,7 @@ bool VM::execMOVI(void) {
|
|||||||
dst = as.code[regs[IP] + 1];
|
dst = as.code[regs[IP] + 1];
|
||||||
imm = *((uint16_t *)&as.code[regs[IP] + 2]);
|
imm = *((uint16_t *)&as.code[regs[IP] + 2]);
|
||||||
DBG_INFO(("MOVI %s, 0x%x\n", getRegName(dst), imm));
|
DBG_INFO(("MOVI %s, 0x%x\n", getRegName(dst), imm));
|
||||||
if (dst == IP) {
|
if (!dstRegCheck(dst)) {
|
||||||
DBG_ERROR(("Can't MOVI to IP!\n"));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
regs[dst] = imm;
|
regs[dst] = imm;
|
||||||
@ -160,8 +176,7 @@ bool VM::execMOVR(void) {
|
|||||||
dst = as.code[regs[IP] + 1] >> 4;
|
dst = as.code[regs[IP] + 1] >> 4;
|
||||||
src = as.code[regs[IP] + 1] & 0b00001111;
|
src = as.code[regs[IP] + 1] & 0b00001111;
|
||||||
DBG_INFO(("MOVR %s, %s\n", getRegName(dst), getRegName(src)));
|
DBG_INFO(("MOVR %s, %s\n", getRegName(dst), getRegName(src)));
|
||||||
if (dst == IP || src == IP) {
|
if (!srcDstRegCheck(src, dst)) {
|
||||||
DBG_ERROR(("Can't MOVR IP!\n"));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
regs[dst] = regs[src];
|
regs[dst] = regs[src];
|
||||||
@ -177,6 +192,9 @@ bool VM::execLODI(void) {
|
|||||||
dst = as.code[regs[IP] + 1];
|
dst = as.code[regs[IP] + 1];
|
||||||
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
||||||
DBG_INFO(("LODI %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("LODI %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!dstRegCheck(dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] = *((uint16_t *)&as.data[src]);
|
regs[dst] = *((uint16_t *)&as.data[src]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -190,6 +208,9 @@ bool VM::execLODR(void) {
|
|||||||
dst = as.code[regs[IP] + 1] >> 4;
|
dst = as.code[regs[IP] + 1] >> 4;
|
||||||
src = as.code[regs[IP] + 1] & 0b00001111;
|
src = as.code[regs[IP] + 1] & 0b00001111;
|
||||||
DBG_INFO(("LODR %s, %s\n", getRegName(dst), getRegName(src)));
|
DBG_INFO(("LODR %s, %s\n", getRegName(dst), getRegName(src)));
|
||||||
|
if (!srcDstRegCheck(src, dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] = *((uint16_t *)&as.data[regs[src]]);
|
regs[dst] = *((uint16_t *)&as.data[regs[src]]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -202,6 +223,9 @@ bool VM::execSTRI(void) {
|
|||||||
dst = *((uint16_t *)&as.code[regs[IP] + 1]);
|
dst = *((uint16_t *)&as.code[regs[IP] + 1]);
|
||||||
src = as.code[regs[IP] + 3];
|
src = as.code[regs[IP] + 3];
|
||||||
DBG_INFO(("STRI 0x%x, %s\n", dst, getRegName(src)));
|
DBG_INFO(("STRI 0x%x, %s\n", dst, getRegName(src)));
|
||||||
|
if (!dstRegCheck(dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
*((uint16_t *)&as.data[dst]) = regs[src];
|
*((uint16_t *)&as.data[dst]) = regs[src];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -216,6 +240,9 @@ bool VM::execSTRR(void) {
|
|||||||
dst = as.code[regs[IP] + 1] >> 4;
|
dst = as.code[regs[IP] + 1] >> 4;
|
||||||
src = as.code[regs[IP] + 1] & 0b00001111;
|
src = as.code[regs[IP] + 1] & 0b00001111;
|
||||||
DBG_INFO(("STRR %s, %s\n", getRegName(dst), getRegName(src)));
|
DBG_INFO(("STRR %s, %s\n", getRegName(dst), getRegName(src)));
|
||||||
|
if (!srcDstRegCheck(src, dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
*((uint16_t *)&as.data[regs[dst]]) = regs[src];
|
*((uint16_t *)&as.data[regs[dst]]) = regs[src];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -230,6 +257,9 @@ bool VM::execADDI(void) {
|
|||||||
dst = as.code[regs[IP] + 1];
|
dst = as.code[regs[IP] + 1];
|
||||||
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
||||||
DBG_INFO(("ADDI %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("ADDI %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!dstRegCheck(dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] += src;
|
regs[dst] += src;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -244,6 +274,9 @@ bool VM::execADDR(void) {
|
|||||||
dst = as.code[regs[IP] + 1] >> 4;
|
dst = as.code[regs[IP] + 1] >> 4;
|
||||||
src = as.code[regs[IP] + 1] & 0b00001111;
|
src = as.code[regs[IP] + 1] & 0b00001111;
|
||||||
DBG_INFO(("ADDR %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("ADDR %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!srcDstRegCheck(src, dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] += regs[src];
|
regs[dst] += regs[src];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -258,6 +291,9 @@ bool VM::execSUBI(void) {
|
|||||||
dst = as.code[regs[IP] + 1];
|
dst = as.code[regs[IP] + 1];
|
||||||
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
||||||
DBG_INFO(("SUBI %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("SUBI %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!dstRegCheck(dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] -= src;
|
regs[dst] -= src;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -271,6 +307,9 @@ bool VM::execSUBR(void) {
|
|||||||
dst = as.code[regs[IP] + 1] >> 4;
|
dst = as.code[regs[IP] + 1] >> 4;
|
||||||
src = as.code[regs[IP] + 1] & 0b00001111;
|
src = as.code[regs[IP] + 1] & 0b00001111;
|
||||||
DBG_INFO(("SUBR %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("SUBR %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!srcDstRegCheck(src, dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] -= regs[src];
|
regs[dst] -= regs[src];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -284,6 +323,9 @@ bool VM::execANDB(void) {
|
|||||||
dst = as.code[regs[IP] + 1];
|
dst = as.code[regs[IP] + 1];
|
||||||
src = as.code[regs[IP] + 2];
|
src = as.code[regs[IP] + 2];
|
||||||
DBG_INFO(("ANDB %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("ANDB %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!dstRegCheck(dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] &= src;
|
regs[dst] &= src;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -297,6 +339,9 @@ bool VM::execANDW(void) {
|
|||||||
dst = as.code[regs[IP] + 1];
|
dst = as.code[regs[IP] + 1];
|
||||||
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
||||||
DBG_INFO(("XORW %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("XORW %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!dstRegCheck(dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] &= src;
|
regs[dst] &= src;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -310,6 +355,9 @@ bool VM::execANDR(void) {
|
|||||||
dst = as.code[regs[IP] + 1] >> 4;
|
dst = as.code[regs[IP] + 1] >> 4;
|
||||||
src = as.code[regs[IP] + 1] & 0b00001111;
|
src = as.code[regs[IP] + 1] & 0b00001111;
|
||||||
DBG_INFO(("ANDR %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("ANDR %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!srcDstRegCheck(src, dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] &= regs[src];
|
regs[dst] &= regs[src];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -323,6 +371,9 @@ bool VM::execYORB(void) {
|
|||||||
dst = as.code[regs[IP] + 1];
|
dst = as.code[regs[IP] + 1];
|
||||||
src = as.code[regs[IP] + 2];
|
src = as.code[regs[IP] + 2];
|
||||||
DBG_INFO(("YORB %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("YORB %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!dstRegCheck(dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] |= src;
|
regs[dst] |= src;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -336,6 +387,9 @@ bool VM::execYORW(void) {
|
|||||||
dst = as.code[regs[IP] + 1];
|
dst = as.code[regs[IP] + 1];
|
||||||
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
||||||
DBG_INFO(("XORW %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("XORW %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!dstRegCheck(dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] |= src;
|
regs[dst] |= src;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -349,6 +403,9 @@ bool VM::execYORR(void) {
|
|||||||
dst = as.code[regs[IP] + 1] >> 4;
|
dst = as.code[regs[IP] + 1] >> 4;
|
||||||
src = as.code[regs[IP] + 1] & 0b00001111;
|
src = as.code[regs[IP] + 1] & 0b00001111;
|
||||||
DBG_INFO(("XORR %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("XORR %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!srcDstRegCheck(src, dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] |= regs[src];
|
regs[dst] |= regs[src];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -362,6 +419,9 @@ bool VM::execXORB(void) {
|
|||||||
dst = as.code[regs[IP] + 1];
|
dst = as.code[regs[IP] + 1];
|
||||||
src = as.code[regs[IP] + 2];
|
src = as.code[regs[IP] + 2];
|
||||||
DBG_INFO(("XORB %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("XORB %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!dstRegCheck(dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] ^= src;
|
regs[dst] ^= src;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -375,6 +435,9 @@ bool VM::execXORW(void) {
|
|||||||
dst = as.code[regs[IP] + 1];
|
dst = as.code[regs[IP] + 1];
|
||||||
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
||||||
DBG_INFO(("XORW %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("XORW %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!dstRegCheck(dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] ^= src;
|
regs[dst] ^= src;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -388,6 +451,9 @@ bool VM::execXORR(void) {
|
|||||||
dst = as.code[regs[IP] + 1] >> 4;
|
dst = as.code[regs[IP] + 1] >> 4;
|
||||||
src = as.code[regs[IP] + 1] & 0b00001111;
|
src = as.code[regs[IP] + 1] & 0b00001111;
|
||||||
DBG_INFO(("XORR %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("XORR %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!srcDstRegCheck(src, dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] ^= regs[src];
|
regs[dst] ^= regs[src];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -401,6 +467,9 @@ bool VM::execNOTR(void) {
|
|||||||
dst = as.code[regs[IP] + 1] >> 4;
|
dst = as.code[regs[IP] + 1] >> 4;
|
||||||
src = as.code[regs[IP] + 1] & 0b00001111;
|
src = as.code[regs[IP] + 1] & 0b00001111;
|
||||||
DBG_INFO(("NOTR %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("NOTR %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!srcDstRegCheck(src, dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] = ~regs[src];
|
regs[dst] = ~regs[src];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -414,6 +483,9 @@ bool VM::execMULI(void) {
|
|||||||
dst = as.code[regs[IP] + 1];
|
dst = as.code[regs[IP] + 1];
|
||||||
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
||||||
DBG_INFO(("SUBI %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("SUBI %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!dstRegCheck(dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] *= src;
|
regs[dst] *= src;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -427,6 +499,9 @@ bool VM::execMULR(void) {
|
|||||||
dst = as.code[regs[IP] + 1] >> 4;
|
dst = as.code[regs[IP] + 1] >> 4;
|
||||||
src = as.code[regs[IP] + 1] & 0b00001111;
|
src = as.code[regs[IP] + 1] & 0b00001111;
|
||||||
DBG_INFO(("MULR %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("MULR %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!srcDstRegCheck(src, dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] *= regs[src];
|
regs[dst] *= regs[src];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -440,6 +515,9 @@ bool VM::execDIVI(void) {
|
|||||||
dst = as.code[regs[IP] + 1];
|
dst = as.code[regs[IP] + 1];
|
||||||
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
||||||
DBG_INFO(("DIVI %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("DIVI %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!dstRegCheck(dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] /= src;
|
regs[dst] /= src;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -453,6 +531,9 @@ bool VM::execDIVR(void) {
|
|||||||
dst = as.code[regs[IP] + 1] >> 4;
|
dst = as.code[regs[IP] + 1] >> 4;
|
||||||
src = as.code[regs[IP] + 1] & 0b00001111;
|
src = as.code[regs[IP] + 1] & 0b00001111;
|
||||||
DBG_INFO(("DIVR %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("DIVR %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!srcDstRegCheck(src, dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] /= regs[src];
|
regs[dst] /= regs[src];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -466,6 +547,9 @@ bool VM::execSHLI(void) {
|
|||||||
dst = as.code[regs[IP] + 1];
|
dst = as.code[regs[IP] + 1];
|
||||||
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
||||||
DBG_INFO(("SHLI %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("SHLI %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!dstRegCheck(dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] = regs[dst] << src;
|
regs[dst] = regs[dst] << src;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -479,6 +563,9 @@ bool VM::execSHLR(void) {
|
|||||||
dst = as.code[regs[IP] + 1] >> 4;
|
dst = as.code[regs[IP] + 1] >> 4;
|
||||||
src = as.code[regs[IP] + 1] & 0b00001111;
|
src = as.code[regs[IP] + 1] & 0b00001111;
|
||||||
DBG_INFO(("SHLR %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("SHLR %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!srcDstRegCheck(src, dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] = regs[dst] << regs[src];
|
regs[dst] = regs[dst] << regs[src];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -492,6 +579,9 @@ bool VM::execSHRI(void) {
|
|||||||
dst = as.code[regs[IP] + 1];
|
dst = as.code[regs[IP] + 1];
|
||||||
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
src = *((uint16_t *)&as.code[regs[IP] + 2]);
|
||||||
DBG_INFO(("SHRI %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("SHRI %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!dstRegCheck(dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] = regs[dst] >> src;
|
regs[dst] = regs[dst] >> src;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -505,25 +595,34 @@ bool VM::execSHRR(void) {
|
|||||||
dst = as.code[regs[IP] + 1] >> 4;
|
dst = as.code[regs[IP] + 1] >> 4;
|
||||||
src = as.code[regs[IP] + 1] & 0b00001111;
|
src = as.code[regs[IP] + 1] & 0b00001111;
|
||||||
DBG_INFO(("SHRR %s, 0x%x\n", getRegName(dst), src));
|
DBG_INFO(("SHRR %s, 0x%x\n", getRegName(dst), src));
|
||||||
|
if (!srcDstRegCheck(src, dst)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[dst] = regs[dst] >> regs[src];
|
regs[dst] = regs[dst] >> regs[src];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool VM::execPUSH(void) {
|
bool VM::execPUSH(void) {
|
||||||
// TODO: STACK < 0
|
|
||||||
uint8_t src;
|
uint8_t src;
|
||||||
|
|
||||||
src = as.code[regs[IP] + 1];
|
src = as.code[regs[IP] + 1];
|
||||||
DBG_INFO(("PUSH %s\n", getRegName(src)));
|
DBG_INFO(("PUSH %s\n", getRegName(src)));
|
||||||
|
if (regs[SP] + sizeof(uint16_t) > 0xffff) {
|
||||||
|
DBG_ERROR(("Out of bound: stack is going above 0xFFFF!\n"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
memcpy(&as.stack[regs[SP]], ®s[src], sizeof(uint16_t));
|
memcpy(&as.stack[regs[SP]], ®s[src], sizeof(uint16_t));
|
||||||
regs[SP] += sizeof(uint16_t);
|
regs[SP] += sizeof(uint16_t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool VM::execPOOP(void) {
|
bool VM::execPOOP(void) {
|
||||||
// TODO: STACK < 0
|
|
||||||
uint8_t dst;
|
uint8_t dst;
|
||||||
|
|
||||||
dst = as.code[regs[IP] + 1];
|
dst = as.code[regs[IP] + 1];
|
||||||
DBG_INFO(("POOP %s\n", getRegName(dst)));
|
DBG_INFO(("POOP %s\n", getRegName(dst)));
|
||||||
|
if (regs[SP] - sizeof(uint16_t) < 0) {
|
||||||
|
DBG_ERROR(("Out of bound: stack is going below 0!\n"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
regs[SP] -= sizeof(uint16_t);
|
regs[SP] -= sizeof(uint16_t);
|
||||||
memcpy(®s[dst], &as.stack[regs[SP]], sizeof(uint16_t));
|
memcpy(®s[dst], &as.stack[regs[SP]], sizeof(uint16_t));
|
||||||
return true;
|
return true;
|
||||||
@ -763,107 +862,274 @@ bool VM::execGRMN(void) {
|
|||||||
void VM::run(void) {
|
void VM::run(void) {
|
||||||
uint8_t opcode;
|
uint8_t opcode;
|
||||||
bool finished = false;
|
bool finished = false;
|
||||||
|
bool ret;
|
||||||
while (!finished) {
|
while (!finished) {
|
||||||
opcode = (uint8_t)as.code[regs[IP]];
|
opcode = (uint8_t)as.code[regs[IP]];
|
||||||
if (opcode == OPS[MOVI]) {
|
if (opcode == OPS[MOVI]) {
|
||||||
execMOVI();
|
ret = execMOVI();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += MOVI_SIZE;
|
regs[IP] += MOVI_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("MOVI FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[MOVR]) {
|
} else if (opcode == OPS[MOVR]) {
|
||||||
execMOVR();
|
ret = execMOVR();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += MOVR_SIZE;
|
regs[IP] += MOVR_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("MOVR FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[LODI]) {
|
} else if (opcode == OPS[LODI]) {
|
||||||
execLODI();
|
ret = execLODI();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += LODI_SIZE;
|
regs[IP] += LODI_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("LODI FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[LODR]) {
|
} else if (opcode == OPS[LODR]) {
|
||||||
execLODR();
|
ret = execLODR();
|
||||||
|
if (ret) {
|
||||||
|
regs[IP] += LODR_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("LODR FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
regs[IP] += LODR_SIZE;
|
regs[IP] += LODR_SIZE;
|
||||||
} else if (opcode == OPS[STRI]) {
|
} else if (opcode == OPS[STRI]) {
|
||||||
execSTRI();
|
ret = execSTRI();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += STRI_SIZE;
|
regs[IP] += STRI_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("MOVI FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[STRR]) {
|
} else if (opcode == OPS[STRR]) {
|
||||||
execSTRR();
|
ret = execSTRR();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += STRR_SIZE;
|
regs[IP] += STRR_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("STRR FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[ADDI]) {
|
} else if (opcode == OPS[ADDI]) {
|
||||||
execADDI();
|
ret = execADDI();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += ADDI_SIZE;
|
regs[IP] += ADDI_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("ADDI FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[ADDR]) {
|
} else if (opcode == OPS[ADDR]) {
|
||||||
execADDR();
|
ret = execADDR();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += ADDR_SIZE;
|
regs[IP] += ADDR_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("ADDR FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[SUBI]) {
|
} else if (opcode == OPS[SUBI]) {
|
||||||
execSUBI();
|
ret = execSUBI();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += SUBI_SIZE;
|
regs[IP] += SUBI_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("SUBI FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[SUBR]) {
|
} else if (opcode == OPS[SUBR]) {
|
||||||
execSUBR();
|
ret = execSUBR();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += SUBR_SIZE;
|
regs[IP] += SUBR_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("SUBR FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[ANDB]) {
|
} else if (opcode == OPS[ANDB]) {
|
||||||
execANDB();
|
ret = execANDB();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += ANDB_SIZE;
|
regs[IP] += ANDB_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("ANDB FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[ANDW]) {
|
} else if (opcode == OPS[ANDW]) {
|
||||||
execANDW();
|
ret = execANDW();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += ANDW_SIZE;
|
regs[IP] += ANDW_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("ANDW FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[ANDR]) {
|
} else if (opcode == OPS[ANDR]) {
|
||||||
execANDR();
|
ret = execANDR();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += ANDR_SIZE;
|
regs[IP] += ANDR_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("ANDR FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[YORB]) {
|
} else if (opcode == OPS[YORB]) {
|
||||||
execYORB();
|
ret = execYORB();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += YORB_SIZE;
|
regs[IP] += YORB_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("YORB FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[YORW]) {
|
} else if (opcode == OPS[YORW]) {
|
||||||
execYORW();
|
ret = execYORW();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += YORW_SIZE;
|
regs[IP] += YORW_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("YORW FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[YORR]) {
|
} else if (opcode == OPS[YORR]) {
|
||||||
execYORR();
|
ret = execYORR();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += YORR_SIZE;
|
regs[IP] += YORR_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("YORR FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[XORB]) {
|
} else if (opcode == OPS[XORB]) {
|
||||||
execXORB();
|
ret = execXORB();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += XORB_SIZE;
|
regs[IP] += XORB_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("XORB FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[XORW]) {
|
} else if (opcode == OPS[XORW]) {
|
||||||
execXORW();
|
ret = execXORW();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += XORW_SIZE;
|
regs[IP] += XORW_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("XORW FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[XORR]) {
|
} else if (opcode == OPS[XORR]) {
|
||||||
execXORR();
|
ret = execXORR();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += XORR_SIZE;
|
regs[IP] += XORR_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("XORR FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[NOTR]) {
|
} else if (opcode == OPS[NOTR]) {
|
||||||
execNOTR();
|
ret = execNOTR();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += NOTR_SIZE;
|
regs[IP] += NOTR_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("NOTR FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[MULI]) {
|
} else if (opcode == OPS[MULI]) {
|
||||||
execMULI();
|
ret = execMULI();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += MULI_SIZE;
|
regs[IP] += MULI_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("MULI FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[MULR]) {
|
} else if (opcode == OPS[MULR]) {
|
||||||
execMULR();
|
ret = execMULR();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += MULR_SIZE;
|
regs[IP] += MULR_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("MULR FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[DIVI]) {
|
} else if (opcode == OPS[DIVI]) {
|
||||||
execDIVI();
|
ret = execDIVI();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += DIVI_SIZE;
|
regs[IP] += DIVI_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("DIVI FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[DIVR]) {
|
} else if (opcode == OPS[DIVR]) {
|
||||||
execDIVR();
|
ret = execDIVR();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += DIVR_SIZE;
|
regs[IP] += DIVR_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("DIVR FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[SHLI]) {
|
} else if (opcode == OPS[SHLI]) {
|
||||||
execSHLI();
|
ret = execSHLI();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += SHLI_SIZE;
|
regs[IP] += SHLI_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("SHLI FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[SHLR]) {
|
} else if (opcode == OPS[SHLR]) {
|
||||||
execSHLR();
|
ret = execSHLR();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += SHLR_SIZE;
|
regs[IP] += SHLR_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("SHLR FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[SHRI]) {
|
} else if (opcode == OPS[SHRI]) {
|
||||||
execSHRI();
|
ret = execSHRI();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += SHRI_SIZE;
|
regs[IP] += SHRI_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("SHRI FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[SHRR]) {
|
} else if (opcode == OPS[SHRR]) {
|
||||||
execSHRR();
|
ret = execSHRR();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += SHRR_SIZE;
|
regs[IP] += SHRR_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("SHRR FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[PUSH]) {
|
} else if (opcode == OPS[PUSH]) {
|
||||||
execPUSH();
|
ret = execPUSH();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += PUSH_SIZE;
|
regs[IP] += PUSH_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("PUSH FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[POOP]) {
|
} else if (opcode == OPS[POOP]) {
|
||||||
execPOOP();
|
ret = execPOOP();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += POOP_SIZE;
|
regs[IP] += POOP_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("POOP FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[CMPB]) {
|
} else if (opcode == OPS[CMPB]) {
|
||||||
execCMPB();
|
ret = execCMPB();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += CMPB_SIZE;
|
regs[IP] += CMPB_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("CMPB FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[CMPW]) {
|
} else if (opcode == OPS[CMPW]) {
|
||||||
execCMPW();
|
ret = execCMPW();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += CMPW_SIZE;
|
regs[IP] += CMPW_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("CMPW FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[CMPR]) {
|
} else if (opcode == OPS[CMPR]) {
|
||||||
execCMPR();
|
ret = execCMPR();
|
||||||
|
if (ret) {
|
||||||
regs[IP] += CMPR_SIZE;
|
regs[IP] += CMPR_SIZE;
|
||||||
|
} else {
|
||||||
|
DBG_ERROR(("CMPR FAILED.\n"));
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
} else if (opcode == OPS[JMPI]) {
|
} else if (opcode == OPS[JMPI]) {
|
||||||
execJMPI();
|
execJMPI();
|
||||||
} else if (opcode == OPS[JMPR]) {
|
} else if (opcode == OPS[JMPR]) {
|
||||||
|
3
vm/vm.h
3
vm/vm.h
@ -16,6 +16,9 @@ private:
|
|||||||
///////////////////////
|
///////////////////////
|
||||||
void initVariables(void);
|
void initVariables(void);
|
||||||
void encryptOpcodes(uint8_t *key);
|
void encryptOpcodes(uint8_t *key);
|
||||||
|
bool dstRegCheck(uint8_t reg);
|
||||||
|
bool srcDstRegCheck(uint8_t dst, uint8_t src);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
DBG UTILS
|
DBG UTILS
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user