case InstructionSet::ADD:
if ((instruction.isRegisterInPosition(0) || instruction.isRegisterInPosition(1)) && (instruction.numOprands > 1)) {
Registers reg = Registers::UNKNOWN;
Registers reg1 = Registers::UNKNOWN;
RegisterSizes regSize = RegisterSizes::ZERO;
RegisterSizes regSize1 = RegisterSizes::ZERO;
Byte* data = nullptr;
Byte* data1 = nullptr;
if (instruction.isRegisterInPosition(0)) {
reg = Registers(instruction.args[0].doubleWord);
regSize = registerToSize(reg);
} else {
std::cerr<<"ElectroCraft CPU: Invaid arguments for ADD!"<<std::endl;
break;
}
if (instruction.isRegisterInPosition(1)) {
reg1 = Registers(instruction.args[1].doubleWord);
regSize1 = registerToSize(reg1);
} else {
data1 = doubleWordToBytes(instruction.args[1]);
}
if (reg != Registers::UNKNOWN) {
switch (regSize) {
case RegisterSizes::FOUR:
data = memory->readData(getRegisterData(reg), 4);
break;
case RegisterSizes::TWO:
data = memory->readData(getRegisterData(reg), 2);
case RegisterSizes::ONE:
data = memory->readData(getRegisterData(reg), 1);
default:
break;
}
} else {
std::cerr<<"ElectroCraft CPU: Invaid arguments for ADD!"<<std::endl;
break;
}
if (reg1 != Registers::UNKNOWN) {
switch (regSize1) {
case RegisterSizes::FOUR:
data1 = memory->readData(getRegisterData(reg1), 4);
break;
case RegisterSizes::TWO:
data1 = memory->readData(getRegisterData(reg1), 2);
case RegisterSizes::ONE:
data1 = memory->readData(getRegisterData(reg1), 1);
default:
break;
}
}
if(data != nullptr && data1 != nullptr) {
if (regSize != RegisterSizes::ZERO && regSize1 != RegisterSizes::ZERO) {
if (regSize == RegisterSizes::FOUR || regSize1 == RegisterSizes::FOUR) {
DoubleWord result;
if (regSize < regSize1) {
std::cerr<<"ElectroCraft CPU: Invaid arguments for ADD: First register too small for storage!"<<std::endl;
} else if(regSize > regSize1) {
DoubleWord value = readDoubleWord(data);
if (regSize == RegisterSizes::TWO) {
DoubleWord::Word value1 = readWord(data);
result.doubleWord = value.doubleWord + value1.lowWord.word;
} else {
result.doubleWord = value.doubleWord + data1[0];
}
memory->writeData(getRegisterData(reg), 4, doubleWordToBytes(result));
} else {
DoubleWord value = readDoubleWord(data);
DoubleWord value1 = readDoubleWord(data1);
result.doubleWord = value.doubleWord + value1.doubleWord;
memory->writeData(getRegisterData(reg), 4, doubleWordToBytes(result));
}
} else if (regSize == RegisterSizes::TWO || regSize1 == RegisterSizes::TWO) {
DoubleWord::Word result;
if (regSize < regSize1) {
std::cerr<<"ElectroCraft CPU: Invaid arguments for ADD: First register too small for storage!"<<std::endl;
} else if(regSize > regSize1) {
DoubleWord::Word value = readWord(data);
result.lowWord.word = value.lowWord.word + data1[0];
memory->writeData(getRegisterData(reg), 2, wordToBytes(result));
} else {
DoubleWord::Word value = readWord(data);
DoubleWord::Word value1 = readWord(data1);
result.lowWord.word = value.lowWord.word + value1.lowWord.word;
memory->writeData(getRegisterData(reg), 2, wordToBytes(result));
}
} else {
Byte result = data[0] + data1[0];
memory->writeData(getRegisterData(reg), 1, &result);
}
} else if (regSize != RegisterSizes::ZERO && data1 != nullptr) {
DoubleWord result;
if (regSize == RegisterSizes::FOUR) {
DoubleWord value = readDoubleWord(data);
result.doubleWord = value.doubleWord + readDoubleWord(data1).doubleWord;
memory->writeData(getRegisterData(reg), 4, doubleWordToBytes(result));
} else if (regSize == RegisterSizes::TWO) {
DoubleWord::Word value = readWord(data);
result.word.lowWord.word = value.lowWord.word + readDoubleWord(data1).doubleWord;
memory->writeData(getRegisterData(reg), 2, wordToBytes(result.word));
} else if (regSize == RegisterSizes::ONE) {
result.word.lowWord.byte.lowByte = data[0] + readDoubleWord(data1).doubleWord;
memory->writeData(getRegisterData(reg), 1, static_cast<Byte*>(&result.word.lowWord.byte.lowByte));
} else {
std::cerr<<"ElectroCraft CPU: Invaid arguments for ADD!"<<std::endl;
}
} else {
std::cerr<<"ElectroCraft CPU: Invaid arguments for ADD!"<<std::endl;
}
} else {
std::cerr<<"ElectroCraft CPU: Invaid arguments for ADD!"<<std::endl;
}
} else {
std::cerr<<"ElectroCraft CPU: Invaid arguments for ADD!"<<std::endl;
}
break;