return grp5_names[opc_aux];
 }
 
-//.. //-- static Char* nameGrp8 ( Int opc_aux )
-//.. //-- {
-//.. //--    static Char* grp8_names[8] 
-//.. //--      = { "???", "???", "???", "???", "bt", "bts", "btr", "btc" };
-//.. //--    if (opc_aux < 4 || opc_aux > 7) VG_(core_panic)("nameGrp8");
-//.. //--    return grp8_names[opc_aux];
-//.. //-- }
-//.. 
+static HChar* nameGrp8 ( Int opc_aux )
+{
+   static HChar* grp8_names[8] 
+      = { "???", "???", "???", "???", "bt", "bts", "btr", "btc" };
+   if (opc_aux < 4 || opc_aux > 7) vpanic("nameGrp8(amd64)");
+   return grp8_names[opc_aux];
+}
+
 //.. static HChar* nameSReg ( UInt sreg )
 //.. {
 //..    switch (sreg) {
 }
 
 
+/* Group 8 extended opcodes (but BT/BTS/BTC/BTR only). */
+static
+ULong dis_Grp8_Imm ( Prefix pfx,
+                     ULong delta, UChar modrm,
+                     Int am_sz, Int sz, ULong src_val,
+                     Bool* decode_OK )
+{
+   /* src_val denotes a d8.
+      And delta on entry points at the modrm byte. */
+
+   IRType ty     = szToITy(sz);
+   IRTemp t2     = newTemp(Ity_I64);
+   IRTemp t2m    = newTemp(Ity_I64);
+   IRTemp t_addr = IRTemp_INVALID;
+   HChar  dis_buf[50];
+   ULong  mask;
 
-//.. //-- /* Group 8 extended opcodes (but BT/BTS/BTC/BTR only). */
-//.. //-- static
-//.. //-- Addr dis_Grp8_BT ( UCodeBlock* cb, 
-//.. //--                    UChar       sorb,
-//.. //--                    Addr eip, UChar modrm,
-//.. //--                    Int am_sz, Int sz, UInt src_val )
-//.. //-- {
-#if 0 /* stop gcc multi-line comment warning */
-/.. #  define MODIFY_t2_AND_SET_CARRY_FLAG                                        \
-/..       /* t2 is the value to be op'd on.  Copy to t_fetched, then        \
-/..          modify t2, if non-BT. */                                        \
-/..       uInstr2(cb, MOV,   4,  TempReg, t2, TempReg, t_fetched);                \
-/..       uInstr2(cb, MOV,  sz,  Literal, 0,  TempReg, t_mask);                \
-/..       uLiteral(cb, v_mask);                                                \
-/..       switch (gregOfRM(modrm)) {                                        \
-/..          case 4: /* BT */  break;                                        \
-/..          case 5: /* BTS */                                                 \
-/..             uInstr2(cb, OR, sz, TempReg, t_mask, TempReg, t2); break;        \
-/..          case 6: /* BTR */                                                \
-/..             uInstr2(cb, AND, sz, TempReg, t_mask, TempReg, t2); break;        \
-/..          case 7: /* BTC */                                                 \
-/..             uInstr2(cb, XOR, sz, TempReg, t_mask, TempReg, t2); break;        \
-/..       }                                                                        \
-/..      /* Copy relevant bit from t_fetched into carry flag. */                \
-/..       uInstr2(cb, SHR, sz, Literal, 0, TempReg, t_fetched);                \
-/..       uLiteral(cb, src_val);                                                \
-/..       uInstr2(cb, MOV, sz, Literal, 0, TempReg, t_mask);                \
-/..       uLiteral(cb, 1);                                                        \
-/..       uInstr2(cb, AND, sz, TempReg, t_mask, TempReg, t_fetched);        \
-/..       uInstr1(cb, NEG, sz, TempReg, t_fetched);                                \
-/..       setFlagsFromUOpcode(cb, NEG);
-#endif /* stop gcc multi-line comment warning */
-//.. 
-//.. 
-//--    /* src_val denotes a d8.
-//--       And eip on entry points at the modrm byte. */
-//--    Int   t1, t2, t_fetched, t_mask;
-//--    UInt  pair;
-//--    HChar dis_buf[50];
-//--    UInt  v_mask;
-//-- 
-//--    /* There is no 1-byte form of this instruction, AFAICS. */
-//--    vg_assert(sz == 2 || sz == 4);
-//-- 
-//--    /* Limit src_val -- the bit offset -- to something within a word.
-//--       The Intel docs say that literal offsets larger than a word are
-//--       masked in this way. */
-//--    switch (sz) {
-//--       case 2: src_val &= 15; break;
-//--       case 4: src_val &= 31; break;
-//--       default: VG_(core_panic)("dis_Grp8_BT: invalid size");
-//--    }
-//-- 
-//--    /* Invent a mask suitable for the operation. */
-//-- 
-//--    switch (gregOfRM(modrm)) {
-//--       case 4: /* BT */  v_mask = 0; break;
-//--       case 5: /* BTS */ v_mask = 1 << src_val; break;
-//--       case 6: /* BTR */ v_mask = ~(1 << src_val); break;
-//--       case 7: /* BTC */ v_mask = 1 << src_val; break;
-//--          /* If this needs to be extended, probably simplest to make a
-//--             new function to handle the other cases (0 .. 3).  The
-//--             Intel docs do however not indicate any use for 0 .. 3, so
-//--             we don't expect this to happen. */
-//--       default: VG_(core_panic)("dis_Grp8_BT");
-//--    }
-//--    /* Probably excessively paranoid. */
-//--    if (sz == 2)
-//--       v_mask &= 0x0000FFFF;
-//-- 
-//--    t1        = INVALID_TEMPREG;
-//--    t_fetched = newTemp(cb);
-//--    t_mask    = newTemp(cb);
-//-- 
-//--    if (epartIsReg(modrm)) {
-//--       vg_assert(am_sz == 1);
-//--       t2 = newTemp(cb);
-//-- 
-//--       /* Fetch the value to be tested and modified. */
-//--       uInstr2(cb, GET, sz, ArchReg, eregOfRM(modrm), TempReg, t2);
-//--       /* Do it! */
-//--       MODIFY_t2_AND_SET_CARRY_FLAG;
-//--       /* Dump the result back, if non-BT. */
-//--       if (gregOfRM(modrm) != 4 /* BT */)
-//--          uInstr2(cb, PUT, sz, TempReg, t2, ArchReg, eregOfRM(modrm));
-//-- 
-//--       eip += (am_sz + 1);
-//--       DIP("%s%c $0x%x, %s\n", nameGrp8(gregOfRM(modrm)), nameISize(sz),
-//--                               src_val, nameIReg(sz,eregOfRM(modrm)));
-//--    } else {
-//--       pair = disAMode ( cb, sorb, eip, dis_buf);
-//--       t1   = LOW24(pair);
-//--       t2   = newTemp(cb);
-//--       eip  += HI8(pair);
-//--       eip  += 1;
-//-- 
-//--       /* Fetch the value to be tested and modified. */
-//--       uInstr2(cb, LOAD,  sz, TempReg, t1, TempReg, t2);
-//--       /* Do it! */
-//--       MODIFY_t2_AND_SET_CARRY_FLAG;
-//--       /* Dump the result back, if non-BT. */
-//--       if (gregOfRM(modrm) != 4 /* BT */) {
-//--          uInstr2(cb, STORE, sz, TempReg, t2, TempReg, t1);
-//--       }
-//--       DIP("%s%c $0x%x, %s\n", nameGrp8(gregOfRM(modrm)), nameISize(sz),
-//--                               src_val, dis_buf);
-//--    }
-//--    return eip;
-//-- 
-//-- #  undef MODIFY_t2_AND_SET_CARRY_FLAG
-//-- }
+   /* we're optimists :-) */
+   *decode_OK = True;
+
+   /* Limit src_val -- the bit offset -- to something within a word.
+      The Intel docs say that literal offsets larger than a word are
+      masked in this way. */
+   switch (sz) {
+      case 2:  src_val &= 15; break;
+      case 4:  src_val &= 31; break;
+      default: *decode_OK = False; return delta;
+   }
+
+   /* Invent a mask suitable for the operation. */
+   switch (gregLO3ofRM(modrm)) {
+      case 4: /* BT */  mask = 0;               break;
+      case 5: /* BTS */ mask = 1 << src_val;    break;
+      case 6: /* BTR */ mask = ~(1 << src_val); break;
+      case 7: /* BTC */ mask = 1 << src_val;    break;
+         /* If this needs to be extended, probably simplest to make a
+            new function to handle the other cases (0 .. 3).  The
+            Intel docs do however not indicate any use for 0 .. 3, so
+            we don't expect this to happen. */
+      default: *decode_OK = False; return delta;
+   }
+
+   /* Fetch the value to be tested and modified into t2, which is
+      64-bits wide regardless of sz. */
+   if (epartIsReg(modrm)) {
+      vassert(am_sz == 1);
+      assign( t2, widenUto64(getIRegE(sz, pfx, modrm)) );
+      delta += (am_sz + 1);
+      DIP("%s%c $0x%llx, %s\n", nameGrp8(gregLO3ofRM(modrm)), 
+                                nameISize(sz),
+                                src_val, nameIRegE(sz,pfx,modrm));
+   } else {
+      Int len;
+      t_addr = disAMode ( &len, pfx, delta, dis_buf, 1 );
+      delta  += (len+1);
+      assign( t2, widenUto64(loadLE(ty, mkexpr(t_addr))) );
+      DIP("%s%c $0x%llx, %s\n", nameGrp8(gregLO3ofRM(modrm)), 
+                                nameISize(sz),
+                                src_val, dis_buf);
+   }
 
+   /* Copy relevant bit from t2 into the carry flag. */
+   /* Flags: C=selected bit, O,S,Z,A,P undefined, so are set to zero. */
+   stmt( IRStmt_Put( OFFB_CC_OP,   mkU64(AMD64G_CC_OP_COPY) ));
+   stmt( IRStmt_Put( OFFB_CC_DEP2, mkU64(0) ));
+   stmt( IRStmt_Put( 
+            OFFB_CC_DEP1,
+            binop(Iop_And64,
+                  binop(Iop_Shr64, mkexpr(t2), mkU8(src_val)),
+                  mkU64(1))
+       ));
+
+   /* Compute the new value into t2m, if non-BT. */
+   switch (gregLO3ofRM(modrm)) {
+      case 4: /* BT */
+         break;
+      case 5: /* BTS */
+         assign( t2m, binop(Iop_Or64, mkU64(mask), mkexpr(t2)) );
+         break;
+      case 6: /* BTR */
+         assign( t2m, binop(Iop_And64, mkU64(mask), mkexpr(t2)) );
+         break;
+      case 7: /* BTC */
+         assign( t2m, binop(Iop_Xor64, mkU64(mask), mkexpr(t2)) );
+         break;
+     default: 
+         vassert(0);
+   }
+
+   /* Write the result back, if non-BT. */
+   if (gregLO3ofRM(modrm) != 4 /* BT */) {
+      if (epartIsReg(modrm)) {
+       putIRegE(sz, pfx, modrm, narrowTo(ty, mkexpr(t2m)));
+      } else {
+       storeLE(mkexpr(t_addr), narrowTo(ty, mkexpr(t2m)));
+      }
+   }
+
+   return delta;
+}
 
 
 /* Signed/unsigned widening multiply.  Generate IR to multiply the
       opc = getUChar(delta); delta++;
       switch (opc) {
 
-//.. //--       /* =-=-=-=-=-=-=-=-=- Grp8 =-=-=-=-=-=-=-=-=-=-=-= */
-//.. //-- 
-//.. //--       case 0xBA: /* Grp8 Ib,Ev */
-//.. //--          modrm = getUChar(eip);
-//.. //--          am_sz = lengthAMode(eip);
-//.. //--          d32   = getSDisp8(eip + am_sz);
-//.. //--          eip = dis_Grp8_BT ( cb, sorb, eip, modrm, am_sz, sz, d32 );
-//.. //--          break;
-//.. 
+      /* =-=-=-=-=-=-=-=-=- Grp8 =-=-=-=-=-=-=-=-=-=-=-= */
+
+      case 0xBA: { /* Grp8 Ib,Ev */
+         Bool decode_OK = False;
+         if (haveF2orF3(pfx)) goto decode_failure;
+         modrm = getUChar(delta);
+         am_sz = lengthAMode(pfx,delta);
+         d64   = getSDisp8(delta + am_sz);
+         delta = dis_Grp8_Imm ( pfx, delta, modrm, am_sz, sz, d64,
+                                &decode_OK );
+         if (!decode_OK)
+            goto decode_failure;
+         break;
+      }
+
 //..       /* =-=-=-=-=-=-=-=-=- BSF/BSR -=-=-=-=-=-=-=-=-=-= */
 //.. 
 //..       case 0xBC: /* BSF Gv,Ev */