/* -*- Mode: C; c-basic-offset:4 ; -*- */
/*
 *  (C) 2016 by Argonne National Laboratory.
 *      See COPYRIGHT in top-level directory.
 */

#ifndef MPL_TIMER_PPC64_CYCLE_H_INCLUDED
#define MPL_TIMER_PPC64_CYCLE_H_INCLUDED

#define SPRN_TBRU 0x10D
#define SPRN_TBRL 0x10C

static inline uint64_t tb()
{
    unsigned temp;
    union
    {
      struct { unsigned hi, lo; } w;
      uint64_t d;
    } result;

    do
    {
        asm volatile ("mfspr %0,%1" : "=r" (temp)        : "i" (SPRN_TBRU));
        asm volatile ("mfspr %0,%1" : "=r" (result.w.lo) : "i" (SPRN_TBRL));
        asm volatile ("mfspr %0,%1" : "=r" (result.w.hi) : "i" (SPRN_TBRU));
    }
    while (temp != result.w.hi);

    return result.d;
}

static inline int MPL_wtime(MPL_time_t *timeval)
{
    *timeval = tb();
    return MPL_TIMER_SUCCESS;
}

#endif
