/*
 * Copyright 2009, Spyros Blanas
 */

#ifdef __sparc__
#include <libcpc.h>
#endif

class PerfCounters {
public:
  void init();
  void threadinit();
  void destroy();

  inline void writeCounters(unsigned long long* counter1,
      unsigned long long* counter2) {
#ifdef PERFCOUNT
#if defined(__i386__) || defined(__x86_64__)
    *counter1 = readpmc(0);
    *counter2 = readpmc(1);
#elif defined(__sparc__)
    unsigned long long val;
    __asm__ __volatile__ (
        "rd %%pic, %0"
        : "=r" (val) /* output */
    );
    *counter1 = val >> 32;
    *counter2 = val & 0xFFFFFFFFull;
#else
#error Performance counters not known for this architecture.
#endif
#endif
  }

private:
#if defined(__i386__) || defined(__x86_64__)
  inline unsigned long long readpmc(unsigned int counterid) {
    unsigned long hi, lo;
    __asm__ __volatile__ ("rdpmc"
        : "=d" (hi), "=a" (lo)
        : "c" (counterid)
    );
    return (((unsigned long long) hi) << 32) | lo;
  }

#elif defined(__sparc__)
  cpc_t* cpc;

#endif

};
