/* -*- mode: C; c-basic-offset: 3; indent-tabs-mode: nil; -*- */
/*
  This file is part of drd, a thread error detector.

  Copyright (C) 2006-2011 Bart Van Assche <bvanassche@acm.org>.

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License as
  published by the Free Software Foundation; either version 2 of the
  License, or (at your option) any later version.

  This program 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.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  02111-1307, USA.

  The GNU General Public License is contained in the file COPYING.
*/


#ifndef __DRD_THREAD_BITMAP_H
#define __DRD_THREAD_BITMAP_H


#include "drd_bitmap.h"
#include "drd_thread.h" /* running_thread_get_segment() */
#include "pub_drd_bitmap.h"


static __inline__
Bool bm_access_load_1_triggers_conflict(const Addr a1)
{
   DRD_(bm_access_load_1)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1);
   return DRD_(bm_load_1_has_conflict_with)(DRD_(thread_get_conflict_set)(),
                                            a1);
}

static __inline__
Bool bm_access_load_2_triggers_conflict(const Addr a1)
{
   if ((a1 & 1) == 0)
   {
      bm_access_aligned_load(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1, 2);
      return bm_aligned_load_has_conflict_with(DRD_(thread_get_conflict_set)(),
                                               a1, 2);
   }
   else
   {
      DRD_(bm_access_range)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()),
                            a1, a1 + 2, eLoad);
      return DRD_(bm_has_conflict_with)(DRD_(thread_get_conflict_set)(),
                                        a1, a1 + 2, eLoad);
   }
}

static __inline__
Bool bm_access_load_4_triggers_conflict(const Addr a1)
{
   if ((a1 & 3) == 0)
   {
      bm_access_aligned_load(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1, 4);
      return bm_aligned_load_has_conflict_with(DRD_(thread_get_conflict_set)(),
                                               a1, 4);
   }
   else
   {
      DRD_(bm_access_range)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()),
                            a1, a1 + 4, eLoad);
      return DRD_(bm_has_conflict_with)(DRD_(thread_get_conflict_set)(),
                                        a1, a1 + 4, eLoad);
   }
}

static __inline__
Bool bm_access_load_8_triggers_conflict(const Addr a1)
{
   if ((a1 & 7) == 0)
   {
      bm_access_aligned_load(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1, 8);
      return bm_aligned_load_has_conflict_with(DRD_(thread_get_conflict_set)(),
                                               a1, 8);
   }
   else if ((a1 & 3) == 0)
   {
      bm_access_aligned_load(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1 + 0, 4);
      bm_access_aligned_load(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1 + 4, 4);
      return DRD_(bm_has_conflict_with)(DRD_(thread_get_conflict_set)(),
                                        a1, a1 + 8, eLoad);
   }
   else
   {
      DRD_(bm_access_range)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()),
                            a1, a1 + 8, eLoad);
      return DRD_(bm_has_conflict_with)(DRD_(thread_get_conflict_set)(),
                                        a1, a1 + 8, eLoad);
   }
}

static __inline__
Bool bm_access_load_triggers_conflict(const Addr a1, const Addr a2)
{
   DRD_(bm_access_range_load)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1, a2);
   return DRD_(bm_load_has_conflict_with)(DRD_(thread_get_conflict_set)(),
                                          a1, a2);
}

static __inline__
Bool bm_access_store_1_triggers_conflict(const Addr a1)
{
   DRD_(bm_access_store_1)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1);
   return DRD_(bm_store_1_has_conflict_with)(DRD_(thread_get_conflict_set)(),
                                             a1);
}

static __inline__
Bool bm_access_store_2_triggers_conflict(const Addr a1)
{
   if ((a1 & 1) == 0)
   {
      bm_access_aligned_store(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1, 2);
      return bm_aligned_store_has_conflict_with(DRD_(thread_get_conflict_set)(),
                                                a1, 2);
   }
   else
   {
      DRD_(bm_access_range)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()),
                            a1, a1 + 2, eStore);
      return DRD_(bm_has_conflict_with)(DRD_(thread_get_conflict_set)(),
                                        a1, a1 + 2, eStore);
   }
}

static __inline__
Bool bm_access_store_4_triggers_conflict(const Addr a1)
{
   if ((a1 & 3) == 0)
   {
      bm_access_aligned_store(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1, 4);
      return bm_aligned_store_has_conflict_with(DRD_(thread_get_conflict_set)(),
                                                a1, 4);
   }
   else
   {
      DRD_(bm_access_range)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()),
                            a1, a1 + 4, eStore);
      return DRD_(bm_has_conflict_with)(DRD_(thread_get_conflict_set)(),
                                        a1, a1 + 4, eStore);
   }
}

static __inline__
Bool bm_access_store_8_triggers_conflict(const Addr a1)
{
   if ((a1 & 7) == 0)
   {
      bm_access_aligned_store(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1, 8);
      return bm_aligned_store_has_conflict_with(DRD_(thread_get_conflict_set)(),
                                                a1, 8);
   }
   else if ((a1 & 3) == 0)
   {
      bm_access_aligned_store(DRD_(sg_bm)(DRD_(running_thread_get_segment)()),
                              a1 + 0, 4);
      bm_access_aligned_store(DRD_(sg_bm)(DRD_(running_thread_get_segment)()),
                              a1 + 4, 4);
      return DRD_(bm_has_conflict_with)(DRD_(thread_get_conflict_set)(),
                                        a1, a1 + 8, eStore);
   }
   else
   {
      DRD_(bm_access_range)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()),
                            a1, a1 + 8, eStore);
      return DRD_(bm_has_conflict_with)(DRD_(thread_get_conflict_set)(),
                                        a1, a1 + 8, eStore);
   }
}

static __inline__
Bool bm_access_store_triggers_conflict(const Addr a1, const Addr a2)
{
   DRD_(bm_access_range_store)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1, a2);
   return DRD_(bm_store_has_conflict_with)(DRD_(thread_get_conflict_set)(),
                                           a1, a2);
}

#endif // __DRD_THREAD_BITMAP_H
