/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Jip J. Dekker * Guido Tack */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include namespace MiniZinc { const std::string BytecodeProc::mode_to_string[] = {"ROOT", "ROOT_NEG", "FUN", "FUN_NEG", "IMP", "IMP_NEG"}; std::string BytecodeStream::toString(const std::vector& procs) const { std::ostringstream oss; int pc = 0; while (pc < _bs.size()) { int cur_pc = pc; switch (instr(pc)) { case BytecodeStream::ADDI: { oss << "ADDI R" << reg(pc) << " R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::SUBI: { oss << "SUBI R" << reg(pc) << " R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::MULI: { oss << "MULI R" << reg(pc) << " R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::DIVI: { oss << "DIVI R" << reg(pc) << " R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::MODI: { oss << "MODI R" << reg(pc) << " R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::INCI: { oss << "INCI R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::DECI: { oss << "DECI R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::IMMI: { oss << "IMMI " << intval(pc).toIntVal() << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::CLEAR: { oss << "CLEAR " << " R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::LOAD_GLOBAL: { oss << "LOAD_GLOBAL " << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::STORE_GLOBAL: { oss << "STORE_GLOBAL R" << reg(pc) << " " << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::MOV: { oss << "MOV R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::JMP: { oss << "JMP " << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::JMPIF: { oss << "JMPIF R" << reg(pc) << " " << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::JMPIFNOT: { oss << "JMPIFNOT R" << reg(pc) << " " << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::EQI: { oss << "EQI R" << reg(pc) << " R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::LTI: { oss << "LTI R" << reg(pc) << " R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::LEI: { oss << "LEI R" << reg(pc) << " R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::AND: { oss << "AND R" << reg(pc) << " R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::OR: { oss << "OR R" << reg(pc) << " R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::NOT: { oss << "NOT R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::XOR: { oss << "XOR R" << reg(pc) << " R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::ISPAR: { oss << "ISPAR R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::ISEMPTY: { oss << "ISEMPTY R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::LENGTH: { oss << "LENGTH R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::GET_VEC: { oss << "GET_VEC R" << reg(pc) << " R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::GET_ARRAY: { oss << "GET_ARRAY "; long long int n = intval(pc).toInt(); oss << n; for (long long int i = 0; i < (n + 3); ++i) { oss << " R" << reg(pc); } oss << " % " << cur_pc << "\n"; } break; case BytecodeStream::LB: { oss << "LB R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::UB: { oss << "UB R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::DOM: { oss << "DOM R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::MAKE_SET: { oss << "MAKE_SET R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::INTERSECTION: { oss << "INTERSECTION R" << reg(pc) << " R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::UNION: { oss << "UNION R" << reg(pc) << " R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::DIFF: { oss << "DIFF R" << reg(pc) << " R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::INTERSECT_DOMAIN: { oss << "INTERSECT_DOMAIN R" << reg(pc) << " R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::RET: { oss << "RET" << " % " << cur_pc << "\n"; } break; case BytecodeStream::CALL: { auto m = static_cast(chr(pc)); int p = reg(pc); bool cse = chr(pc); assert(!procs.empty()); oss << "CALL " << BytecodeProc::mode_to_string[m] << " " << procs[p].name << (cse ? "" : " no_cse") << " "; oss << procs[p].nargs; for (int i = 0; i < procs[p].nargs; i++) { oss << " R" << reg(pc); } oss << " % " << cur_pc << "\n"; } break; case BytecodeStream::BUILTIN: { int p = reg(pc); oss << "BUILTIN " << p << " "; oss << procs[p].nargs; for (int i = 0; i < procs[p].nargs; i++) { oss << " R" << reg(pc); } oss << " % " << cur_pc << "\n"; } break; case BytecodeStream::TCALL: { auto m = static_cast(chr(pc)); int p = reg(pc); bool cse = chr(pc); if (procs.empty()) { oss << "TCALL " << BytecodeProc::mode_to_string[m] << " " << p << (cse ? "" : " no_cse") << " % " << cur_pc << "\n"; } else { oss << "TCALL " << BytecodeProc::mode_to_string[m] << " " << procs[p].name << (cse ? "" : " no_cse") << " % " << cur_pc << "\n"; } } break; case BytecodeStream::ITER_ARRAY: { oss << "ITER_ARRAY" << reg(pc) << " " << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::ITER_VEC: { oss << "ITER_VEC " << reg(pc) << " " << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::ITER_RANGE: { oss << "ITER_RANGE " << reg(pc) << " " << reg(pc) << " " << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::ITER_NEXT: { oss << "ITER_NEXT R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::ITER_BREAK: { oss << "ITER_BREAK " << intval(pc).toString() << " % " << cur_pc << "\n"; } break; case BytecodeStream::OPEN_AGGREGATION: { oss << "OPEN_AGGREGATION "; int p = chr(pc); switch (p) { case AggregationCtx::VCTX_AND: oss << "AND"; break; case AggregationCtx::VCTX_OR: oss << "OR"; break; case AggregationCtx::VCTX_VEC: oss << "VEC"; break; case AggregationCtx::VCTX_OTHER: oss << "OTHER"; break; default: oss << "ERROR"; assert(false); break; } oss << " % " << cur_pc << "\n"; } break; case BytecodeStream::CLOSE_AGGREGATION: { oss << "CLOSE_AGGREGATION" << " % " << cur_pc << "\n"; } break; case BytecodeStream::SIMPLIFY_LIN: { oss << "SIMPLIFY_LIN R" << reg(pc) << " R" << reg(pc) << " " << intval(pc).toIntVal() << " R" << reg(pc) << " R" << reg(pc) << " R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::PUSH: { oss << "PUSH R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::POP: { oss << "POP R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::POST: { oss << "POST R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::TRACE: { oss << "TRACE R" << reg(pc) << " % " << cur_pc << "\n"; } break; case BytecodeStream::ABORT: { oss << "ABORT" << " % " << cur_pc << "\n"; } break; } } return oss.str(); } } // namespace MiniZinc