ISA: Make the decode function part of the ISA's decoder.
[gem5.git] / src / base / misc.hh
index 87faf20e6b05b9abe6dc0198b82201cd6290b5c4..25dcbaa6268280df65ab8e794fc43216e5afcd83 100644 (file)
  *          Dave Greene
  */
 
-#ifndef __MISC_HH__
-#define __MISC_HH__
+#ifndef __BASE_MISC_HH__
+#define __BASE_MISC_HH__
 
-#include <assert.h>
+#include "base/compiler.hh"
 #include "base/cprintf.hh"
+#include "base/varargs.hh"
+
+#if defined(__SUNPRO_CC)
+#define __FUNCTION__ "how to fix me?"
+#endif
+
+// General exit message, these functions will never return and will
+// either abort() if code is < 0 or exit with the code if >= 0
+void __exit_message(const char *prefix, int code,
+    const char *func, const char *file, int line,
+    const char *format, CPRINTF_DECLARATION) M5_ATTR_NORETURN;
+
+void __exit_message(const char *prefix, int code,
+    const char *func, const char *file, int line,
+    const std::string &format, CPRINTF_DECLARATION) M5_ATTR_NORETURN;
+
+inline void
+__exit_message(const char *prefix, int code,
+    const char *func, const char *file, int line,
+    const std::string& format, CPRINTF_DEFINITION)
+{
+    __exit_message(prefix, code, func, file, line, format.c_str(),
+                   VARARGS_ALLARGS);
+}
+
+M5_PRAGMA_NORETURN(__exit_message)
+#define exit_message(prefix, code, ...)                            \
+    __exit_message(prefix, code, __FUNCTION__, __FILE__, __LINE__, \
+                   __VA_ARGS__)
 
 //
 // This implements a cprintf based panic() function.  panic() should
 // calls abort which can dump core or enter the debugger.
 //
 //
-void __panic(const std::string&, cp::ArgList &, const char*, const char*, int)
-    __attribute__((noreturn));
-#define __panic__(format, args...) \
-    __panic(format, (*(new cp::ArgList), args), \
-        __FUNCTION__, __FILE__, __LINE__)
-#define panic(args...) \
-    __panic__(args, cp::ArgListNull())
+#define panic(...) exit_message("panic", -1, __VA_ARGS__)
 
 //
 // This implements a cprintf based fatal() function.  fatal() should
@@ -58,31 +81,70 @@ void __panic(const std::string&, cp::ArgList &, const char*, const char*, int)
 // "normal" exit with an error code, as opposed to abort() like
 // panic() does.
 //
-void __fatal(const std::string&, cp::ArgList &, const char*, const char*, int)
-    __attribute__((noreturn));
-#define __fatal__(format, args...) \
-    __fatal(format, (*(new cp::ArgList), args), \
-        __FUNCTION__, __FILE__, __LINE__)
-#define fatal(args...) \
-    __fatal__(args, cp::ArgListNull())
+#define fatal(...) exit_message("fatal", 1, __VA_ARGS__)
 
-//
-// This implements a cprintf based warn
-//
-void __warn(const std::string&, cp::ArgList &, const char*, const char*, int);
-#define __warn__(format, args...) \
-    __warn(format, (*(new cp::ArgList), args), \
-           __FUNCTION__, __FILE__, __LINE__)
-#define warn(args...) \
-    __warn__(args, cp::ArgListNull())
+void
+__base_message(std::ostream &stream, const char *prefix, bool verbose,
+          const char *func, const char *file, int line,
+          const char *format, CPRINTF_DECLARATION);
 
-//
-// assert() that prints out the current cycle
-//
-#define m5_assert(TEST) \
-   if (!(TEST)) { \
-     std::cerr << "Assertion failure, curTick = " << curTick << std::endl; \
-   } \
-   assert(TEST);
+inline void
+__base_message(std::ostream &stream, const char *prefix, bool verbose,
+          const char *func, const char *file, int line,
+          const std::string &format, CPRINTF_DECLARATION)
+{
+    __base_message(stream, prefix, verbose, func, file, line, format.c_str(),
+              VARARGS_ALLARGS);
+}
+
+#define base_message(stream, prefix, verbose, ...)                      \
+    __base_message(stream, prefix, verbose, __FUNCTION__, __FILE__, __LINE__, \
+                   __VA_ARGS__)
+
+// Only print the message the first time this expression is
+// encountered.  i.e.  This doesn't check the string itself and
+// prevent duplicate strings, this prevents the statement from
+// happening more than once. So, even if the arguments change and that
+// would have resulted in a different message thoes messages would be
+// supressed.
+#define base_message_once(...) do {                     \
+        static bool once = false;                       \
+        if (!once) {                                    \
+            base_message(__VA_ARGS__);                  \
+            once = true;                                \
+        }                                               \
+    } while (0)
+
+#define cond_message(cond, ...) do {            \
+        if (cond)                               \
+            base_message(__VA_ARGS__);          \
+    } while (0)
+
+#define cond_message_once(cond, ...) do {               \
+        static bool once = false;                       \
+        if (!once && cond) {                            \
+            base_message(__VA_ARGS__);                  \
+            once = true;                                \
+        }                                               \
+    } while (0)
+
+
+extern bool want_warn, warn_verbose;
+extern bool want_info, info_verbose;
+extern bool want_hack, hack_verbose;
+
+#define warn(...) \
+    cond_message(want_warn, std::cerr, "warn", warn_verbose, __VA_ARGS__)
+#define inform(...) \
+    cond_message(want_info, std::cout, "info", info_verbose, __VA_ARGS__)
+#define hack(...) \
+    cond_message(want_hack, std::cerr, "hack", hack_verbose, __VA_ARGS__)
+
+#define warn_once(...) \
+    cond_message_once(want_warn, std::cerr, "warn", warn_verbose, __VA_ARGS__)
+#define inform_once(...) \
+    cond_message_once(want_info, std::cout, "info", info_verbose, __VA_ARGS__)
+#define hack_once(...) \
+    cond_message_once(want_hack, std::cerr, "hack", hack_verbose, __VA_ARGS__)
 
-#endif // __MISC_HH__
+#endif // __BASE_MISC_HH__