Extended SET to include virtual dynamic way of setting bits on offset/register cases

This commit is contained in:
DataHoarder 2021-08-03 22:20:59 +02:00
parent ec5421ff3c
commit 86f808291b

View file

@ -167,7 +167,67 @@ namespace Instruction {
addOperator("POLL_NOTEQUALS", 6, Poll::fromNonEqualTokens);
addOperator("PNE", 6, Poll::fromNonEqualTokens); //TODO: redo
addOperator("SET", 3, Set::fromTokens);
//This allows both static and dynamic calls, with multiple offsets
addOperator("SET", 3, [](const parseOperatorResult &op, const std::vector<Token> &tokens) -> std::unique_ptr<Instruction> {
if (tokens.at(1).getType() == Token::Type::Immediate && tokens.at(2).getType() == Token::Type::Immediate) {
return Set::fromTokens(op, tokens);
} else {
auto c = std::make_unique<Container>("SET op, extended with registers");
//Get register if needed due to offset
if (op.offset1) {
c->addInstruction(std::make_unique<Copy>(AddressWithOffset{(uint32_t) MgmtRegisters::std_SCRATCH_0, 0},
AddressWithOffset{tokens.at(0).getNumericValue(), op.offset1}));
}
//S0 = (Register & ~maskValue)
if (tokens.at(2).getType() == Token::Type::Immediate) {
c->addInstruction(std::make_unique<CalcImm>(Calc::Operation::AND, 0, (uint32_t) MgmtRegisters::std_SCRATCH_0,
op.offset1 ? (uint32_t) MgmtRegisters::std_SCRATCH_0 : tokens.at(
0).getNumericValue(), ~tokens.at(2).getNumericValue()));
} else {
if (op.offset2) {
c->addInstruction(std::make_unique<Copy>(AddressWithOffset{(uint32_t) MgmtRegisters::std_SCRATCH_1, 0},
AddressWithOffset{tokens.at(2).getNumericValue(), op.offset2}));
}
//NOT without offset
c->addInstruction(std::make_unique<Calc>(Calc::Operation::SUB, 0,
(uint32_t) MgmtRegisters::std_SCRATCH_1,
(uint32_t) MgmtRegisters::INTERNAL_REGISTER_ALWAYS_FFFFFFFF,
op.offset2 ? (uint32_t) MgmtRegisters::std_SCRATCH_1 : tokens.at(
2).getNumericValue()));
c->addInstruction(std::make_unique<Calc>(Calc::Operation::AND, 0, (uint32_t) MgmtRegisters::std_SCRATCH_0,
op.offset1 ? (uint32_t) MgmtRegisters::std_SCRATCH_0 : tokens.at(
0).getNumericValue(), (uint32_t) MgmtRegisters::std_SCRATCH_1));
}
//Register = S0 | value
if (tokens.at(1).getType() == Token::Type::Immediate) {
c->addInstruction(std::make_unique<CalcImm>(Calc::Operation::OR, 0,
op.offset1 ? (uint32_t) MgmtRegisters::std_SCRATCH_0 : tokens.at(
0).getNumericValue(), (uint32_t) MgmtRegisters::std_SCRATCH_0,
tokens.at(1).getNumericValue()));
} else {
if (op.offset3) {
c->addInstruction(std::make_unique<Copy>(AddressWithOffset{(uint32_t) MgmtRegisters::std_SCRATCH_1, 0},
AddressWithOffset{tokens.at(1).getNumericValue(), op.offset2}));
}
c->addInstruction(std::make_unique<Calc>(Calc::Operation::OR, 0,
op.offset1 ? (uint32_t) MgmtRegisters::std_SCRATCH_0 : tokens.at(
0).getNumericValue(), (uint32_t) MgmtRegisters::std_SCRATCH_0,
op.offset3 ? (uint32_t) MgmtRegisters::std_SCRATCH_1 : tokens.at(
1).getNumericValue()));
}
//set register if needed due to offset
if (op.offset1) {
c->addInstruction(std::make_unique<Copy>(AddressWithOffset{tokens.at(0).getNumericValue(), op.offset1},
AddressWithOffset{(uint32_t) MgmtRegisters::std_SCRATCH_0, 0}));
}
return std::move(c);
}
});
addOperator("LOOP", 1, Loop::fromTokens);