Delete all the old UCode stuff.


git-svn-id: svn://svn.valgrind.org/vex/trunk@510 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/head20041019/memcheck/mc_translate.c b/head20041019/memcheck/mc_translate.c
index d39f959..f4701c7 100644
--- a/head20041019/memcheck/mc_translate.c
+++ b/head20041019/memcheck/mc_translate.c
@@ -1,6 +1,6 @@
 
 /*--------------------------------------------------------------------*/
-/*--- Instrument UCode to perform memory checking operations.      ---*/
+/*--- Instrument IR to perform memory checking operations.         ---*/
 /*---                                               mc_translate.c ---*/
 /*--------------------------------------------------------------------*/
 
@@ -31,1618 +31,6 @@
 
 #include "mc_include.h"
 
-/* ---------------------------------------------------------------------
-   Template functions for extending UCode
-   ------------------------------------------------------------------ */
-
-/* Compare this with the restrictions on core instructions in
-   vg_translate.c:is_sane_UInstr().  Everything general said there
-   applies here too.
-*/
-Bool SK_(sane_XUInstr)(Bool beforeRA, Bool beforeLiveness, UInstr* u)
-{
-// SSS: duplicating these macros really sucks
-#  define LIT0 (u->lit32 == 0)
-#  define LIT1 (!(LIT0))
-#  define LITm (u->tag1 == Literal ? True : LIT0 )
-#  define SZ0 (u->size == 0)
-#  define SZi (u->size == 4 || u->size == 2 || u->size == 1)
-#  define SZj (u->size == 4 || u->size == 2 || u->size == 1 || u->size == 0)
-#  define CC0 (u->flags_r == FlagsEmpty && u->flags_w == FlagsEmpty)
-#  define TR1 (beforeRA ? (u->tag1 == TempReg) : (u->tag1 == RealReg))
-#  define TR2 (beforeRA ? (u->tag2 == TempReg) : (u->tag2 == RealReg))
-#  define A1  (u->tag1 == ArchReg)
-#  define A2  (u->tag2 == ArchReg)
-#  define L1  (u->tag1 == Literal && u->val1 == 0)
-#  define Ls1 (u->tag1 == Lit16)
-#  define Ls3 (u->tag3 == Lit16)
-#  define TRL1 (TR1 || L1)
-#  define N2  (u->tag2 == NoValue)
-#  define N3  (u->tag3 == NoValue)
-#  define COND0    (u->cond         == 0)
-#  define EXTRA4b0 (u->extra4b      == 0)
-#  define SG_WD0   (u->signed_widen == 0)
-#  define JMPKIND0 (u->jmpkind      == 0)
-#  define CCALL0   (u->argc==0 && u->regparms_n==0 && u->has_ret_val==0 && \
-                    ( beforeLiveness                                       \
-                    ? u->regs_live_after == ALL_RREGS_LIVE                 \
-                    : True ))
-#  define XOTHER   (COND0 && EXTRA4b0 && SG_WD0 && JMPKIND0 && CCALL0)
-
-   Int n_lits = 0;
-   if (u->tag1 == Literal) n_lits++;
-   if (u->tag2 == Literal) n_lits++;
-   if (u->tag3 == Literal) n_lits++;
-   if (n_lits > 1) 
-      return False;
-
-   /* Fields not checked: val1, val2, val3 */
-
-   switch (u->opcode) {
-
-   /* Fields checked: lit32   size flags_r/w tag1   tag2   tag3    (rest) */
-   case LOADV:  return LIT0 && SZi && CC0 &&  TR1 && TR2 &&  N3 && XOTHER;
-   case STOREV: return LITm && SZi && CC0 && TRL1 && TR2 &&  N3 && XOTHER;
-   case GETV:   return LIT0 && SZi && CC0 &&   A1 && TR2 &&  N3 && XOTHER;
-   case PUTV:   return LITm && SZi && CC0 && TRL1 &&  A2 &&  N3 && XOTHER;
-   case GETVF: 
-   case PUTVF:  return LIT0 && SZ0 && CC0 &&  TR1 &&  N2 &&  N3 && XOTHER;
-   case TESTV: 
-   case SETV:   return LIT0 && SZj && CC0 &&  TR1 &&  N2 &&  N3 && XOTHER;
-   case TAG1:   return LIT0 && SZ0 && CC0 &&  TR1 &&  N2 && Ls3 && XOTHER;
-   case TAG2:   return LIT0 && SZ0 && CC0 &&  TR1 && TR2 && Ls3 && XOTHER;
-   default:
-      VG_(printf)("unhandled opcode: %u\n", u->opcode);
-      VG_(skin_panic)("SK_(sane_XUInstr): unhandled opcode");
-   }
-#  undef LIT0
-#  undef LIT1
-#  undef LITm
-#  undef SZ0
-#  undef SZi
-#  undef SZj
-#  undef CC0
-#  undef TR1
-#  undef TR2
-#  undef A1
-#  undef A2
-#  undef L1
-#  undef Ls1
-#  undef Ls3
-#  undef TRL1
-#  undef N2
-#  undef N3
-#  undef COND0
-#  undef EXTRA4b0
-#  undef JMPKIND0
-#  undef CCALL0
-#  undef XOTHER
-}
-
-static Char* nameOfTagOp ( TagOp h )
-{
-   switch (h) {
-      case Tag_PCast40:        return "PCast40";
-      case Tag_PCast20:        return "PCast20";
-      case Tag_PCast10:        return "PCast10";
-      case Tag_PCast01:        return "PCast01";
-      case Tag_PCast02:        return "PCast02";
-      case Tag_PCast04:        return "PCast04";
-      case Tag_PCast14:        return "PCast14";
-      case Tag_PCast12:        return "PCast12";
-      case Tag_PCast11:        return "PCast11";
-      case Tag_Left4:          return "Left4";
-      case Tag_Left2:          return "Left2";
-      case Tag_Left1:          return "Left1";
-      case Tag_SWiden14:       return "SWiden14";
-      case Tag_SWiden24:       return "SWiden24";
-      case Tag_SWiden12:       return "SWiden12";
-      case Tag_ZWiden14:       return "ZWiden14";
-      case Tag_ZWiden24:       return "ZWiden24";
-      case Tag_ZWiden12:       return "ZWiden12";
-      case Tag_UifU4:          return "UifU4";
-      case Tag_UifU2:          return "UifU2";
-      case Tag_UifU1:          return "UifU1";
-      case Tag_UifU0:          return "UifU0";
-      case Tag_DifD4:          return "DifD4";
-      case Tag_DifD2:          return "DifD2";
-      case Tag_DifD1:          return "DifD1";
-      case Tag_ImproveAND4_TQ: return "ImproveAND4_TQ";
-      case Tag_ImproveAND2_TQ: return "ImproveAND2_TQ";
-      case Tag_ImproveAND1_TQ: return "ImproveAND1_TQ";
-      case Tag_ImproveOR4_TQ:  return "ImproveOR4_TQ";
-      case Tag_ImproveOR2_TQ:  return "ImproveOR2_TQ";
-      case Tag_ImproveOR1_TQ:  return "ImproveOR1_TQ";
-      case Tag_DebugFn:        return "DebugFn";
-      default: VG_(skin_panic)("vg_nameOfTagOp");
-   }
-}
-
-
-Char* SK_(name_XUOpcode)(Opcode opc)
-{
-   switch (opc) {
-      case GETVF:   return "GETVF";
-      case PUTVF:   return "PUTVF";
-      case TAG1:    return "TAG1";
-      case TAG2:    return "TAG2";
-      case LOADV:   return "LOADV";
-      case STOREV:  return "STOREV";
-      case GETV:    return "GETV";
-      case PUTV:    return "PUTV";
-      case TESTV:   return "TESTV";
-      case SETV:    return "SETV";
-      default:      
-         VG_(printf)("unhandled opcode: %u\n", opc);
-         VG_(skin_panic)("SK_(name_XUOpcode): unhandled case");
-   }
-}
-
-/* ---------------------------------------------------------------------
-   Debugging stuff.
-   ------------------------------------------------------------------ */
-
-void SK_(pp_XUInstr)(UInstr* u)
-{
-   switch (u->opcode) {
-      case TAG1:
-         VG_(pp_UOperand)(u, 1, 4, False);
-         VG_(printf)(" = %s ( ", nameOfTagOp( u->val3 ));
-         VG_(pp_UOperand)(u, 1, 4, False);
-         VG_(printf)(" )");
-         break;
-
-      case TAG2:
-         VG_(pp_UOperand)(u, 2, 4, False);
-         VG_(printf)(" = %s ( ", nameOfTagOp( u->val3 ));
-         VG_(pp_UOperand)(u, 1, 4, False);
-         VG_(printf)(", ");
-         VG_(pp_UOperand)(u, 2, 4, False);
-         VG_(printf)(" )");
-         break;
-
-      case STOREV: case LOADV:
-         VG_(pp_UOperand)(u, 1, u->size, u->opcode==LOADV);
-         VG_(printf)(", ");
-         VG_(pp_UOperand)(u, 2, u->size, u->opcode==STOREV);
-         break;
-
-      case PUTVF: case GETVF:
-         VG_(pp_UOperand)(u, 1, 0, False);
-         break;
-
-      case GETV: case PUTV:
-         VG_(pp_UOperand)(u, 1, u->opcode==PUTV ? 4 : u->size, False);
-         VG_(printf)(", ");
-         VG_(pp_UOperand)(u, 2, u->opcode==GETV ? 4 : u->size, False);
-         break;
-
-      case TESTV: case SETV:
-         VG_(pp_UOperand)(u, 1, u->size, False);
-         break;
-
-      default:
-         VG_(printf)("unhandled opcode: %u\n", u->opcode);
-         VG_(skin_panic)("SK_(pp_XUInstr): unhandled opcode");
-   }
-
-}
-
-Int SK_(get_Xreg_usage)(UInstr* u, Tag tag, Int* regs, Bool* isWrites)
-{
-#  define RD(ono)    VG_UINSTR_READS_REG(ono, regs, isWrites)
-#  define WR(ono)    VG_UINSTR_WRITES_REG(ono, regs, isWrites)
-
-   Int n = 0;
-   switch (u->opcode) {        
-      case TAG1:    RD(1); WR(1);        break;
-      case TAG2:    RD(1); RD(2); WR(2); break;
-      case LOADV:   RD(1); WR(2);        break;
-      case STOREV:  RD(1); RD(2);        break;
-      case GETV:    WR(2);               break;
-      case PUTV:    RD(1);               break;
-      case TESTV:   RD(1);               break;
-      case SETV:    WR(1);               break;
-      case PUTVF:   RD(1);               break;
-      case GETVF:   WR(1);               break;
-
-      default: 
-         VG_(printf)("unhandled opcode: %u\n", u->opcode);
-         VG_(skin_panic)("SK_(get_Xreg_usage): unhandled opcode");
-   }
-   return n;
-
-#  undef RD
-#  undef WR
-}
-
-/*------------------------------------------------------------*/
-/*--- New instrumentation machinery.                       ---*/
-/*------------------------------------------------------------*/
-#if 0
-static
-TagOp get_Tag_ImproveOR_TQ ( Int sz )
-{
-   switch (sz) {
-      case 4: return Tag_ImproveOR4_TQ;
-      case 2: return Tag_ImproveOR2_TQ;
-      case 1: return Tag_ImproveOR1_TQ;
-      default: VG_(skin_panic)("get_Tag_ImproveOR_TQ");
-   }
-}
-
-
-static
-TagOp get_Tag_ImproveAND_TQ ( Int sz )
-{
-   switch (sz) {
-      case 4: return Tag_ImproveAND4_TQ;
-      case 2: return Tag_ImproveAND2_TQ;
-      case 1: return Tag_ImproveAND1_TQ;
-      default: VG_(skin_panic)("get_Tag_ImproveAND_TQ");
-   }
-}
-
-
-static
-TagOp get_Tag_Left ( Int sz )
-{
-   switch (sz) {
-      case 4: return Tag_Left4;
-      case 2: return Tag_Left2;
-      case 1: return Tag_Left1;
-      default: VG_(skin_panic)("get_Tag_Left");
-   }
-}
-
-
-static
-TagOp get_Tag_UifU ( Int sz )
-{
-   switch (sz) {
-      case 4: return Tag_UifU4;
-      case 2: return Tag_UifU2;
-      case 1: return Tag_UifU1;
-      case 0: return Tag_UifU0;
-      default: VG_(skin_panic)("get_Tag_UifU");
-   }
-}
-
-
-static
-TagOp get_Tag_DifD ( Int sz )
-{
-   switch (sz) {
-      case 4: return Tag_DifD4;
-      case 2: return Tag_DifD2;
-      case 1: return Tag_DifD1;
-      default: VG_(skin_panic)("get_Tag_DifD");
-   }
-}
-
-
-static 
-TagOp get_Tag_PCast ( Int szs, Int szd )
-{
-   if (szs == 4 && szd == 0) return Tag_PCast40;
-   if (szs == 2 && szd == 0) return Tag_PCast20;
-   if (szs == 1 && szd == 0) return Tag_PCast10;
-   if (szs == 0 && szd == 1) return Tag_PCast01;
-   if (szs == 0 && szd == 2) return Tag_PCast02;
-   if (szs == 0 && szd == 4) return Tag_PCast04;
-   if (szs == 1 && szd == 4) return Tag_PCast14;
-   if (szs == 1 && szd == 2) return Tag_PCast12;
-   if (szs == 1 && szd == 1) return Tag_PCast11;
-   VG_(printf)("get_Tag_PCast(%d,%d)\n", szs, szd);
-   VG_(skin_panic)("get_Tag_PCast");
-}
-
-
-static 
-TagOp get_Tag_Widen ( Bool syned, Int szs, Int szd )
-{
-   if (szs == 1 && szd == 2 && syned)  return Tag_SWiden12;
-   if (szs == 1 && szd == 2 && !syned) return Tag_ZWiden12;
-
-   if (szs == 1 && szd == 4 && syned)  return Tag_SWiden14;
-   if (szs == 1 && szd == 4 && !syned) return Tag_ZWiden14;
-
-   if (szs == 2 && szd == 4 && syned)  return Tag_SWiden24;
-   if (szs == 2 && szd == 4 && !syned) return Tag_ZWiden24;
-
-   VG_(printf)("get_Tag_Widen(%d,%d,%d)\n", (Int)syned, szs, szd);
-   VG_(skin_panic)("get_Tag_Widen");
-}
-
-/* Pessimally cast the spec'd shadow from one size to another. */
-static 
-void create_PCast ( UCodeBlock* cb, Int szs, Int szd, Int tempreg )
-{
-   if (szs == 0 && szd == 0)
-      return;
-   uInstr3(cb, TAG1, 0, TempReg, tempreg, 
-                        NoValue, 0, 
-                        Lit16,   get_Tag_PCast(szs,szd));
-}
-
-
-/* Create a signed or unsigned widen of the spec'd shadow from one
-   size to another.  The only allowed size transitions are 1->2, 1->4
-   and 2->4. */
-static 
-void create_Widen ( UCodeBlock* cb, Bool signed_widen,
-                    Int szs, Int szd, Int tempreg )
-{
-   if (szs == szd) return;
-   uInstr3(cb, TAG1, 0, TempReg, tempreg, 
-                        NoValue, 0, 
-                        Lit16,   get_Tag_Widen(signed_widen,szs,szd));
-}
-
-
-/* Get the condition codes into a new shadow, at the given size. */
-static
-Int create_GETVF ( UCodeBlock* cb, Int sz )
-{
-   Int tt = newShadow(cb);
-   uInstr1(cb, GETVF, 0, TempReg, tt);
-   create_PCast(cb, 0, sz, tt);
-   return tt;
-}
-
-
-/* Save the condition codes from the spec'd shadow. */
-static
-void create_PUTVF ( UCodeBlock* cb, Int sz, Int tempreg )
-{
-   if (sz == 0) {
-      uInstr1(cb, PUTVF, 0, TempReg, tempreg);
-   } else { 
-      Int tt = newShadow(cb);
-      uInstr2(cb, MOV, 4, TempReg, tempreg, TempReg, tt);
-      create_PCast(cb, sz, 0, tt);
-      uInstr1(cb, PUTVF, 0, TempReg, tt);
-   }
-}
-
-
-/* Do Left on the spec'd shadow. */
-static 
-void create_Left ( UCodeBlock* cb, Int sz, Int tempreg )
-{
-   uInstr3(cb, TAG1, 0, 
-               TempReg, tempreg,
-               NoValue, 0, 
-               Lit16, get_Tag_Left(sz));
-}
-
-
-/* Do UifU on ts and td, putting the result in td. */
-static 
-void create_UifU ( UCodeBlock* cb, Int sz, Int ts, Int td )
-{
-   uInstr3(cb, TAG2, 0, TempReg, ts, TempReg, td,
-               Lit16, get_Tag_UifU(sz));
-}
-
-
-/* Do DifD on ts and td, putting the result in td. */
-static 
-void create_DifD ( UCodeBlock* cb, Int sz, Int ts, Int td )
-{
-   uInstr3(cb, TAG2, 0, TempReg, ts, TempReg, td,
-               Lit16, get_Tag_DifD(sz));
-}
-
-
-/* Do HelpAND on value tval and tag tqqq, putting the result in
-   tqqq. */
-static 
-void create_ImproveAND_TQ ( UCodeBlock* cb, Int sz, Int tval, Int tqqq )
-{
-   uInstr3(cb, TAG2, 0, TempReg, tval, TempReg, tqqq,
-               Lit16, get_Tag_ImproveAND_TQ(sz));
-}
-
-
-/* Do HelpOR on value tval and tag tqqq, putting the result in
-   tqqq. */
-static 
-void create_ImproveOR_TQ ( UCodeBlock* cb, Int sz, Int tval, Int tqqq )
-{
-   uInstr3(cb, TAG2, 0, TempReg, tval, TempReg, tqqq,
-               Lit16, get_Tag_ImproveOR_TQ(sz));
-}
-
-
-/* Get the shadow for an operand described by (tag, val).  Emit code
-   to do this and return the identity of the shadow holding the
-   result.  The result tag is always copied into a new shadow, so it
-   can be modified without trashing the original.*/
-static
-Int /* TempReg */ getOperandShadow ( UCodeBlock* cb, 
-                                     Int sz, Int tag, Int val )
-{
-   Int sh;
-   sh = newShadow(cb);
-   if (tag == TempReg) {
-      uInstr2(cb, MOV, 4, TempReg, SHADOW(val), TempReg, sh);
-      return sh;
-   }
-   if (tag == Literal) {
-      uInstr1(cb, SETV, sz, TempReg, sh);
-      return sh;
-   }
-   if (tag == ArchReg) {
-      uInstr2(cb, GETV, sz, ArchReg, val, TempReg, sh);
-      return sh;
-   }
-   VG_(skin_panic)("getOperandShadow");
-}
-
-/* Create and return an instrumented version of cb_in.  Free cb_in
-   before returning. */
-static UCodeBlock* memcheck_instrument ( UCodeBlock* cb_in )
-{
-   UCodeBlock* cb;
-   Int         i, j;
-   UInstr*     u_in;
-   Int         qs, qd, qt, qtt;
-   Bool        bogusLiterals;
-
-   cb = VG_(setup_UCodeBlock)(cb_in);
-
-   /* Scan the block to look for bogus literals.  These are magic
-      numbers which particularly appear in hand-optimised / inlined
-      implementations of strlen() et al which cause so much trouble
-      (spurious reports of uninit-var uses).  Purpose of this horrible
-      hack is to disable some checks any such literals are present in
-      this basic block. */
-   bogusLiterals = False;
-
-   if (MC_(clo_avoid_strlen_errors)) {
-      for (i = 0; i < VG_(get_num_instrs)(cb_in); i++) {
-         u_in = VG_(get_instr)(cb_in, i);
-         switch (u_in->opcode) {
-            case ADD: case SUB: case MOV: 
-               if (u_in->size == 4 && u_in->tag1 == Literal)
-                  goto literal;
-               break;
-            case LEA1: 
-               sk_assert(u_in->size == 4);
-               goto literal;
-            default: 
-               break;
-         }     
-         continue;
-        literal:
-         if (u_in->lit32 == 0xFEFEFEFF ||
-             u_in->lit32 == 0x80808080 ||
-             u_in->lit32 == 0x00008080) {
-            bogusLiterals = True;
-            break;
-         }
-      }
-   }
-
-   for (i = 0; i < VG_(get_num_instrs)(cb_in); i++) {
-      u_in = VG_(get_instr)(cb_in, i);
-      qs = qd = qt = qtt = INVALID_TEMPREG;
-
-      switch (u_in->opcode) {
-
-         case LOCK:
-         case NOP:
-            break;
-
-         case INCEIP:
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* The segment registers do not have their definedness
-            tracked.  We therefore make fake shadows on GETSEG and
-            test them on PUTSEG.  This will catch writing garbage to a
-            segment register; therefore we can assume it to be defined
-            when read (GETSEGd).  Since the first arg of USESEG is
-            fetched by GETSEG, we can assume it to be defined, and so
-            the definedness of the result is simply the definedness of
-            the second (virtual_address) arg of USESEG.  The upshot of
-            all this is that instrumentation of USESEG is a no-op! */
-
-         case PUTSEG:
-            sk_assert(u_in->tag1 == TempReg);
-            uInstr1(cb, TESTV, 2, TempReg, SHADOW(u_in->val1));
-            uInstr1(cb, SETV,  2, TempReg, SHADOW(u_in->val1));
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         case GETSEG:
-            sk_assert(u_in->tag2 == TempReg);
-            uInstr1(cb, SETV,  2, TempReg, SHADOW(u_in->val2));
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         case USESEG:
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* Loads and stores.  Test the V bits for the address.  24
-            Mar 02: since the address is A-checked anyway, there's not
-            really much point in doing the V-check too, unless you
-            think that you might use addresses which are undefined but
-            still addressible.  Hence the optionalisation of the V
-            check.  15 Dec 02: optionalisation removed, since it no
-            longer makes much sense given we also have an addrcheck
-            tool.
-
-            The LOADV/STOREV does an addressibility check for the
-            address. */
-
-         case LOAD: 
-            uInstr1(cb, TESTV, 4, TempReg, SHADOW(u_in->val1));
-            uInstr1(cb, SETV,  4, TempReg, SHADOW(u_in->val1));
-            uInstr2(cb, LOADV, u_in->size, 
-                        TempReg, u_in->val1,
-                        TempReg, SHADOW(u_in->val2));
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         case STORE:
-            uInstr1(cb, TESTV,  4, TempReg, SHADOW(u_in->val2));
-            uInstr1(cb, SETV,   4, TempReg, SHADOW(u_in->val2));
-            uInstr2(cb, STOREV, u_in->size,
-                        TempReg, SHADOW(u_in->val1), 
-                        TempReg, u_in->val2);
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* Moving stuff around.  Make the V bits follow accordingly,
-            but don't do anything else.  */
-
-         case GET:
-            uInstr2(cb, GETV, u_in->size,
-                        ArchReg, u_in->val1,
-                        TempReg, SHADOW(u_in->val2));
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         case PUT:
-            uInstr2(cb, PUTV, u_in->size, 
-                        TempReg, SHADOW(u_in->val1),
-                        ArchReg, u_in->val2);
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         case GETF:
-            /* This is not the smartest way to do it, but should work. */
-            qd = create_GETVF(cb, u_in->size);
-            uInstr2(cb, MOV, 4, TempReg, qd, TempReg, SHADOW(u_in->val1));
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         case PUTF:
-            create_PUTVF(cb, u_in->size, SHADOW(u_in->val1));
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         case MOV:
-            switch (u_in->tag1) {
-               case TempReg: 
-                  uInstr2(cb, MOV, 4,
-                              TempReg, SHADOW(u_in->val1),
-                              TempReg, SHADOW(u_in->val2));
-                  break;
-               case Literal: 
-                  uInstr1(cb, SETV, u_in->size, 
-                              TempReg, SHADOW(u_in->val2));
-                  break;
-               default: 
-                  VG_(skin_panic)("memcheck_instrument: MOV");
-            }
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* Special case of add, where one of the operands is a literal.
-            lea1(t) = t + some literal.
-            Therefore: lea1#(qa) = left(qa) 
-         */
-         case LEA1:
-            sk_assert(u_in->size == 4 && !VG_(any_flag_use)(u_in));
-            qs = SHADOW(u_in->val1);
-            qd = SHADOW(u_in->val2);
-            uInstr2(cb, MOV, 4, TempReg, qs, TempReg, qd);
-            create_Left(cb, u_in->size, qd);
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* Another form of add.  
-            lea2(ts,tt,shift) = ts + (tt << shift); shift is a literal
-                                and is 0,1,2 or 3.
-            lea2#(qs,qt) = left(qs `UifU` (qt << shift)).
-            Note, subtly, that the shift puts zeroes at the bottom of qt,
-            meaning Valid, since the corresponding shift of tt puts 
-            zeroes at the bottom of tb.
-         */
-         case LEA2: {
-            Int shift;
-            sk_assert(u_in->size == 4 && !VG_(any_flag_use)(u_in));
-            switch (u_in->extra4b) {
-               case 1: shift = 0; break;
-               case 2: shift = 1; break;
-               case 4: shift = 2; break;
-               case 8: shift = 3; break;
-               default: VG_(skin_panic)( "memcheck_instrument(LEA2)" );
-            }
-            qs = SHADOW(u_in->val1);
-            qt = SHADOW(u_in->val2);
-            qd = SHADOW(u_in->val3);
-            uInstr2(cb, MOV, 4, TempReg, qt, TempReg, qd);
-            if (shift > 0) {
-               uInstr2(cb, SHL, 4, Literal, 0, TempReg, qd);
-               uLiteral(cb, shift);
-            }
-            create_UifU(cb, 4, qs, qd);
-            create_Left(cb, u_in->size, qd);
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-         }
-
-         /* inc#/dec#(qd) = q `UifU` left(qd) = left(qd) */
-         case INC: case DEC:
-            qd = SHADOW(u_in->val1);
-            create_Left(cb, u_in->size, qd);
-            if (u_in->flags_w != FlagsEmpty)
-               create_PUTVF(cb, u_in->size, qd);
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* This is a HACK (approximation :-) */
-         /* rcl#/rcr#(qs,qd) 
-               = let q0 = pcast-sz-0(qd) `UifU` pcast-sz-0(qs) `UifU` eflags#
-                 eflags# = q0
-                 qd =pcast-0-sz(q0)
-            Ie, cast everything down to a single bit, then back up.
-            This assumes that any bad bits infect the whole word and 
-            the eflags.
-         */
-         case RCL: case RCR:
-	    sk_assert(u_in->flags_r != FlagsEmpty);
-            /* The following assertion looks like it makes sense, but is
-               actually wrong.  Consider this:
-                  rcll    %eax
-                  imull   %eax, %eax
-               The rcll writes O and C but so does the imull, so the O and C 
-               write of the rcll is annulled by the prior improvement pass.
-               Noticed by Kevin Ryde <user42@zip.com.au>
-            */
-	    /* sk_assert(u_in->flags_w != FlagsEmpty); */
-            qs = getOperandShadow(cb, 1, u_in->tag1, u_in->val1);
-            /* We can safely modify qs; cast it to 0-size. */
-            create_PCast(cb, 1, 0, qs);
-            qd = SHADOW(u_in->val2);
-            create_PCast(cb, u_in->size, 0, qd);
-            /* qs is cast-to-0(shift count#), and qd is cast-to-0(value#). */
-            create_UifU(cb, 0, qs, qd);
-            /* qs is now free; reuse it for the flag definedness. */
-            qs = create_GETVF(cb, 0);
-            create_UifU(cb, 0, qs, qd);
-            create_PUTVF(cb, 0, qd);
-            create_PCast(cb, 0, u_in->size, qd);
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* for OP in shl shr sar rol ror
-            (qs is shift count#, qd is value to be OP#d)
-            OP(ts,td)
-            OP#(qs,qd)
-               = pcast-1-sz(qs) `UifU` OP(ts,qd)
-            So we apply OP to the tag bits too, and then UifU with
-            the shift count# to take account of the possibility of it
-            being undefined.
-            
-            A bit subtle:
-               ROL/ROR rearrange the tag bits as per the value bits.
-               SHL/SHR shifts zeroes into the value, and corresponding 
-                  zeroes indicating Definedness into the tag.
-               SAR copies the top bit of the value downwards, and therefore
-                  SAR also copies the definedness of the top bit too.
-            So in all five cases, we just apply the same op to the tag 
-            bits as is applied to the value bits.  Neat!
-         */
-         case SHL:
-         case SHR: case SAR:
-         case ROL: case ROR: {
-            Int t_amount = INVALID_TEMPREG;
-            sk_assert(u_in->tag1 == TempReg || u_in->tag1 == Literal);
-            sk_assert(u_in->tag2 == TempReg);
-            qd = SHADOW(u_in->val2);
-
-            /* Make qs hold shift-count# and make
-               t_amount be a TempReg holding the shift count. */
-            if (u_in->tag1 == Literal) {
-               t_amount = newTemp(cb);
-               uInstr2(cb, MOV, 4, Literal, 0, TempReg, t_amount);
-               uLiteral(cb, u_in->lit32);
-               qs = SHADOW(t_amount);
-               uInstr1(cb, SETV, 1, TempReg, qs);
-            } else {
-               t_amount = u_in->val1;
-               qs = SHADOW(u_in->val1);
-            }
-
-            uInstr2(cb, u_in->opcode, 
-                        u_in->size, 
-                        TempReg, t_amount, 
-                        TempReg, qd);
-            qt = newShadow(cb);
-            uInstr2(cb, MOV, 4, TempReg, qs, TempReg, qt);
-            create_PCast(cb, 1, u_in->size, qt);
-            create_UifU(cb, u_in->size, qt, qd);
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-         }
-
-         /* One simple tag operation. */
-         case WIDEN:
-            sk_assert(u_in->tag1 == TempReg);
-            create_Widen(cb, u_in->signed_widen, u_in->extra4b, u_in->size, 
-                             SHADOW(u_in->val1));
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* not#(x) = x (since bitwise independent) */
-         case NOT:
-            sk_assert(u_in->tag1 == TempReg);
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* neg#(x) = left(x) (derivable from case for SUB) */
-         case NEG:
-            sk_assert(u_in->tag1 == TempReg);
-            create_Left(cb, u_in->size, SHADOW(u_in->val1));
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* bswap#(x) = bswap(x) */
-         case BSWAP:
-            sk_assert(u_in->tag1 == TempReg);
-            sk_assert(u_in->size == 4);
-            qd = SHADOW(u_in->val1);
-            uInstr1(cb, BSWAP, 4, TempReg, qd);
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* cc2val#(qd) = pcast-0-to-size(eflags#) */
-         case CC2VAL:
-            sk_assert(u_in->tag1 == TempReg);
-            sk_assert(u_in->flags_r != FlagsEmpty);
-            qt = create_GETVF(cb, u_in->size);
-            uInstr2(cb, MOV, 4, TempReg, qt, TempReg, SHADOW(u_in->val1));
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* cmov#(qs,qd) = cmov(qs,qd)
-            That is, do the cmov of tags using the same flags as for
-            the data (obviously).  However, first do a test on the 
-            validity of the flags.
-         */
-         case CMOV:
-            sk_assert(u_in->size == 4);
-            sk_assert(u_in->tag1 == TempReg);
-            sk_assert(u_in->tag2 == TempReg);
-            sk_assert(u_in->flags_r != FlagsEmpty);
-            sk_assert(u_in->flags_w == FlagsEmpty);
-            qs = SHADOW(u_in->val1);
-            qd = SHADOW(u_in->val2);
-            qt = create_GETVF(cb, 0);
-            uInstr1(cb, TESTV, 0, TempReg, qt);
-            /* qt should never be referred to again.  Nevertheless
-               ... */
-            uInstr1(cb, SETV, 0, TempReg, qt);
-
-            uInstr2(cb, CMOV, 4, TempReg, qs, TempReg, qd);
-            uCond(cb, u_in->cond);         
-            uFlagsRWU(cb, u_in->flags_r, u_in->flags_w, FlagsEmpty);
-
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* add#/sub#(qs,qd) 
-               = qs `UifU` qd `UifU` left(qs) `UifU` left(qd)
-               = left(qs) `UifU` left(qd)
-               = left(qs `UifU` qd)
-            adc#/sbb#(qs,qd)
-               = left(qs `UifU` qd) `UifU` pcast(eflags#)
-            Second arg (dest) is TempReg.
-            First arg (src) is Literal or TempReg or ArchReg. 
-         */
-         case ADD: case SUB:
-         case ADC: case SBB:
-         case MUL:
-            qd = SHADOW(u_in->val2);
-            qs = getOperandShadow(cb, u_in->size, u_in->tag1, u_in->val1);
-            create_UifU(cb, u_in->size, qs, qd);
-            create_Left(cb, u_in->size, qd);
-            if (u_in->opcode == ADC || u_in->opcode == SBB) {
-               sk_assert(u_in->flags_r != FlagsEmpty);
-               qt = create_GETVF(cb, u_in->size);
-               create_UifU(cb, u_in->size, qt, qd);
-            }
-            if (u_in->flags_w != FlagsEmpty) {
-               create_PUTVF(cb, u_in->size, qd);
-            }
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* xor#(qs,qd) = qs `UifU` qd */
-         case XOR:
-            qd = SHADOW(u_in->val2);
-            qs = getOperandShadow(cb, u_in->size, u_in->tag1, u_in->val1);
-            create_UifU(cb, u_in->size, qs, qd);
-            if (u_in->flags_w != FlagsEmpty) {
-               create_PUTVF(cb, u_in->size, qd);
-            }
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* and#/or#(qs,qd) 
-               = (qs `UifU` qd) `DifD` improve(vs,qs) 
-                                `DifD` improve(vd,qd)
-            where improve is the relevant one of
-                Improve{AND,OR}_TQ
-            Use the following steps, with qt as a temp:
-               qt = improve(vd,qd)
-               qd = qs `UifU` qd
-               qd = qt `DifD` qd
-               qt = improve(vs,qs)
-               qd = qt `DifD` qd
-         */
-         case AND: case OR:
-            sk_assert(u_in->tag1 == TempReg);
-            sk_assert(u_in->tag2 == TempReg);
-            qd = SHADOW(u_in->val2);
-            qs = SHADOW(u_in->val1);
-            qt = newShadow(cb);
-
-            /* qt = improve(vd,qd) */
-            uInstr2(cb, MOV, 4, TempReg, qd, TempReg, qt);
-            if (u_in->opcode == AND)
-               create_ImproveAND_TQ(cb, u_in->size, u_in->val2, qt);
-            else
-               create_ImproveOR_TQ(cb, u_in->size, u_in->val2, qt);
-            /* qd = qs `UifU` qd */
-            create_UifU(cb, u_in->size, qs, qd);
-            /* qd = qt `DifD` qd */
-            create_DifD(cb, u_in->size, qt, qd);
-            /* qt = improve(vs,qs) */
-            uInstr2(cb, MOV, 4, TempReg, qs, TempReg, qt);
-            if (u_in->opcode == AND)
-               create_ImproveAND_TQ(cb, u_in->size, u_in->val1, qt);
-            else
-               create_ImproveOR_TQ(cb, u_in->size, u_in->val1, qt);
-            /* qd = qt `DifD` qd */
-               create_DifD(cb, u_in->size, qt, qd);
-            /* So, finally qd is the result tag. */
-            if (u_in->flags_w != FlagsEmpty) {
-               create_PUTVF(cb, u_in->size, qd);
-            }
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* Machinery to do with supporting CALLM.  Copy the start and
-            end markers only to make the result easier to read
-            (debug); they generate no code and have no effect. 
-         */
-         case CALLM_S: case CALLM_E:
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* Copy PUSH and POP verbatim.  Arg/result absval
-            calculations are done when the associated CALL is
-            processed.  CLEAR has no effect on absval calculations but
-            needs to be copied.  
-         */
-         case PUSH: case POP: case CLEAR:
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* In short:
-               callm#(a1# ... an#) = (a1# `UifU` ... `UifU` an#)
-            We have to decide on a size to do the computation at,
-            although the choice doesn't affect correctness.  We will
-            do a pcast to the final size anyway, so the only important
-            factor is to choose a size which minimises the total
-            number of casts needed.  Valgrind: just use size 0,
-            regardless.  It may not be very good for performance
-            but does simplify matters, mainly by reducing the number
-            of different pessimising casts which have to be implemented.
-         */
-         case CALLM: {
-            UInstr* uu;
-            Bool res_used;
-
-            /* Now generate the code.  Get the final result absval
-               into qt. */
-            qt  = newShadow(cb);
-            qtt = newShadow(cb);
-            uInstr1(cb, SETV, 0, TempReg, qt);
-            for (j = i-1; VG_(get_instr)(cb_in, j)->opcode != CALLM_S; j--) {
-               uu = VG_(get_instr)(cb_in, j);
-               if (uu->opcode != PUSH) continue;
-               /* cast via a temporary */
-               uInstr2(cb, MOV, 4, TempReg, SHADOW(uu->val1),
-                                   TempReg, qtt);
-               create_PCast(cb, uu->size, 0, qtt);
-               create_UifU(cb, 0, qtt, qt);
-            }
-            /* Remembering also that flags read count as inputs. */
-            if (u_in->flags_r != FlagsEmpty) {
-               qtt = create_GETVF(cb, 0);
-               create_UifU(cb, 0, qtt, qt);
-            }
-
-            /* qt now holds the result tag.  If any results from the
-               call are used, either by fetching with POP or
-               implicitly by writing the flags, we copy the result
-               absval to the relevant location.  If not used, the call
-               must have been for its side effects, so we test qt here
-               and now.  Note that this assumes that all values
-               removed by POP continue to be live.  So dead args
-               *must* be removed with CLEAR, not by POPping them into
-               a dummy tempreg. 
-            */
-            res_used = False;
-            for (j = i+1; VG_(get_instr)(cb_in, j)->opcode != CALLM_E; j++) {
-               uu = VG_(get_instr)(cb_in, j);
-               if (uu->opcode != POP) continue;
-               /* Cast via a temp. */
-               uInstr2(cb, MOV, 4, TempReg, qt, TempReg, qtt);
-               create_PCast(cb, 0, uu->size, qtt);
-               uInstr2(cb, MOV, 4, TempReg, qtt, 
-                                   TempReg, SHADOW(uu->val1));
-               res_used = True;
-            }
-            if (u_in->flags_w != FlagsEmpty) {
-               create_PUTVF(cb, 0, qt);
-               res_used = True;
-            }
-            if (!res_used) {
-               uInstr1(cb, TESTV, 0, TempReg, qt);
-               /* qt should never be referred to again.  Nevertheless
-                  ... */
-               uInstr1(cb, SETV, 0, TempReg, qt);
-            }
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-         }
-         /* Whew ... */
-
-         case JMP:
-            if (u_in->tag1 == TempReg) {
-               uInstr1(cb, TESTV, 4, TempReg, SHADOW(u_in->val1));
-               uInstr1(cb, SETV,  4, TempReg, SHADOW(u_in->val1));
-            } else {
-               sk_assert(u_in->tag1 == Literal);
-            }
-            if (u_in->cond != CondAlways) {
-               sk_assert(u_in->flags_r != FlagsEmpty);
-               qt = create_GETVF(cb, 0);
-               if (/* HACK */ bogusLiterals) {
-                  if (0) 
-                     VG_(printf)("ignore TESTV due to bogus literal\n");
-               } else {
-                  uInstr1(cb, TESTV, 0, TempReg, qt);
-               }
-               /* qt should never be referred to again.  Nevertheless
-                  ... */
-               uInstr1(cb, SETV, 0, TempReg, qt);
-            }
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         case JIFZ:
-            uInstr1(cb, TESTV, 4, TempReg, SHADOW(u_in->val1));
-            uInstr1(cb, SETV,  4, TempReg, SHADOW(u_in->val1));
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* Emit a check on the address used.  The value loaded into the 
-            FPU is checked by the call to fpu_{read/write}_check().  */
-         case MMX2_MemRd: case MMX2_MemWr:
-         case FPU_R: case FPU_W: {
-            Int t_size = INVALID_TEMPREG;
-            Bool is_load;
-
-            if (u_in->opcode == MMX2_MemRd || u_in->opcode == MMX2_MemWr)
-               sk_assert(u_in->size == 4 || u_in->size == 8);
-
-            is_load = u_in->opcode==FPU_R || u_in->opcode==MMX2_MemRd;
-            sk_assert(u_in->tag2 == TempReg);
-            uInstr1(cb, TESTV, 4, TempReg, SHADOW(u_in->val2));
-            uInstr1(cb, SETV,  4, TempReg, SHADOW(u_in->val2));
-
-            t_size = newTemp(cb);
-            uInstr2(cb, MOV,   4, Literal, 0, TempReg, t_size);
-            uLiteral(cb, u_in->size);
-            uInstr2(cb, CCALL, 0, TempReg, u_in->val2, TempReg, t_size);
-            uCCall(cb, is_load ? (Addr) & MC_(fpu_read_check) 
-                               : (Addr) & MC_(fpu_write_check),
-                   2, 2, False);
-
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-         }
-
-         case MMX2a1_MemRd: {
-            Int t_size = INVALID_TEMPREG;
-
-            sk_assert(u_in->size == 8);
-
-            sk_assert(u_in->tag3 == TempReg);
-            uInstr1(cb, TESTV, 4, TempReg, SHADOW(u_in->val3));
-            uInstr1(cb, SETV,  4, TempReg, SHADOW(u_in->val3));
-
-            t_size = newTemp(cb);
-            uInstr2(cb, MOV,   4, Literal, 0, TempReg, t_size);
-            uLiteral(cb, u_in->size);
-            uInstr2(cb, CCALL, 0, TempReg, u_in->val3, TempReg, t_size);
-            uCCall(cb, (Addr) & MC_(fpu_read_check), 2, 2, False);
-            
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-         }
-
-	 /* SSE ins referencing scalar integer registers */
-         case SSE2g_RegWr:
-         case SSE2g1_RegWr:
-         case SSE2e1_RegRd:
-         case SSE3g_RegWr:
-         case SSE3e_RegRd:
-         case SSE3e_RegWr: 
-         case SSE3g1_RegWr:
-         case SSE3e1_RegRd:
-            sk_assert(u_in->tag3 == TempReg);
-
-            if (u_in->opcode == SSE2e1_RegRd || u_in->opcode == SSE3e1_RegRd) {
-               sk_assert(u_in->size == 2);
-            } else {
-               sk_assert(u_in->size == 4);
-            }
-
-            /* Is it a read ?  Better check the V bits right now. */
-            if ( u_in->opcode == SSE2e1_RegRd
-                 || u_in->opcode == SSE3e_RegRd
-                 || u_in->opcode == SSE3e1_RegRd )
-	       uInstr1(cb, TESTV, u_in->size, 
-                           TempReg, SHADOW(u_in->val3));
-
-	    /* And for both read and write, set the register to be
-	       defined. */
-	    uInstr1(cb, SETV, u_in->size, 
-                        TempReg, SHADOW(u_in->val3));
-
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* ... and the same deal for SSE insns referencing memory */
-         case SSE3a_MemRd:
-         case SSE3a_MemWr:
-         case SSE2a_MemWr:
-         case SSE2a_MemRd:
-         case SSE3a1_MemRd:
-         case SSE2a1_MemRd: { 
-            Bool is_load;
-            Int t_size;
-
-            sk_assert(u_in->size == 4 || u_in->size == 8
-                      || u_in->size == 16 || u_in->size == 512);
-
-            t_size = INVALID_TEMPREG;
-            is_load = u_in->opcode==SSE2a_MemRd 
-                      || u_in->opcode==SSE3a_MemRd
-                      || u_in->opcode==SSE2a1_MemRd
-                      || u_in->opcode==SSE3a1_MemRd;
-
-            sk_assert(u_in->tag3 == TempReg);
-
-	    uInstr1(cb, TESTV, 4, TempReg, SHADOW(u_in->val3));
-	    uInstr1(cb, SETV,  4, TempReg, SHADOW(u_in->val3));
-	    t_size = newTemp(cb);
-	    uInstr2(cb, MOV,   4, Literal, 0, TempReg, t_size);
-	    uLiteral(cb, u_in->size);
-	    uInstr2(cb, CCALL, 0, TempReg, u_in->val3, TempReg, t_size);
-	    uCCall(cb, is_load ? (Addr) & MC_(fpu_read_check) 
-		   : (Addr) & MC_(fpu_write_check),
-		   2, 2, False);
-
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-         }
-
-	 case SSE3ag_MemRd_RegWr:
-	 {
-	    Int t_size;
-
-            sk_assert(u_in->size == 4 || u_in->size == 8);
-	    sk_assert(u_in->tag1 == TempReg);
-	    uInstr1(cb, TESTV, 4, TempReg, SHADOW(u_in->val1));
-	    uInstr1(cb, SETV,  4, TempReg, SHADOW(u_in->val1));
-            t_size = newTemp(cb);
-	    uInstr2(cb, MOV, 4, Literal, 0, TempReg, t_size);
-	    uLiteral(cb, u_in->size);
-            uInstr2(cb, CCALL, 0, TempReg, u_in->val1, TempReg, t_size);
-            uCCall(cb, (Addr) MC_(fpu_read_check), 2, 2, False );
-	    uInstr1(cb, SETV, 4, TempReg, SHADOW(u_in->val2));
-            VG_(copy_UInstr)(cb, u_in);
-	    break;
-         }
-         
-         /* For MMX and SSE insns not referencing memory, just
-            make sure the eflags are defined if the instruction
-            read them, and make them defined it it writes them. */
-         case SSE5: case SSE4: case SSE3:
-         case MMX1: case MMX2: case MMX3:
-         case FPU:
-            if (u_in->flags_r != FlagsEmpty) {
-               qt = create_GETVF(cb, 0);
-               uInstr1(cb, TESTV, 0, TempReg, qt);
-               /* qt should never be referred to again.  Nevertheless
-                  ... */
-               uInstr1(cb, SETV, 0, TempReg, qt);
-            }
-            if (u_in->flags_w != FlagsEmpty) {
-               qd = newTemp(cb);
-               uInstr2(cb, MOV, 4, Literal, 0, TempReg, qd);
-               uLiteral(cb, 0);
-               create_PUTVF(cb, 0, qd);
-            }
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-         /* Since we don't track definedness of values inside the
-            MMX state, we'd better check that the (int) reg being
-            read here is defined. */
-         case MMX2_ERegRd: 
-            sk_assert(u_in->tag2 == TempReg);
-            sk_assert(u_in->size == 4);
-            uInstr1(cb, TESTV, 4, TempReg, SHADOW(u_in->val2));
-            uInstr1(cb, SETV,  4, TempReg, SHADOW(u_in->val2));
-            VG_(copy_UInstr)(cb, u_in);
-            break;
-
-	 /* The MMX register is assumed to be fully defined, so
-	    that's what this register becomes. */
-         case MMX2_ERegWr:
-            sk_assert(u_in->tag2 == TempReg);
-            sk_assert(u_in->size == 4);
-            uInstr1(cb, SETV,  4, TempReg, SHADOW(u_in->val2));
-            VG_(copy_UInstr)(cb, u_in);	 
-            break;
-
-         default:
-            VG_(pp_UInstr)(0, u_in);
-            VG_(skin_panic)( "memcheck_instrument: unhandled case");
-
-      } /* end of switch (u_in->opcode) */
-
-   } /* end of for loop */
-
-   VG_(free_UCodeBlock)(cb_in);
-   return cb;
-}
-
-/*------------------------------------------------------------*/
-/*--- Clean up mem check instrumentation.                  ---*/
-/*------------------------------------------------------------*/
-
-#define dis    VG_(print_codegen)
-
-
-#define VGC_IS_SHADOW(tempreg) ((tempreg % 2) == 1)
-#define VGC_UNDEF ((UChar)100)
-#define VGC_VALUE ((UChar)101)
-
-#define NOP_no_msg(uu)                                            \
-   do { VG_(new_NOP)(uu); } while (False)
-
-#define NOP_tag1_op(uu)                                           \
-   do { VG_(new_NOP)(uu);                                         \
-        if (dis)                                                  \
-           VG_(printf)("   at %2d: delete %s due to defd arg\n",  \
-                       i, nameOfTagOp(u->val3));                  \
-   } while (False)
-
-#define SETV_tag1_op(uu,newsz)                                    \
-   do { uu->opcode = SETV;                                        \
-        uu->size = newsz;                                         \
-        uu->tag2 = uu->tag3 = NoValue;                            \
-        if (dis)                                                  \
-           VG_(printf)("   at %2d: convert %s to SETV%d "         \
-                       "due to defd arg\n",                       \
-                       i, nameOfTagOp(u->val3), newsz);           \
-   } while (False)
-
-
-
-/* Run backwards and delete SETVs on shadow temps for which the next
-   action is a write.  Needs an env saying whether or not the next
-   action is a write.  The supplied UCodeBlock is destructively
-   modified.
-*/
-static void vg_delete_redundant_SETVs ( UCodeBlock* cb )
-{
-   Int     i, j, k;
-   Int     n_temps = VG_(get_num_temps)(cb);
-   Bool*   next_is_write;
-   UInstr* u;
-   Int     tempUse[VG_MAX_REGS_USED];
-   Bool    isWrites[VG_MAX_REGS_USED];
-
-   if (n_temps == 0) return;
-
-   next_is_write = VG_(malloc)(n_temps * sizeof(Bool));
-
-   for (i = 0; i < n_temps; i++) next_is_write[i] = True;
-
-   for (i = VG_(get_num_instrs)(cb) - 1; i >= 0; i--) {
-      u = VG_(get_instr)(cb, i);
-
-      /* Occasionally there will be GETVs, TAG1s and TAG2s calculating
-         values which are never used.  These first three cases get rid
-         of them. */
-
-      if (u->opcode == GETV && VGC_IS_SHADOW(u->val2) 
-                            && next_is_write[u->val2]) {
-         sk_assert(u->val2 < n_temps);
-         VG_(new_NOP)(u);
-         if (dis) 
-            VG_(printf)("   at %2d: delete GETV\n", i);
-      } else
-
-      if (u->opcode == TAG1 && VGC_IS_SHADOW(u->val1) 
-                            && next_is_write[u->val1]) {
-         sk_assert(u->val1 < n_temps);
-         VG_(new_NOP)(u);
-         if (dis) 
-            VG_(printf)("   at %2d: delete TAG1\n", i);
-      } else
-
-      if (u->opcode == TAG2 && VGC_IS_SHADOW(u->val2) 
-                            && next_is_write[u->val2]) {
-         sk_assert(u->val2 < n_temps);
-         VG_(new_NOP)(u);
-         if (dis) 
-            VG_(printf)("   at %2d: delete TAG2\n", i);
-      } else
-
-      /* The bulk of the cleanup work of this function is done by
-         the code from here downwards. */
-
-      if (u->opcode == MOV && VGC_IS_SHADOW(u->val2) 
-                           && next_is_write[u->val2]) {
-         /* This MOV is pointless because the target is dead at this
-            point.  Delete it. */
-         VG_(new_NOP)(u);
-         if (dis) 
-            VG_(printf)("   at %2d: delete MOV\n", i);
-      } else
-
-      if (u->opcode == SETV) {
-         if (u->tag1 == TempReg) {
-            sk_assert(VGC_IS_SHADOW(u->val1));
-            if (next_is_write[u->val1]) {
-               /* This write is pointless, so annul it. */
-               VG_(new_NOP)(u);
-               if (dis) 
-                  VG_(printf)("   at %2d: delete SETV\n", i);
-            } else {
-               /* This write has a purpose; don't annul it, but do
-                  notice that we did it. */
-               next_is_write[u->val1] = True;
-            }
-              
-         }
-
-      } else {
-         /* Find out what this insn does to the temps. */
-         k = VG_(get_reg_usage)(u, TempReg, &tempUse[0], &isWrites[0]);
-         sk_assert(0 <= k && k <= VG_MAX_REGS_USED);
-         for (j = k-1; j >= 0; j--) {
-            next_is_write[ tempUse[j] ] = isWrites[j];
-         }
-      }
-   }
-}
-
-
-/* Run forwards, propagating and using the is-completely-defined
-   property.  This removes a lot of redundant tag-munging code.
-   Unfortunately it requires intimate knowledge of how each uinstr and
-   tagop modifies its arguments.  This duplicates knowledge of uinstr
-   tempreg uses embodied in VG_(get_reg_usage)(), which is unfortunate. 
-   The supplied UCodeBlock* is modified in-place.
-
-   For each value temp, def[] should hold VGC_VALUE.
-
-   For each shadow temp, def[] may hold 4,2,1 or 0 iff that shadow is
-   definitely known to be fully defined at that size.  In all other
-   circumstances a shadow's def[] entry is VGC_UNDEF, meaning possibly
-   undefined.  In cases of doubt, VGC_UNDEF is always safe.
-*/
-static void vg_propagate_definedness ( UCodeBlock* cb )
-{
-   Int     i, j, k, t;
-   Int     n_temps = VG_(get_num_temps)(cb);
-   UChar*  def;
-   UInstr* u;
-   Int     tempUse[VG_MAX_REGS_USED];
-   Bool    isWrites[VG_MAX_REGS_USED];
-
-   if (n_temps == 0) return;
-
-   def = VG_(malloc)(n_temps * sizeof(UChar));
-
-   for (i = 0; i < n_temps; i++) 
-      def[i] = VGC_IS_SHADOW(i) ? VGC_UNDEF : VGC_VALUE;
-
-   /* Run forwards, detecting and using the all-defined property. */
-
-   for (i = 0; i < VG_(get_num_instrs)(cb); i++) {
-      u = VG_(get_instr)(cb, i);
-      switch (u->opcode) {
-
-      /* Tag-handling uinstrs. */
-
-         /* Deal with these quickly. */
-         case NOP:
-         case LOCK:
-         case INCEIP:
-            break;
-
-         /* Make a tag defined. */
-         case SETV:
-            sk_assert(u->tag1 == TempReg && VGC_IS_SHADOW(u->val1));
-            def[u->val1] = u->size;
-            break;
-
-         /* Check definedness of a tag. */
-         case TESTV:
-            sk_assert(u->tag1 == TempReg && VGC_IS_SHADOW(u->val1));
-            if (def[u->val1] <= 4) { 
-               sk_assert(def[u->val1] == u->size); 
-               NOP_no_msg(u);
-               if (dis) 
-                  VG_(printf)("   at %2d: delete TESTV on defd arg\n", i);
-            }
-            break;
-
-         /* Applies to both values and tags.  Propagate Definedness
-            property through copies.  Note that this isn't optional;
-            we *have* to do this to keep def[] correct. */
-         case MOV:
-            sk_assert(u->tag2 == TempReg);
-            if (u->tag1 == TempReg) {
-               if (VGC_IS_SHADOW(u->val1)) {
-                  sk_assert(VGC_IS_SHADOW(u->val2));
-                  def[u->val2] = def[u->val1];
-               }
-            }
-            break;
-
-         case PUTV:
-            sk_assert(u->tag1 == TempReg && VGC_IS_SHADOW(u->val1));
-            if (def[u->val1] <= 4) {
-               sk_assert(def[u->val1] == u->size);
-               u->tag1 = Literal;
-               u->val1 = 0;
-               switch (u->size) {
-                  case 4: u->lit32 = 0x00000000; break;
-                  case 2: u->lit32 = 0xFFFF0000; break;
-                  case 1: u->lit32 = 0xFFFFFF00; break;
-                  default: VG_(skin_panic)("vg_cleanup(PUTV)");
-               }
-               if (dis) 
-                  VG_(printf)(
-                     "   at %2d: propagate definedness into PUTV\n", i);
-            }
-            break;
-
-         case STOREV:
-            sk_assert(u->tag1 == TempReg && VGC_IS_SHADOW(u->val1));
-            if (def[u->val1] <= 4) {
-               sk_assert(def[u->val1] == u->size);
-               u->tag1 = Literal;
-               u->val1 = 0;
-               switch (u->size) {
-                  case 4: u->lit32 = 0x00000000; break;
-                  case 2: u->lit32 = 0xFFFF0000; break;
-                  case 1: u->lit32 = 0xFFFFFF00; break;
-                  default: VG_(skin_panic)("vg_cleanup(STOREV)");
-               }
-               if (dis) 
-                  VG_(printf)(
-                     "   at %2d: propagate definedness into STandV\n", i);
-            }
-            break;
-
-         /* Nothing interesting we can do with this, I think. */
-         case PUTVF:
-            break;
-
-         /* Tag handling operations. */
-         case TAG2:
-            sk_assert(u->tag2 == TempReg && VGC_IS_SHADOW(u->val2));
-            sk_assert(u->tag3 == Lit16);
-            /* Ultra-paranoid "type" checking. */
-            switch (u->val3) {
-               case Tag_ImproveAND4_TQ: case Tag_ImproveAND2_TQ:
-               case Tag_ImproveAND1_TQ: case Tag_ImproveOR4_TQ:
-               case Tag_ImproveOR2_TQ: case Tag_ImproveOR1_TQ:
-                  sk_assert(u->tag1 == TempReg && !VGC_IS_SHADOW(u->val1));
-                  break;
-               default:
-                  sk_assert(u->tag1 == TempReg && VGC_IS_SHADOW(u->val1));
-                  break;
-            }
-            switch (u->val3) {
-               Int sz;
-               case Tag_UifU4: 
-                  sz = 4; goto do_UifU;
-               case Tag_UifU2: 
-                  sz = 2; goto do_UifU;
-               case Tag_UifU1:
-                  sz = 1; goto do_UifU;
-               case Tag_UifU0:
-                  sz = 0; goto do_UifU;
-               do_UifU:
-                  sk_assert(u->tag1 == TempReg && VGC_IS_SHADOW(u->val1));
-                  sk_assert(u->tag2 == TempReg && VGC_IS_SHADOW(u->val2));
-                  if (def[u->val1] <= 4) {
-                     /* UifU.  The first arg is defined, so result is
-                        simply second arg.  Delete this operation. */
-                     sk_assert(def[u->val1] == sz);
-                     NOP_no_msg(u);
-                     if (dis) 
-                        VG_(printf)(
-                           "   at %2d: delete UifU%d due to defd arg1\n", 
-                           i, sz);
-                  }
-                  else 
-                  if (def[u->val2] <= 4) {
-                     /* UifU.  The second arg is defined, so result is
-                        simply first arg.  Copy to second. */
-                     sk_assert(def[u->val2] == sz);
-                     u->opcode = MOV; 
-                     u->size = 4;
-                     u->tag3 = NoValue;
-                     def[u->val2] = def[u->val1];
-                     if (dis) 
-                        VG_(printf)(
-                           "   at %2d: change UifU%d to MOV due to defd"
-                           " arg2\n", 
-                           i, sz);
-                  }
-                  break;
-               case Tag_ImproveAND4_TQ:
-                  sz = 4; goto do_ImproveAND;
-               case Tag_ImproveAND1_TQ:
-                  sz = 1; goto do_ImproveAND;
-               do_ImproveAND:
-                  /* Implements Q = T AND Q.  So if Q is entirely defined,
-                     ie all 0s, we get MOV T, Q. */
-		  if (def[u->val2] <= 4) {
-                     sk_assert(def[u->val2] == sz);
-                     u->size = 4; /* Regardless of sz */
-                     u->opcode = MOV;
-                     u->tag3 = NoValue;
-                     def[u->val2] = VGC_UNDEF;
-                     if (dis) 
-                        VG_(printf)(
-                            "   at %2d: change ImproveAND%d_TQ to MOV due "
-                            "to defd arg2\n", 
-                            i, sz);
-                  }
-                  break;
-               default: 
-                  goto unhandled;
-            }
-            break;
-
-         case TAG1:
-            sk_assert(u->tag1 == TempReg && VGC_IS_SHADOW(u->val1));
-            if (def[u->val1] > 4) break;
-            /* We now know that the arg to the op is entirely defined.
-               If the op changes the size of the arg, we must replace
-               it with a SETV at the new size.  If it doesn't change
-               the size, we can delete it completely. */
-            switch (u->val3) {
-               /* Maintain the same size ... */
-               case Tag_Left4: 
-                  sk_assert(def[u->val1] == 4);
-                  NOP_tag1_op(u);
-                  break;
-               case Tag_PCast11: 
-                  sk_assert(def[u->val1] == 1);
-                  NOP_tag1_op(u);
-                  break;
-               /* Change size ... */
-               case Tag_PCast40: 
-                  sk_assert(def[u->val1] == 4);
-                  SETV_tag1_op(u,0);
-                  def[u->val1] = 0;
-                  break;
-               case Tag_PCast14: 
-                  sk_assert(def[u->val1] == 1);
-                  SETV_tag1_op(u,4);
-                  def[u->val1] = 4;
-                  break;
-               case Tag_PCast12: 
-                  sk_assert(def[u->val1] == 1);
-                  SETV_tag1_op(u,2);
-                  def[u->val1] = 2;
-                  break;
-               case Tag_PCast10: 
-                  sk_assert(def[u->val1] == 1);
-                  SETV_tag1_op(u,0);
-                  def[u->val1] = 0;
-                  break;
-               case Tag_PCast02: 
-                  sk_assert(def[u->val1] == 0);
-                  SETV_tag1_op(u,2);
-                  def[u->val1] = 2;
-                  break;
-               default: 
-                  goto unhandled;
-            }
-            if (dis) 
-               VG_(printf)(
-                  "   at %2d: delete TAG1 %s due to defd arg\n",
-                  i, nameOfTagOp(u->val3));
-            break;
-
-         default:
-         unhandled:
-            /* We don't know how to handle this uinstr.  Be safe, and 
-               set to VGC_VALUE or VGC_UNDEF all temps written by it. */
-            k = VG_(get_reg_usage)(u, TempReg, &tempUse[0], &isWrites[0]);
-            sk_assert(0 <= k && k <= VG_MAX_REGS_USED);
-            for (j = 0; j < k; j++) {
-               t = tempUse[j];
-               sk_assert(t >= 0 && t < n_temps);
-               if (!isWrites[j]) {
-                  /* t is read; ignore it. */
-                  if (0&& VGC_IS_SHADOW(t) && def[t] <= 4)
-                     VG_(printf)("ignoring def %d at %s %s\n", 
-                                 def[t], 
-                                 VG_(name_UOpcode)(True, u->opcode),
-                                 (u->opcode == TAG1 || u->opcode == TAG2)
-                                    ? nameOfTagOp(u->val3) 
-                                    : (Char*)"");
-               } else {
-                  /* t is written; better nullify it. */
-                  def[t] = VGC_IS_SHADOW(t) ? VGC_UNDEF : VGC_VALUE;
-               }
-            }
-      }
-   }
-}
-
-
-/* Top level post-MemCheck-instrumentation cleanup function. */
-static void vg_cleanup ( UCodeBlock* cb )
-{
-   vg_propagate_definedness ( cb );
-   vg_delete_redundant_SETVs ( cb );
-}
-#endif
-
-
-#undef dis
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
 
 /*------------------------------------------------------------*/
 /*--- Forward decls                                        ---*/