/*
  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.
*/


#include "drd_bitmap.h"
#include "drd_thread_bitmap.h"
#include "drd_vc.h"            /* DRD_(vc_snprint)() */

/* Include several source files here in order to allow the compiler to */
/* do more inlining.                                                   */
#include "drd_bitmap.c"
#include "drd_load_store.h"
#include "drd_segment.c"
#include "drd_thread.c"
#include "drd_vc.c"
#include "libvex_guest_offsets.h"


/* STACK_POINTER_OFFSET: VEX register offset for the stack pointer register. */
#if defined(VGA_x86)
#define STACK_POINTER_OFFSET OFFSET_x86_ESP
#elif defined(VGA_amd64)
#define STACK_POINTER_OFFSET OFFSET_amd64_RSP
#elif defined(VGA_ppc32)
#define STACK_POINTER_OFFSET OFFSET_ppc32_GPR1
#elif defined(VGA_ppc64)
#define STACK_POINTER_OFFSET OFFSET_ppc64_GPR1
#elif defined(VGA_arm)
#define STACK_POINTER_OFFSET OFFSET_arm_R13
#elif defined(VGA_s390x)
#define STACK_POINTER_OFFSET OFFSET_s390x_r15
#elif defined(VGA_mips32)
#define STACK_POINTER_OFFSET OFFSET_mips32_r29
#else
#error Unknown architecture.
#endif


/* Local variables. */

static Bool s_check_stack_accesses = False;
static Bool s_first_race_only      = False;


/* Function definitions. */

Bool DRD_(get_check_stack_accesses)()
{
   return s_check_stack_accesses;
}

void DRD_(set_check_stack_accesses)(const Bool c)
{
   tl_assert(c == False || c == True);
   s_check_stack_accesses = c;
}

Bool DRD_(get_first_race_only)()
{
   return s_first_race_only;
}

void DRD_(set_first_race_only)(const Bool fro)
{
   tl_assert(fro == False || fro == True);
   s_first_race_only = fro;
}

void DRD_(trace_mem_access)(const Addr addr, const SizeT size,
                            const BmAccessTypeT access_type,
                            const HWord stored_value_hi,
                            const HWord stored_value_lo)
{
   if (DRD_(is_any_traced)(addr, addr + size))
   {
      char* vc;

      vc = DRD_(vc_aprint)(DRD_(thread_get_vc)(DRD_(thread_get_running_tid)()));
      if (access_type == eStore && size <= sizeof(HWord)) {
         DRD_(trace_msg_w_bt)("store 0x%lx size %ld val %ld/0x%lx (thread %d /"
                              " vc %s)", addr, size, stored_value_lo,
                              stored_value_lo, DRD_(thread_get_running_tid)(),
                              vc);
      } else if (access_type == eStore && size > sizeof(HWord)) {
         ULong sv;

         tl_assert(sizeof(HWord) == 4);
         sv = ((ULong)stored_value_hi << 32) | stored_value_lo;
         DRD_(trace_msg_w_bt)("store 0x%lx size %ld val %lld/0x%llx (thread %d"
                              " / vc %s)", addr, size, sv, sv,
                              DRD_(thread_get_running_tid)(), vc);
      } else {
         DRD_(trace_msg_w_bt)("%s 0x%lx size %ld (thread %d / vc %s)",
                              access_type == eLoad ? "load "
                              : access_type == eStore ? "store"
                              : access_type == eStart ? "start"
                              : access_type == eEnd ? "end  " : "????",
                              addr, size, DRD_(thread_get_running_tid)(), vc);
      }
      VG_(free)(vc);
      tl_assert(DRD_(DrdThreadIdToVgThreadId)(DRD_(thread_get_running_tid)())
                == VG_(get_running_tid)());
   }
}

static VG_REGPARM(2) void drd_trace_mem_load(const Addr addr, const SizeT size)
{
   return DRD_(trace_mem_access)(addr, size, eLoad, 0, 0);
}

static VG_REGPARM(3) void drd_trace_mem_store(const Addr addr,const SizeT size,
                                              const HWord stored_value_hi,
                                              const HWord stored_value_lo)
{
   return DRD_(trace_mem_access)(addr, size, eStore, stored_value_hi,
                                 stored_value_lo);
}

static void drd_report_race(const Addr addr, const SizeT size,
                            const BmAccessTypeT access_type)
{
   ThreadId vg_tid;

   vg_tid = VG_(get_running_tid)();
   if (!DRD_(get_check_stack_accesses)()
       && DRD_(thread_address_on_any_stack)(addr)) {
#if 0
      GenericErrInfo GEI = {
         .tid = DRD_(thread_get_running_tid)(),
         .addr = addr,
      };
      VG_(maybe_record_error)(vg_tid, GenericErr, VG_(get_IP)(vg_tid),
                              "--check-stack-var=no skips checking stack"
                              " variables shared over threads",
                              &GEI);
#endif
  } else {
      DataRaceErrInfo drei = {
         .tid  = DRD_(thread_get_running_tid)(),
         .addr = addr,
         .size = size,
         .access_type = access_type,
      };
      VG_(maybe_record_error)(vg_tid, DataRaceErr, VG_(get_IP)(vg_tid),
                              "Conflicting access", &drei);

      if (s_first_race_only)
         DRD_(start_suppression)(addr, addr + size, "first race only");
   }
}

VG_REGPARM(2) void DRD_(trace_load)(Addr addr, SizeT size)
{
#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
   /* The assert below has been commented out because of performance reasons.*/
   tl_assert(DRD_(thread_get_running_tid)()
             == DRD_(VgThreadIdToDrdThreadId)(VG_(get_running_tid())));
#endif

   if (DRD_(running_thread_is_recording_loads)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_load_triggers_conflict(addr, addr + size)
       && ! DRD_(is_suppressed)(addr, addr + size))
   {
      drd_report_race(addr, size, eLoad);
   }
}

static VG_REGPARM(1) void drd_trace_load_1(Addr addr)
{
   if (DRD_(running_thread_is_recording_loads)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_load_1_triggers_conflict(addr)
       && ! DRD_(is_suppressed)(addr, addr + 1))
   {
      drd_report_race(addr, 1, eLoad);
   }
}

static VG_REGPARM(1) void drd_trace_load_2(Addr addr)
{
   if (DRD_(running_thread_is_recording_loads)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_load_2_triggers_conflict(addr)
       && ! DRD_(is_suppressed)(addr, addr + 2))
   {
      drd_report_race(addr, 2, eLoad);
   }
}

static VG_REGPARM(1) void drd_trace_load_4(Addr addr)
{
   if (DRD_(running_thread_is_recording_loads)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_load_4_triggers_conflict(addr)
       && ! DRD_(is_suppressed)(addr, addr + 4))
   {
      drd_report_race(addr, 4, eLoad);
   }
}

static VG_REGPARM(1) void drd_trace_load_8(Addr addr)
{
   if (DRD_(running_thread_is_recording_loads)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_load_8_triggers_conflict(addr)
       && ! DRD_(is_suppressed)(addr, addr + 8))
   {
      drd_report_race(addr, 8, eLoad);
   }
}

VG_REGPARM(2) void DRD_(trace_store)(Addr addr, SizeT size)
{
#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
   /* The assert below has been commented out because of performance reasons.*/
   tl_assert(DRD_(thread_get_running_tid)()
             == DRD_(VgThreadIdToDrdThreadId)(VG_(get_running_tid())));
#endif

   if (DRD_(running_thread_is_recording_stores)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_store_triggers_conflict(addr, addr + size)
       && ! DRD_(is_suppressed)(addr, addr + size))
   {
      drd_report_race(addr, size, eStore);
   }
}

static VG_REGPARM(1) void drd_trace_store_1(Addr addr)
{
   if (DRD_(running_thread_is_recording_stores)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_store_1_triggers_conflict(addr)
       && ! DRD_(is_suppressed)(addr, addr + 1))
   {
      drd_report_race(addr, 1, eStore);
   }
}

static VG_REGPARM(1) void drd_trace_store_2(Addr addr)
{
   if (DRD_(running_thread_is_recording_stores)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_store_2_triggers_conflict(addr)
       && ! DRD_(is_suppressed)(addr, addr + 2))
   {
      drd_report_race(addr, 2, eStore);
   }
}

static VG_REGPARM(1) void drd_trace_store_4(Addr addr)
{
   if (DRD_(running_thread_is_recording_stores)()
       && (s_check_stack_accesses
           || !DRD_(thread_address_on_stack)(addr))
       && bm_access_store_4_triggers_conflict(addr)
       && !DRD_(is_suppressed)(addr, addr + 4))
   {
      drd_report_race(addr, 4, eStore);
   }
}

static VG_REGPARM(1) void drd_trace_store_8(Addr addr)
{
   if (DRD_(running_thread_is_recording_stores)()
       && (s_check_stack_accesses
           || ! DRD_(thread_address_on_stack)(addr))
       && bm_access_store_8_triggers_conflict(addr)
       && ! DRD_(is_suppressed)(addr, addr + 8))
   {
      drd_report_race(addr, 8, eStore);
   }
}

/**
 * Return true if and only if addr_expr matches the pattern (SP) or
 * <offset>(SP).
 */
static Bool is_stack_access(IRSB* const bb, IRExpr* const addr_expr)
{
   Bool result = False;

   if (addr_expr->tag == Iex_RdTmp)
   {
      int i;
      for (i = 0; i < bb->stmts_size; i++)
      {
         if (bb->stmts[i]
             && bb->stmts[i]->tag == Ist_WrTmp
             && bb->stmts[i]->Ist.WrTmp.tmp == addr_expr->Iex.RdTmp.tmp)
         {
            IRExpr* e = bb->stmts[i]->Ist.WrTmp.data;
            if (e->tag == Iex_Get && e->Iex.Get.offset == STACK_POINTER_OFFSET)
            {
               result = True;
            }

            //ppIRExpr(e);
            //VG_(printf)(" (%s)\n", result ? "True" : "False");
            break;
         }
      }
   }
   return result;
}

static const IROp u_widen_irop[5][9] = {
   [Ity_I1  - Ity_I1] = { [4] = Iop_1Uto32,  [8] = Iop_1Uto64 },
   [Ity_I8  - Ity_I1] = { [4] = Iop_8Uto32,  [8] = Iop_8Uto64 },
   [Ity_I16 - Ity_I1] = { [4] = Iop_16Uto32, [8] = Iop_16Uto64 },
   [Ity_I32 - Ity_I1] = {                    [8] = Iop_32Uto64 },
};

/**
 * Instrument the client code to trace a memory load (--trace-addr).
 */
static IRExpr* instr_trace_mem_load(IRSB* const bb, IRExpr* addr_expr,
                                    const HWord size)
{
   IRTemp tmp;

   tmp = newIRTemp(bb->tyenv, typeOfIRExpr(bb->tyenv, addr_expr));
   addStmtToIRSB(bb, IRStmt_WrTmp(tmp, addr_expr));
   addr_expr = IRExpr_RdTmp(tmp);

   addStmtToIRSB(bb,
      IRStmt_Dirty(
         unsafeIRDirty_0_N(/*regparms*/2,
                           "drd_trace_mem_load",
                           VG_(fnptr_to_fnentry)
                           (drd_trace_mem_load),
                           mkIRExprVec_2(addr_expr, mkIRExpr_HWord(size)))));

   return addr_expr;
}

/**
 * Instrument the client code to trace a memory store (--trace-addr).
 */
static void instr_trace_mem_store(IRSB* const bb, IRExpr* const addr_expr,
                                  IRExpr* data_expr_hi, IRExpr* data_expr_lo)
{
   IRType ty_data_expr;
   HWord size;

   tl_assert(sizeof(HWord) == 4 || sizeof(HWord) == 8);
   tl_assert(!data_expr_hi || typeOfIRExpr(bb->tyenv, data_expr_hi) == Ity_I32);

   ty_data_expr = typeOfIRExpr(bb->tyenv, data_expr_lo);
   size = sizeofIRType(ty_data_expr);

#if 0
   // Test code
   if (ty_data_expr == Ity_I32) {
      IRTemp tmp = newIRTemp(bb->tyenv, Ity_F32);
      data_expr_lo = IRExpr_Unop(Iop_ReinterpI32asF32, data_expr_lo);
      addStmtToIRSB(bb, IRStmt_WrTmp(tmp, data_expr_lo));
      data_expr_lo = IRExpr_RdTmp(tmp);
      ty_data_expr = Ity_F32;
   } else if (ty_data_expr == Ity_I64) {
      IRTemp tmp = newIRTemp(bb->tyenv, Ity_F64);
      data_expr_lo = IRExpr_Unop(Iop_ReinterpI64asF64, data_expr_lo);
      addStmtToIRSB(bb, IRStmt_WrTmp(tmp, data_expr_lo));
      data_expr_lo = IRExpr_RdTmp(tmp);
      ty_data_expr = Ity_F64;
   }
#endif

   if (ty_data_expr == Ity_F32) {
      IRTemp tmp = newIRTemp(bb->tyenv, Ity_I32);
      addStmtToIRSB(bb, IRStmt_WrTmp(tmp, IRExpr_Unop(Iop_ReinterpF32asI32,
                                                      data_expr_lo)));
      data_expr_lo = IRExpr_RdTmp(tmp);
      ty_data_expr = Ity_I32;
   } else if (ty_data_expr == Ity_F64) {
      IRTemp tmp = newIRTemp(bb->tyenv, Ity_I64);
      addStmtToIRSB(bb, IRStmt_WrTmp(tmp, IRExpr_Unop(Iop_ReinterpF64asI64,
                                                      data_expr_lo)));
      data_expr_lo = IRExpr_RdTmp(tmp);
      ty_data_expr = Ity_I64;
   }

   if (size == sizeof(HWord)
       && (ty_data_expr == Ity_I32 || ty_data_expr == Ity_I64))
   {
      /* No conversion necessary */
   } else {
      IROp widen_op;

      if (Ity_I1 <= ty_data_expr
          && ty_data_expr
             < Ity_I1 + sizeof(u_widen_irop)/sizeof(u_widen_irop[0]))
      {
         widen_op = u_widen_irop[ty_data_expr - Ity_I1][sizeof(HWord)];
         if (!widen_op)
            widen_op = Iop_INVALID;
      } else {
         widen_op = Iop_INVALID;
      }
      if (widen_op != Iop_INVALID) {
         IRTemp tmp;

         /* Widen the integer expression to a HWord */
         tmp = newIRTemp(bb->tyenv, sizeof(HWord) == 4 ? Ity_I32 : Ity_I64);
         addStmtToIRSB(bb,
                       IRStmt_WrTmp(tmp, IRExpr_Unop(widen_op, data_expr_lo)));
         data_expr_lo = IRExpr_RdTmp(tmp);
      } else if (size > sizeof(HWord) && !data_expr_hi
                 && ty_data_expr == Ity_I64) {
         IRTemp tmp;
         
         tl_assert(sizeof(HWord) == 4);
         tl_assert(size == 8);
         tmp = newIRTemp(bb->tyenv, Ity_I32);
         addStmtToIRSB(bb,
                       IRStmt_WrTmp(tmp,
                                    IRExpr_Unop(Iop_64HIto32, data_expr_lo)));
         data_expr_hi = IRExpr_RdTmp(tmp);
         tmp = newIRTemp(bb->tyenv, Ity_I32);
         addStmtToIRSB(bb, IRStmt_WrTmp(tmp,
                                        IRExpr_Unop(Iop_64to32, data_expr_lo)));
         data_expr_lo = IRExpr_RdTmp(tmp);
      } else {
         data_expr_lo = mkIRExpr_HWord(0);
      }
   }
   addStmtToIRSB(bb,
      IRStmt_Dirty(
         unsafeIRDirty_0_N(/*regparms*/3,
                           "drd_trace_mem_store",
                           VG_(fnptr_to_fnentry)(drd_trace_mem_store),
                           mkIRExprVec_4(addr_expr, mkIRExpr_HWord(size),
                                         data_expr_hi ? data_expr_hi
                                         : mkIRExpr_HWord(0), data_expr_lo))));
}

static void instrument_load(IRSB* const bb, IRExpr* const addr_expr,
                            const HWord size)
{
   IRExpr* size_expr;
   IRExpr** argv;
   IRDirty* di;

   if (!s_check_stack_accesses && is_stack_access(bb, addr_expr))
      return;

   switch (size)
   {
   case 1:
      argv = mkIRExprVec_1(addr_expr);
      di = unsafeIRDirty_0_N(/*regparms*/1,
                             "drd_trace_load_1",
                             VG_(fnptr_to_fnentry)(drd_trace_load_1),
                             argv);
      break;
   case 2:
      argv = mkIRExprVec_1(addr_expr);
      di = unsafeIRDirty_0_N(/*regparms*/1,
                             "drd_trace_load_2",
                             VG_(fnptr_to_fnentry)(drd_trace_load_2),
                             argv);
      break;
   case 4:
      argv = mkIRExprVec_1(addr_expr);
      di = unsafeIRDirty_0_N(/*regparms*/1,
                             "drd_trace_load_4",
                             VG_(fnptr_to_fnentry)(drd_trace_load_4),
                             argv);
      break;
   case 8:
      argv = mkIRExprVec_1(addr_expr);
      di = unsafeIRDirty_0_N(/*regparms*/1,
                             "drd_trace_load_8",
                             VG_(fnptr_to_fnentry)(drd_trace_load_8),
                             argv);
      break;
   default:
      size_expr = mkIRExpr_HWord(size);
      argv = mkIRExprVec_2(addr_expr, size_expr);
      di = unsafeIRDirty_0_N(/*regparms*/2,
                             "drd_trace_load",
                             VG_(fnptr_to_fnentry)(DRD_(trace_load)),
                             argv);
      break;
   }
   addStmtToIRSB(bb, IRStmt_Dirty(di));
}

static void instrument_store(IRSB* const bb, IRExpr* addr_expr,
                             IRExpr* const data_expr)
{
   IRExpr* size_expr;
   IRExpr** argv;
   IRDirty* di;
   HWord size;

   size = sizeofIRType(typeOfIRExpr(bb->tyenv, data_expr));

   if (UNLIKELY(DRD_(any_address_is_traced)())) {
      IRTemp tmp = newIRTemp(bb->tyenv, typeOfIRExpr(bb->tyenv, addr_expr));
      addStmtToIRSB(bb, IRStmt_WrTmp(tmp, addr_expr));
      addr_expr = IRExpr_RdTmp(tmp);
      instr_trace_mem_store(bb, addr_expr, NULL, data_expr);
   }

   if (!s_check_stack_accesses && is_stack_access(bb, addr_expr))
      return;

   switch (size)
   {
   case 1:
      argv = mkIRExprVec_1(addr_expr);
      di = unsafeIRDirty_0_N(/*regparms*/1,
                             "drd_trace_store_1",
                             VG_(fnptr_to_fnentry)(drd_trace_store_1),
                             argv);
      break;
   case 2:
      argv = mkIRExprVec_1(addr_expr);
      di = unsafeIRDirty_0_N(/*regparms*/1,
                             "drd_trace_store_2",
                             VG_(fnptr_to_fnentry)(drd_trace_store_2),
                             argv);
      break;
   case 4:
      argv = mkIRExprVec_1(addr_expr);
      di = unsafeIRDirty_0_N(/*regparms*/1,
                             "drd_trace_store_4",
                             VG_(fnptr_to_fnentry)(drd_trace_store_4),
                             argv);
      break;
   case 8:
      argv = mkIRExprVec_1(addr_expr);
      di = unsafeIRDirty_0_N(/*regparms*/1,
                             "drd_trace_store_8",
                             VG_(fnptr_to_fnentry)(drd_trace_store_8),
                             argv);
      break;
   default:
      size_expr = mkIRExpr_HWord(size);
      argv = mkIRExprVec_2(addr_expr, size_expr);
      di = unsafeIRDirty_0_N(/*regparms*/2,
                             "drd_trace_store",
                             VG_(fnptr_to_fnentry)(DRD_(trace_store)),
                             argv);
      break;
   }
   addStmtToIRSB(bb, IRStmt_Dirty(di));
}

IRSB* DRD_(instrument)(VgCallbackClosure* const closure,
                       IRSB* const bb_in,
                       VexGuestLayout* const layout,
                       VexGuestExtents* const vge,
                       IRType const gWordTy,
                       IRType const hWordTy)
{
   IRDirty* di;
   Int      i;
   IRSB*    bb;
   IRExpr** argv;
   Bool     instrument = True;

   /* Set up BB */
   bb           = emptyIRSB();
   bb->tyenv    = deepCopyIRTypeEnv(bb_in->tyenv);
   bb->next     = deepCopyIRExpr(bb_in->next);
   bb->jumpkind = bb_in->jumpkind;
   bb->offsIP   = bb_in->offsIP;

   for (i = 0; i < bb_in->stmts_used; i++)
   {
      IRStmt* const st = bb_in->stmts[i];
      tl_assert(st);
      tl_assert(isFlatIRStmt(st));

      switch (st->tag)
      {
         /* Note: the code for not instrumenting the code in .plt          */
         /* sections is only necessary on CentOS 3.0 x86 (kernel 2.4.21    */
         /* + glibc 2.3.2 + NPTL 0.60 + binutils 2.14.90.0.4).             */
         /* This is because on this platform dynamic library symbols are   */
         /* relocated in another way than by later binutils versions. The  */
         /* linker e.g. does not generate .got.plt sections on CentOS 3.0. */
      case Ist_IMark:
         instrument = VG_(DebugInfo_sect_kind)(NULL, 0, st->Ist.IMark.addr)
            != Vg_SectPLT;
         addStmtToIRSB(bb, st);
         break;

      case Ist_MBE:
         switch (st->Ist.MBE.event)
         {
         case Imbe_Fence:
            break; /* not interesting */
         default:
            tl_assert(0);
         }
         addStmtToIRSB(bb, st);
         break;

      case Ist_Store:
         if (instrument)
            instrument_store(bb, st->Ist.Store.addr, st->Ist.Store.data);
         addStmtToIRSB(bb, st);
         break;

      case Ist_WrTmp:
         if (instrument) {
            const IRExpr* const data = st->Ist.WrTmp.data;
            IRExpr* addr_expr = data->Iex.Load.addr;
            if (data->tag == Iex_Load) {
               if (UNLIKELY(DRD_(any_address_is_traced)())) {
                  addr_expr = instr_trace_mem_load(bb, addr_expr,
                                       sizeofIRType(data->Iex.Load.ty));
               }
               instrument_load(bb, data->Iex.Load.addr,
                               sizeofIRType(data->Iex.Load.ty));
            }
         }
         addStmtToIRSB(bb, st);
         break;

      case Ist_Dirty:
         if (instrument) {
            IRDirty* d = st->Ist.Dirty.details;
            IREffect const mFx = d->mFx;
            switch (mFx) {
            case Ifx_None:
               break;
            case Ifx_Read:
            case Ifx_Write:
            case Ifx_Modify:
               tl_assert(d->mAddr);
               tl_assert(d->mSize > 0);
               argv = mkIRExprVec_2(d->mAddr, mkIRExpr_HWord(d->mSize));
               if (mFx == Ifx_Read || mFx == Ifx_Modify) {
                  di = unsafeIRDirty_0_N(
                          /*regparms*/2,
                          "drd_trace_load",
                          VG_(fnptr_to_fnentry)(DRD_(trace_load)),
                          argv);
                  addStmtToIRSB(bb, IRStmt_Dirty(di));
               }
               if (mFx == Ifx_Write || mFx == Ifx_Modify)
               {
                  di = unsafeIRDirty_0_N(
                          /*regparms*/2,
                          "drd_trace_store",
                          VG_(fnptr_to_fnentry)(DRD_(trace_store)),
                          argv);
                  addStmtToIRSB(bb, IRStmt_Dirty(di));
               }
               break;
            default:
               tl_assert(0);
            }
         }
         addStmtToIRSB(bb, st);
         break;

      case Ist_CAS:
         if (instrument) {
            /*
             * Treat compare-and-swap as a read. By handling atomic
             * instructions as read instructions no data races are reported
             * between conflicting atomic operations nor between atomic
             * operations and non-atomic reads. Conflicts between atomic
             * operations and non-atomic write operations are still reported
             * however.
             */
            Int    dataSize;
            IRCAS* cas = st->Ist.CAS.details;

            tl_assert(cas->addr != NULL);
            tl_assert(cas->dataLo != NULL);
            dataSize = sizeofIRType(typeOfIRExpr(bb->tyenv, cas->dataLo));
            if (cas->dataHi != NULL)
               dataSize *= 2; /* since it's a doubleword-CAS */

            if (UNLIKELY(DRD_(any_address_is_traced)()))
               instr_trace_mem_store(bb, cas->addr, cas->dataHi, cas->dataLo);

            instrument_load(bb, cas->addr, dataSize);
         }
         addStmtToIRSB(bb, st);
         break;

      case Ist_LLSC: {
         /*
          * Ignore store-conditionals (except for tracing), and handle
          * load-linked's exactly like normal loads.
          */
         IRType dataTy;

         if (st->Ist.LLSC.storedata == NULL) {
            /* LL */
            dataTy = typeOfIRTemp(bb_in->tyenv, st->Ist.LLSC.result);
            if (instrument) {
               IRExpr* addr_expr = st->Ist.LLSC.addr;
               if (UNLIKELY(DRD_(any_address_is_traced)()))
                  addr_expr = instr_trace_mem_load(bb, addr_expr,
                                                   sizeofIRType(dataTy));

               instrument_load(bb, addr_expr, sizeofIRType(dataTy));
            }
         } else {
            /* SC */
            instr_trace_mem_store(bb, st->Ist.LLSC.addr, NULL,
                                  st->Ist.LLSC.storedata);
         }
         addStmtToIRSB(bb, st);
         break;
      }

      case Ist_NoOp:
      case Ist_AbiHint:
      case Ist_Put:
      case Ist_PutI:
      case Ist_Exit:
         /* None of these can contain any memory references. */
         addStmtToIRSB(bb, st);
         break;

      default:
         ppIRStmt(st);
         tl_assert(0);
      }
   }

   return bb;
}

