#define OpMem64            6ull  /* Memory, 64-bit */
 #define OpImmUByte         7ull  /* Zero-extended 8-bit immediate */
 #define OpDX               8ull  /* DX register */
+#define OpCL               9ull  /* CL register (for shifts) */
+#define OpImmByte         10ull  /* 8-bit sign extended immediate */
+#define OpOne             11ull  /* Implied 1 */
+#define OpImm             12ull  /* Sign extended immediate */
 
 #define OpBits             4  /* Width of operand field */
 #define OpMask             ((1ull << OpBits) - 1)
 #define Priv        (1<<27) /* instruction generates #GP if current CPL != 0 */
 #define No64       (1<<28)
 /* Source 2 operand type */
-#define Src2None    (0u<<29)
-#define Src2CL      (1u<<29)
-#define Src2ImmByte (2u<<29)
-#define Src2One     (3u<<29)
-#define Src2Imm     (4u<<29)
-#define Src2Mask    (7u<<29)
+#define Src2Shift   (29)
+#define Src2None    (OpNone << Src2Shift)
+#define Src2CL      (OpCL << Src2Shift)
+#define Src2ImmByte (OpImmByte << Src2Shift)
+#define Src2One     (OpOne << Src2Shift)
+#define Src2Imm     (OpImm << Src2Shift)
+#define Src2Mask    (OpMask << Src2Shift)
 
 #define X2(x...) x, x
 #define X3(x...) X2(x), x
                op->addr.reg = &ctxt->regs[VCPU_REGS_RDX];
                fetch_register_operand(op);
                break;
+       case OpCL:
+               op->bytes = 1;
+               op->val = ctxt->regs[VCPU_REGS_RCX] & 0xff;
+               break;
+       case OpImmByte:
+               rc = decode_imm(ctxt, op, 1, true);
+               break;
+       case OpOne:
+               op->bytes = 1;
+               op->val = 1;
+               break;
+       case OpImm:
+               rc = decode_imm(ctxt, op, imm_size(ctxt), true);
+               break;
        case OpImplicit:
                /* Special instructions do their own operand decoding. */
        default:
         * Decode and fetch the second source operand: register, memory
         * or immediate.
         */
-       switch (ctxt->d & Src2Mask) {
-       case Src2None:
-               break;
-       case Src2CL:
-               ctxt->src2.bytes = 1;
-               ctxt->src2.val = ctxt->regs[VCPU_REGS_RCX] & 0xff;
-               break;
-       case Src2ImmByte:
-               rc = decode_imm(ctxt, &ctxt->src2, 1, true);
-               break;
-       case Src2One:
-               ctxt->src2.bytes = 1;
-               ctxt->src2.val = 1;
-               break;
-       case Src2Imm:
-               rc = decode_imm(ctxt, &ctxt->src2, imm_size(ctxt), true);
-               break;
-       }
-
+       rc = decode_operand(ctxt, &ctxt->src2, (ctxt->d >> Src2Shift) & OpMask);
        if (rc != X86EMUL_CONTINUE)
                goto done;