// -*- SystemC -*-
//=============================================================================
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2012 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
// This is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
//=============================================================================
///
/// \file
/// \brief SystemPerl common simple utilities, not requiring SystemC
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
#ifndef _SPCOMMON_H_
#define _SPCOMMON_H_ 1
#include <sys/types.h> // uint32_t
#if defined(_MSC_VER)
typedef unsigned __int64 uint64_t;
typedef unsigned __int32 uint32_t;
#else
#include <stdint.h> // uint32_t
#endif
#include <cctype>
#include <cstdlib> // NULL
// Utilities here must NOT require SystemC headers!
//=============================================================================
// Switches
//#define WAVES // Must be defined to do waveform tracing
#if VM_TRACE // Verilator tracing requested
# define WAVES 1 // So, trace in SystemC too
#endif
//#define SP_COVERAGE // Must be defined to do coverage analysis
#if VM_COVERAGE // Verilator coverage requested
# define SP_COVERAGE 1 // So, coverage in SystemC too
#endif
//=============================================================================
// Compiler pragma abstraction
#ifdef __GNUC__
# define SP_ATTR_PRINTF(fmtArgNum) __attribute__ ((format (printf, fmtArgNum, fmtArgNum+1)))
# define SP_ATTR_ALIGNED(alignment) __attribute__ ((aligned (alignment)))
# define SP_ATTR_NORETURN __attribute__ ((noreturn))
# define SP_ATTR_UNUSED __attribute__ ((unused))
# define SP_LIKELY(x) __builtin_expect(!!(x), 1)
# define SP_UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
# define SP_ATTR_PRINTF(fmtArgNum) ///< Function with printf format checking
# define SP_ATTR_ALIGNED(alignment) ///< Align structure to specified byte alignment
# define SP_ATTR_NORETURN ///< Function does not ever return
# define SP_ATTR_UNUSED ///< Function that may be never used
# define SP_LIKELY(x) (!!(x)) ///< Boolean expression more often true than false
# define SP_UNLIKELY(x) (!!(x)) ///< Boolean expression more often false than true
#endif
//=============================================================================
/// Report SystemPerl internal error message and abort
#if defined(UERROR) && defined(UERROR_NL)
# define SP_ABORT(msg) { UERROR(msg); }
#else
# define SP_ABORT(msg) { cerr<<msg; abort(); }
#endif
#ifndef SP_ERROR_LN
/// Print error message and exit, redefine if you want something else...
# define SP_ERROR_LN(file,line,stmsg) { cout<<"%Error:"<<file<<":"<<dec<<line<<": "<<stmsg<<endl; abort();}
#endif
#ifndef SP_NOTICE_LN
/// Print notice message and non-exit, redefine if you want something else...
# define SP_NOTICE_LN(file,line,stmsg) { cout<<"%Notice:"<<file<<":"<<dec<<line<<": "<<stmsg<<endl; }
#endif
//=============================================================================
/// Conditionally compile coverage code
#ifdef SP_COVERAGE
# define SP_IF_COVER(stmts) do { stmts ; } while(0)
#else
# define SP_IF_COVER(stmts) do { if(0) { stmts ; } } while(0)
#endif
//********************************************************************
// Simple classes. If get bigger, move to optional include
// Some functions may be used by generic C compilers!
#ifdef __cplusplus
/// Templated class which constructs to zero.
/// Originally used for easy pre-zeroing of data used for SpCoverage.
/// SystemPerl 1.301 and later always zero the points when they are added.
template <class T> class SpZeroed { public:
T m_v;
SpZeroed(): m_v(0) {};
inline operator const T () const { return m_v; };
inline SpZeroed& operator++() {++m_v; return *this;}; // prefix
// There is no post-increment; pre-increment may be faster.
};
/// Uint32_t which constructs to zero. (Backward compatible)
typedef SpZeroed<uint32_t> SpUInt32Zeroed;
#endif // __cplusplus
//=============================================================================
#endif // guard