/*
  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
#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;
}

