void Div::Execute() { ResolveValue(1); unsigned int val1; unsigned int quot; if(arguments[1] == 0) { VM_INSTANCE()->GetLogger() << "Divide by zero attempted" << std::endl; return; } switch(subcode[0]) { case SC_REG: val1 = VM_INSTANCE()->GetRegister(arguments[0]); quot = val1 / arguments[1]; VM_INSTANCE()->SetRegister(arguments[0], quot); if(quot > val1) VM_INSTANCE()->SetFlag(FLAG_OFL); else VM_INSTANCE()->ClearFlag(FLAG_OFL); if(quot == 0) VM_INSTANCE()->SetFlag(FLAG_ZERO); else VM_INSTANCE()->ClearFlag(FLAG_ZERO); break; default: VM_INSTANCE()->GetLogger() << "Invalid First Operand For Add: 0x" << std::hex << subcode[0] << std::dec << std::endl; } }
// // Info::trStmnt_Call // void Info::trStmnt_Call() { CheckArgC(stmnt, 2); CheckArgB(stmnt, 1, IR::ArgBase::Lit); for(auto n = stmnt->args.size(); --n != 1;) CheckArgB(stmnt, n, IR::ArgBase::Stk); auto ret = ResolveValue(stmnt->args[1].aLit.value->getValue()); switch(stmnt->args[0].a) { case IR::ArgBase::Lit: if(ret != 0 && ret != 1) { std::cerr << "STUB: " __FILE__ << ':' << __LINE__ << '\n'; throw EXIT_FAILURE; } break; case IR::ArgBase::Stk: if(ret != 0 && ret != 1) { std::cerr << "STUB: " __FILE__ << ':' << __LINE__ << '\n'; throw EXIT_FAILURE; } break; default: std::cerr << "ERROR: " << stmnt->pos << ": bad Call\n"; throw EXIT_FAILURE; } }
void Jmp::Execute() { ResolveValue(0); if(Condition()) { char* target = VM_INSTANCE()->GetMemory(arguments[0]); if(target) VM_INSTANCE()->SetRegister(REG_EIP, arguments[0]); } }
void Loop::Execute() { unsigned int ecx = VM_INSTANCE()->GetRegister(REG_ECX); if(ecx) { ResolveValue(0); if(VM_INSTANCE()->GetMemory(arguments[0])) VM_INSTANCE()->SetRegister(REG_EIP, arguments[0]); VM_INSTANCE()->SetRegister(REG_ECX, ecx - 1); } }
void And::Execute() { ResolveValue(1); unsigned int target; switch(subcode[0]) { case SC_REG: target = VM_INSTANCE()->GetRegister(arguments[0]); target &= arguments[1]; VM_INSTANCE()->SetRegister(arguments[0], target); break; } }
// // Info::trStmnt_Cspe // void Info::trStmnt_Cspe() { CheckArgC(stmnt, 2); CheckArgB(stmnt, 0, IR::ArgBase::Lit); CheckArgB(stmnt, 1, IR::ArgBase::Lit); auto ret = ResolveValue(stmnt->args[1].aLit.value->getValue()); if(ret > 1) { std::cerr << "ERROR: " << stmnt->pos << ": bad Cspe ret\n"; throw EXIT_FAILURE; } // Too many call args. if(stmnt->args.size() > 7) { std::cerr << "ERROR: " << stmnt->pos << ": bad Cspe arg count\n"; throw EXIT_FAILURE; } // No call args. if(stmnt->args.size() == 2) return; switch(stmnt->args[2].a) { case IR::ArgBase::Lit: for(auto n = stmnt->args.size(); n-- != 3;) CheckArgB(stmnt, n, IR::ArgBase::Lit); break; case IR::ArgBase::Stk: for(auto n = stmnt->args.size(); n-- != 3;) CheckArgB(stmnt, n, IR::ArgBase::Stk); break; default: std::cerr << "ERROR: " << stmnt->pos << ": bad Cspe\n"; throw EXIT_FAILURE; } }
void Shr::Execute() { ResolveValue(1); unsigned int val1; unsigned int shr; switch(subcode[0]) { case SC_REG: val1 = VM_INSTANCE()->GetRegister(arguments[0]); shr = val1 >> arguments[1]; VM_INSTANCE()->SetRegister(arguments[0], shr); if(shr == 0) VM_INSTANCE()->SetFlag(FLAG_ZERO); else VM_INSTANCE()->ClearFlag(FLAG_ZERO); break; default: VM_INSTANCE()->GetLogger() << "Invalid First Operand For Shr: 0x" << std::hex << subcode[0] << std::dec << std::endl; } }