From 513beace42e50c9cbbd2aae5f9678f62701cda8d Mon Sep 17 00:00:00 2001 From: Petr Rockai <me@mornfall.net> Date: Sat, 22 Jun 2019 13:40:51 +0000 Subject: [PATCH] VM: Move and rename dbg::print::opcode() to vm::opname(). --- divine/dbg/print.cpp | 112 --------------------------------- divine/dbg/print.hpp | 5 -- divine/dbg/print.tpp | 5 +- divine/vm/opnames.cpp | 141 ++++++++++++++++++++++++++++++++++++++++++ divine/vm/opnames.hpp | 7 +++ 5 files changed, 151 insertions(+), 119 deletions(-) create mode 100644 divine/vm/opnames.cpp create mode 100644 divine/vm/opnames.hpp diff --git a/divine/dbg/print.cpp b/divine/dbg/print.cpp index cf91c9791..3e613d81d 100644 --- a/divine/dbg/print.cpp +++ b/divine/dbg/print.cpp @@ -25,117 +25,6 @@ using namespace std::literals; namespace divine::dbg::print { -#define HANDLE_INST(num, opc, class) [num] = #opc ## s, -static std::string _opcode[] = { "", -#include <llvm/IR/Instruction.def> -}; -#undef HANDLE_INST - -void opcode_tolower() -{ - static bool done = false; - if ( done ) - return; - for ( int i = 0; i < int( sizeof( _opcode ) / sizeof( _opcode[0] ) ); ++i ) - std::transform( _opcode[i].begin(), _opcode[i].end(), - _opcode[i].begin(), ::tolower ); - done = true; -} - -std::string opcode( int op ) -{ - if ( op == lx::OpDbgCall ) - return "dbg.call"; - if ( op == lx::OpDbg ) - return "dbg"; - if ( op == lx::OpHypercall ) - return "vm"; - opcode_tolower(); - return _opcode[ op ]; -} - -template< typename I > -decltype( I::opcode, std::string() ) opcode( I &insn ) -{ - std::string op = opcode( insn.opcode ); - if ( insn.opcode == llvm::Instruction::ICmp ) - switch ( insn.subcode ) - { - case llvm::ICmpInst::ICMP_EQ: op += ".eq"; break; - case llvm::ICmpInst::ICMP_NE: op += ".ne"; break; - case llvm::ICmpInst::ICMP_ULT: op += ".ult"; break; - case llvm::ICmpInst::ICMP_UGE: op += ".uge"; break; - case llvm::ICmpInst::ICMP_UGT: op += ".ugt"; break; - case llvm::ICmpInst::ICMP_ULE: op += ".ule"; break; - case llvm::ICmpInst::ICMP_SLT: op += ".slt"; break; - case llvm::ICmpInst::ICMP_SGT: op += ".sgt"; break; - case llvm::ICmpInst::ICMP_SLE: op += ".sle"; break; - case llvm::ICmpInst::ICMP_SGE: op += ".sge"; break; - default: UNREACHABLE( "unexpected icmp predicate" ); break; - } - if ( insn.opcode == llvm::Instruction::FCmp ) - switch ( insn.subcode ) - { - case llvm::FCmpInst::FCMP_OEQ: op += ".oeq"; break; - case llvm::FCmpInst::FCMP_ONE: op += ".one"; break; - case llvm::FCmpInst::FCMP_OLE: op += ".ole"; break; - case llvm::FCmpInst::FCMP_OLT: op += ".olt"; break; - case llvm::FCmpInst::FCMP_OGE: op += ".oge"; break; - case llvm::FCmpInst::FCMP_OGT: op += ".ogt"; break; - - case llvm::FCmpInst::FCMP_UEQ: op += ".ueq"; break; - case llvm::FCmpInst::FCMP_UNE: op += ".une"; break; - case llvm::FCmpInst::FCMP_ULE: op += ".ule"; break; - case llvm::FCmpInst::FCMP_ULT: op += ".ult"; break; - case llvm::FCmpInst::FCMP_UGE: op += ".uge"; break; - case llvm::FCmpInst::FCMP_UGT: op += ".ugt"; break; - - case llvm::FCmpInst::FCMP_FALSE: op += ".false"; break; - case llvm::FCmpInst::FCMP_TRUE: op += ".true"; break; - case llvm::FCmpInst::FCMP_ORD: op += ".ord"; break; - case llvm::FCmpInst::FCMP_UNO: op += ".uno"; break; - default: UNREACHABLE( "unexpected fcmp predicate" ); break; - } - if ( insn.opcode == lx::OpDbg ) - switch ( insn.subcode ) - { - case lx::DbgValue: op += ".value"; break; - case lx::DbgDeclare: op += ".declare"; break; - case lx::DbgBitCast: op += ".bitcast"; break; - default: UNREACHABLE( "unexpected debug opcode" ); break; - } - if ( insn.opcode == lx::OpHypercall ) - switch ( insn.subcode ) - { - case lx::HypercallChoose: op += ".choose"; break; - case lx::HypercallFault: op += ".fault"; break; - - case lx::HypercallCtlSet: op += ".ctl.set"; break; - case lx::HypercallCtlGet: op += ".ctl.get"; break; - case lx::HypercallCtlFlag: op += ".ctl.flag"; break; - - case lx::HypercallTestCrit: op += ".test.crit"; break; - case lx::HypercallTestLoop: op += ".test.loop"; break; - case lx::HypercallTestTaint: op += ".test.taint"; break; - - case lx::HypercallPeek: op += ".peek"; break; - case lx::HypercallPoke: op += ".poke"; break; - - case lx::HypercallTrace : op += ".trace"; break; - case lx::HypercallSyscall: op += ".syscall"; break; - - case lx::HypercallObjMake: op += ".obj.make"; break; - case lx::HypercallObjFree: op += ".obj.free"; break; - case lx::HypercallObjShared: op += ".obj.shared"; break; - case lx::HypercallObjResize: op += ".obj.resize"; break; - case lx::HypercallObjSize: op += ".obj.size"; break; - case lx::HypercallObjClone: op += ".obj.clone"; break; - - default: UNREACHABLE( "unexpected hypercall opcode" ); break; - } - return op; -} - template< typename Heap > std::string raw( Heap &heap, vm::HeapPointer hloc, int sz ) { @@ -178,6 +67,5 @@ std::string raw( Heap &heap, vm::HeapPointer hloc, int sz ) template struct Print< dbg::Context< vm::CowHeap > >; template struct Print< dbg::DNContext< vm::CowHeap > >; template std::string raw< vm::CowHeap >( vm::CowHeap &, vm::HeapPointer, int ); -template std::string opcode< vm::Program::Instruction >( vm::Program::Instruction & ); } diff --git a/divine/dbg/print.hpp b/divine/dbg/print.hpp index 834ade3da..2d822c62c 100644 --- a/divine/dbg/print.hpp +++ b/divine/dbg/print.hpp @@ -37,8 +37,6 @@ namespace divine::dbg::print namespace lx = vm::lx; -std::string opcode( int ); - static void pad( std::ostream &o, int &col, int target ) { while ( col < target ) @@ -66,9 +64,6 @@ void ascbyte( std::ostream &o, int &col, B byte ) enum class DisplayVal { Name, Value, PreferName }; -template< typename I > -decltype( I::opcode, std::string() ) opcode( I &insn ); - template< typename Ctx > struct Print { diff --git a/divine/dbg/print.tpp b/divine/dbg/print.tpp index 533795c86..2e28b29b9 100644 --- a/divine/dbg/print.tpp +++ b/divine/dbg/print.tpp @@ -18,6 +18,7 @@ #include <divine/dbg/print.hpp> #include <divine/vm/eval.tpp> +#include <divine/vm/opnames.hpp> #include <brick-llvm> using namespace std::literals; @@ -95,7 +96,7 @@ std::string Print< Ctx >::instruction( int padding, int colmax ) auto I = dbg.find( nullptr, eval.pc() ).first; if ( !I ) - return opcode( insn ); + return vm::opname( insn ); bool printres = true; @@ -104,7 +105,7 @@ std::string Print< Ctx >::instruction( int padding, int colmax ) else printres = false; - out << opcode( insn ) << " "; + out << vm::opname( insn ) << " "; uint64_t skipMask = 0; int argc = I->getNumOperands(); diff --git a/divine/vm/opnames.cpp b/divine/vm/opnames.cpp new file mode 100644 index 000000000..2839885bb --- /dev/null +++ b/divine/vm/opnames.cpp @@ -0,0 +1,141 @@ +// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- + +/* + * (c) 2016 Petr RoÄŤkai <code@fixp.eu> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <divine/dbg/print.tpp> +#include <divine/dbg/context.hpp> +#include <divine/vm/eval.tpp> + +using namespace std::literals; + +namespace divine::vm +{ + +#define HANDLE_INST(num, opc, class) [num] = #opc ## s, + static std::string _opname[] = { "", +#include <llvm/IR/Instruction.def> + }; +#undef HANDLE_INST + + static void opnames_tolower() + { + static bool done = false; + if ( done ) + return; + for ( int i = 0; i < int( sizeof( _opname ) / sizeof( _opname[0] ) ); ++i ) + std::transform( _opname[i].begin(), _opname[i].end(), + _opname[i].begin(), ::tolower ); + done = true; + } + + std::string opname( int op ) + { + if ( op == lx::OpDbgCall ) + return "dbg.call"; + if ( op == lx::OpDbg ) + return "dbg"; + if ( op == lx::OpHypercall ) + return "vm"; + opnames_tolower(); + return _opname[ op ]; + } + + template< typename I > + decltype( I::opcode, std::string() ) opname( I &insn ) + { + std::string op = opname( insn.opcode ); + if ( insn.opcode == llvm::Instruction::ICmp ) + switch ( insn.subcode ) + { + case llvm::ICmpInst::ICMP_EQ: op += ".eq"; break; + case llvm::ICmpInst::ICMP_NE: op += ".ne"; break; + case llvm::ICmpInst::ICMP_ULT: op += ".ult"; break; + case llvm::ICmpInst::ICMP_UGE: op += ".uge"; break; + case llvm::ICmpInst::ICMP_UGT: op += ".ugt"; break; + case llvm::ICmpInst::ICMP_ULE: op += ".ule"; break; + case llvm::ICmpInst::ICMP_SLT: op += ".slt"; break; + case llvm::ICmpInst::ICMP_SGT: op += ".sgt"; break; + case llvm::ICmpInst::ICMP_SLE: op += ".sle"; break; + case llvm::ICmpInst::ICMP_SGE: op += ".sge"; break; + default: UNREACHABLE( "unexpected icmp predicate" ); break; + } + if ( insn.opcode == llvm::Instruction::FCmp ) + switch ( insn.subcode ) + { + case llvm::FCmpInst::FCMP_OEQ: op += ".oeq"; break; + case llvm::FCmpInst::FCMP_ONE: op += ".one"; break; + case llvm::FCmpInst::FCMP_OLE: op += ".ole"; break; + case llvm::FCmpInst::FCMP_OLT: op += ".olt"; break; + case llvm::FCmpInst::FCMP_OGE: op += ".oge"; break; + case llvm::FCmpInst::FCMP_OGT: op += ".ogt"; break; + + case llvm::FCmpInst::FCMP_UEQ: op += ".ueq"; break; + case llvm::FCmpInst::FCMP_UNE: op += ".une"; break; + case llvm::FCmpInst::FCMP_ULE: op += ".ule"; break; + case llvm::FCmpInst::FCMP_ULT: op += ".ult"; break; + case llvm::FCmpInst::FCMP_UGE: op += ".uge"; break; + case llvm::FCmpInst::FCMP_UGT: op += ".ugt"; break; + + case llvm::FCmpInst::FCMP_FALSE: op += ".false"; break; + case llvm::FCmpInst::FCMP_TRUE: op += ".true"; break; + case llvm::FCmpInst::FCMP_ORD: op += ".ord"; break; + case llvm::FCmpInst::FCMP_UNO: op += ".uno"; break; + default: UNREACHABLE( "unexpected fcmp predicate" ); break; + } + if ( insn.opcode == lx::OpDbg ) + switch ( insn.subcode ) + { + case lx::DbgValue: op += ".value"; break; + case lx::DbgDeclare: op += ".declare"; break; + case lx::DbgBitCast: op += ".bitcast"; break; + default: UNREACHABLE( "unexpected debug opcode" ); break; + } + if ( insn.opcode == lx::OpHypercall ) + switch ( insn.subcode ) + { + case lx::HypercallChoose: op += ".choose"; break; + case lx::HypercallFault: op += ".fault"; break; + + case lx::HypercallCtlSet: op += ".ctl.set"; break; + case lx::HypercallCtlGet: op += ".ctl.get"; break; + case lx::HypercallCtlFlag: op += ".ctl.flag"; break; + + case lx::HypercallTestCrit: op += ".test.crit"; break; + case lx::HypercallTestLoop: op += ".test.loop"; break; + case lx::HypercallTestTaint: op += ".test.taint"; break; + + case lx::HypercallPeek: op += ".peek"; break; + case lx::HypercallPoke: op += ".poke"; break; + + case lx::HypercallTrace : op += ".trace"; break; + case lx::HypercallSyscall: op += ".syscall"; break; + + case lx::HypercallObjMake: op += ".obj.make"; break; + case lx::HypercallObjFree: op += ".obj.free"; break; + case lx::HypercallObjShared: op += ".obj.shared"; break; + case lx::HypercallObjResize: op += ".obj.resize"; break; + case lx::HypercallObjSize: op += ".obj.size"; break; + case lx::HypercallObjClone: op += ".obj.clone"; break; + + default: UNREACHABLE( "unexpected hypercall opcode" ); break; + } + return op; + } + + template std::string opname< vm::Program::Instruction >( vm::Program::Instruction & ); + +} diff --git a/divine/vm/opnames.hpp b/divine/vm/opnames.hpp new file mode 100644 index 000000000..da706a8c1 --- /dev/null +++ b/divine/vm/opnames.hpp @@ -0,0 +1,7 @@ +namespace divine::vm +{ + std::string opname( int ); + + template< typename I > + decltype( I::opcode, std::string() ) opname( I &insn ); +} -- GitLab