Extended SET to include virtual dynamic way of setting bits on offset/register cases
This commit is contained in:
parent
ec5421ff3c
commit
86f808291b
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue