/*
  This file is part of drd, a thread error detector.

  Copyright (C) 2006-2013 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_ppc64be) || defined(VGA_ppc64le)
#define STACK_POINTER_OFFSET OFFSET_ppc64_GPR1
#elif defined(VGA_arm)
#define STACK_POINTER_OFFSET OFFSET_arm_R13
#elif defined(VGA_arm64)
#define STACK_POINTER_OFFSET OFFSET_arm64_XSP
#elif defined(VGA_s390x)
#define STACK_POINTER_OFFSET OFFSET_s390x_r15
#elif defined(VGA_mips32)
#define STACK_POINTER_OFFSET OFFSET_mips32_r29
#elif defined(VGA_mips64)
#define STACK_POINTER_OFFSET OFFSET_mips64_r29
#elif defined(VGA_tilegx)
#define STACK_POINTER_OFFSET OFFSET_tilegx_r54
#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))
   {
      HChar* 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_used; 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,
                                    IRExpr* const guard/* NULL => True */)
{
   IRTemp tmp;

   tmp = newIRTemp(bb->tyenv, typeOfIRExpr(bb->tyenv, addr_expr));
   addStmtToIRSB(bb, IRStmt_WrTmp(tmp, addr_expr));
   addr_expr = IRExpr_RdTmp(tmp);
   IRDirty* di
     = unsafeIRDirty_0_N(/*regparms*/2,
                         "drd_trace_mem_load",
                         VG_(fnptr_to_fnentry)
                         (drd_trace_mem_load),
                         mkIRExprVec_2(addr_expr, mkIRExpr_HWord(size)));
   if (guard) di->guard = guard;
   addStmtToIRSB(bb, IRStmt_Dirty(di));

   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,
                                  IRExpr* const guard/* NULL => True */)
{
   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);
      }
   }
   IRDirty* di
     = 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));
   if (guard) di->guard = guard;
   addStmtToIRSB(bb, IRStmt_Dirty(di) );
}

static void instrument_load(IRSB* const bb, IRExpr* const addr_expr,
                            const HWord size,
                            IRExpr* const guard/* NULL => True */)
{
   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;
   }
   if (guard) di->guard = guard;
   addStmtToIRSB(bb, IRStmt_Dirty(di));
}

static void instrument_store(IRSB* const bb, IRExpr* addr_expr,
                             IRExpr* const data_expr,
                             IRExpr* const guard_expr/* NULL => True */)
{
   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, guard_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;
   }
   if (guard_expr) di->guard = guard_expr;
   addStmtToIRSB(bb, IRStmt_Dirty(di));
}

IRSB* DRD_(instrument)(VgCallbackClosure* const closure,
                       IRSB* const bb_in,
                       const VexGuestLayout* const layout,
                       const VexGuestExtents* const vge,
                       const VexArchInfo* archinfo_host,
                       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, st->Ist.IMark.addr)
            != Vg_SectPLT;
         addStmtToIRSB(bb, st);
         break;

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

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

      case Ist_StoreG: {
         IRStoreG* sg   = st->Ist.StoreG.details;
         IRExpr*   data = sg->data;
         IRExpr*   addr = sg->addr;
         if (instrument)
            instrument_store(bb, addr, data, sg->guard);
         addStmtToIRSB(bb, st);
         break;
      }

      case Ist_LoadG: {
         IRLoadG* lg        = st->Ist.LoadG.details;
         IRType   type      = Ity_INVALID; /* loaded type */
         IRType   typeWide  = Ity_INVALID; /* after implicit widening */
         IRExpr*  addr_expr = lg->addr;
         typeOfIRLoadGOp(lg->cvt, &typeWide, &type);
         tl_assert(type != Ity_INVALID);
         if (UNLIKELY(DRD_(any_address_is_traced)())) {
            addr_expr = instr_trace_mem_load(bb, addr_expr,
                                             sizeofIRType(type), lg->guard);
         }
         instrument_load(bb, lg->addr,
                         sizeofIRType(type), lg->guard);
         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),
                                       NULL/* no guard */);
               }
               instrument_load(bb, addr_expr, sizeofIRType(data->Iex.Load.ty),
                               NULL/* no guard */);
            }
         }
         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,
                                     NULL/* no guard */);

            instrument_load(bb, cas->addr, dataSize, NULL/*no guard*/);
         }
         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),
                                                   NULL /* no guard */);

               instrument_load(bb, addr_expr, sizeofIRType(dataTy),
                               NULL/*no guard*/);
            }
         } else {
            /* SC */
            instr_trace_mem_store(bb, st->Ist.LLSC.addr, NULL,
                                  st->Ist.LLSC.storedata,
                                  NULL/* no guard */);
         }
         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;
}

